GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 6aae74...9679e9 )
by thatsIch
56s
created

get_current_config()   D

Complexity

Conditions 9

Size

Total Lines 72

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
dl 0
loc 72
rs 4.1525
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
"""Module for getting Rainmeter-specific paths."""
2
3
import os
4
import re
5
import filecmp
6
import ctypes
7
8
# own dependencies
9
from . import logger
10
11
from .path.program_path_provider import get_cached_program_path
12
from .path.setting_path_provider import get_cached_setting_path
13
from .path.program_drive_provider import get_cached_program_drive
14
from .path.plugin_path_provider import get_cached_plugin_path
15
from .path.addon_path_provider import get_cached_addon_path
16
from .path.skin_path_provider import get_cached_skin_path
17
18
19
def get_current_path(filepath):
20
    """Get the value of the #CURRENTPATH# variable for the specified path.
21
22
    Returns None if the file path is not in the skins folder
23
    """
24
    filepath = os.path.normpath(filepath)
25
26
    skinspath = get_cached_skin_path()
27
    if not skinspath or not filepath.startswith(skinspath):
28
        logger.info("current path could not be found because" +
29
                    " either the skins path could not be found or the current file" +
30
                    " is not located in the skins path.")
31
        return
32
33
    if os.path.isfile(filepath):
34
        return os.path.dirname(filepath) + "\\"
35
    else:
36
        return filepath + "\\"
37
38
39
def get_root_config_path(filepath):
40
    """Get the value of the #ROOTCONFIGPATH# variable for the specified path.
41
42
    Returns None if the path is not in the skins folder
43
    """
44
    filepath = os.path.normpath(filepath)
45
46
    skinspath = get_cached_skin_path()
47
    if not skinspath or not filepath.startswith(skinspath):
48
        logger.info("root config path could not be found" +
49
                    " because either the skins path could not be found or the" +
50
                    " current file is not located in the skins path.")
51
        return
52
53
    relpath = os.path.relpath(filepath, skinspath)
54
    logger.info(os.path.join(skinspath, relpath.split("\\")[0]) + "\\")
55
56
    return os.path.join(skinspath, relpath.split("\\")[0]) + "\\"
57
58
59
def get_current_file(filepath):
60
    """Get the value of the #CURRENTFILE# variable for the specified path.
61
62
    Returns None if the path is not in the skins folder
63
    """
64
    filepath = os.path.normpath(filepath)
65
66
    skinspath = get_cached_skin_path()
67
    if not skinspath or not filepath.startswith(skinspath):
68
        logger.info("current file could not be found because" +
69
                    " either the skins path could not be found or the current" +
70
                    " file is not located in the skins path.")
71
        return
72
73
    if os.path.isfile(filepath):
74
        return os.path.basename(filepath)
75
    else:
76
        logger.info("specified path is not a file.")
77
        return
78
79
80
def get_current_config(filepath):
81
    """Get the value of the #CURRENTCONFIG# variable for the specified path.
82
83
    Returns None if the path is not in the skins folder
84
    """
85
    filepath = os.path.normpath(filepath)
86
87
    skinspath = get_cached_skin_path()
88
    if not skinspath:
89
        logger.info("current config could not be found" +
90
                    " because the skins path could not be found.")
91
        return
92
    if not filepath.startswith(skinspath):
93
        logger.info("current config could not be found" +
94
                    " because the current file is not located in the skins path.")
95
96
        """workaround for symlinks:
97
        It could exists a symlink in the rainmeter skins folder.
98
        Rainmeter detects it correctly but uses the name of the symlink
99
        for the config name."""
100
101
        logger.info("trying symlink detection to find the skin config.")
102
        skins = os.listdir(skinspath)
103
104
        for skin in skins:
105
            check = os.path.join(skinspath, skin)
106
            # 0x0400 is the attribute for reparse point https://msdn.microsoft.com/en-us/library/ee332330(VS.85).aspx
107
            symbolic = os.path.isdir(check) and (ctypes.windll.kernel32.GetFileAttributesW(str(check)) & 0x0400) > 0
108
            if symbolic:
109
                logger.info("detected a symbolic link '" + check + "' through reparse pointer in file attributes.")
110
                walked = os.walk(check)
111
                # we walk deeper here because there can also be sub configs hidden in folders like <config/subconfig/config.ini>
112
                # which results the config being <config/subconfig>
113
                # at this point <skin> is probably the <config/
114
                for root, dirs, files in walked:
115
                    for file in files:
116
                        probe = os.path.join(root, file)
117
                        if filecmp.cmp(probe, filepath):
118
                            config = os.path.relpath(root, skinspath)
119
                            logger.info("found same file '" + file + "'. Recreate interpreted config '" + config + "'.")
120
121
                            return config
122
123
                            # when we found the file, we need to reverse the path to detect the sub configs
124
                            # _, probe_path_and_file = os.path.splitdrive(probe)
125
                            # _, actual_path_and_file = os.path.splitdrive(filepath)
126
                            
127
                            # prime the algorithm to remove the files
128
                            # probe_path, _ = os.path.split(probe_path_and_file)
129
                            # actual_path, _ = os.path.split(actual_path_and_file)
130
131
                            # while 1:
132
                            #     probe_path, probe_folder = os.path.split(probe_path)
133
                            #     actual_path, actual_folder = os.path.split(actual_path)
134
                            #     if probe_folder != actual_folder:
135
                            #         logger.info("Found last not matching folder '" + probe_folder + "' with '" + actual_folder + "'")
136
137
                            #         directory = os.path.dirname(probe)
138
139
                                    
140
               
141
        return
142
143
    # before you get the whole path called from the skin D:\Documents\Rainmeter\Skins\test\test.ini
144
    if os.path.isfile(filepath):
145
        filepath = os.path.dirname(filepath)
146
    # after the file name is trimmed D:\Documents\Rainmeter\Skins\test
147
148
    # the result is the directory path minus the skin path
149
    # D:\Documents\Rainmeter\Skins\test minus D:\Documents\Rainmeter\Skins\test equals test
150
    # thus the config is called <test>
151
    return os.path.relpath(filepath, skinspath)
152
153
154
def get_resources_path(filepath):
155
    """Get the value of the #@# variable for the specified path.
156
157
    Returns None if the path is not in the skins folder
158
    """
159
    rfp = get_root_config_path(filepath)
160
161
    if not rfp:
162
        return
163
    logger.info(os.path.join(rfp, "@Resources") + "\\")
164
    return os.path.join(rfp, "@Resources") + "\\"
165
166
167
def replace_variables(string, filepath):
168
    """Replace Rainmeter built-in variables and Windows environment variables in string.
169
170
    Replaces occurrences of the following variables in the string:
171
    #CURRENTFILE#
172
    #CURRENTPATH#
173
    #ROOTCONFIGPATH#
174
    #CURRENTCONFIG#
175
    #@#
176
    #SKINSPATH#
177
    #SETTINGSPATH#
178
    #PROGRAMPATH#
179
    #PROGRAMDRIVE#
180
    #ADDONSPATH#
181
    #PLUGINSPATH#
182
    Any Windows environment variables (like %APPDATA%)
183
    filepath must be a skin file located in a subdirectory of the skins folder
184
    """
185
    variables = {
186
        # lambdas for lazy evaluation
187
        "#CURRENTFILE#": lambda: get_current_file(filepath),
188
        "#CURRENTPATH#": lambda: get_current_path(filepath),
189
        "#ROOTCONFIGPATH#": lambda: get_root_config_path(filepath),
190
        "#CURRENTCONFIG#": lambda: get_current_config(filepath),
191
        "#@#": lambda: get_resources_path(filepath),
192
        "#SKINSPATH#": get_cached_skin_path,
193
        "#SETTINGSPATH#": get_cached_setting_path,
194
        "#PROGRAMPATH#": get_cached_program_path,
195
        "#PROGRAMDRIVE#": get_cached_program_drive,
196
        "#ADDONSPATH#": get_cached_addon_path,
197
        "#PLUGINSPATH#": get_cached_plugin_path
198
    }
199
200
    pattern = re.compile("(?i)" + "|".join(list(variables.keys())))
201
    # replace Rainmeter variables
202
    repl = pattern.sub(lambda x: variables[x.group().upper()](),
203
                       string)
204
    # expand windows environment variables
205
    repl = os.path.expandvars(repl)
206
    return repl
207
208
209
def make_path(string, filepath):
210
    """Make the string into an absolute path of an existing file or folder.
211
212
    Replacing Rainmeter built-in variables relative to the file specified in
213
    filepath (see replace_variables()) will return None if the file or folder
214
    doesn't exist, or if string is None or empty.
215
    """
216
    if not string:
217
        return None
218
219
    repl = replace_variables(string, filepath)
220
    norm = os.path.normpath(repl)
221
222
    # For relative paths, try folder of current file first
223
224
    if not os.path.isabs(norm):
225
        curpath = get_current_path(filepath)
226
        if curpath:
227
            abso = os.path.join(curpath, norm)
228
        else:
229
            abso = os.path.join(os.path.dirname(filepath), norm)
230
231
        if os.path.exists(abso):
232
            return abso
233
234
        # if that doesn't work, try relative to skins path
235
        # (for #CURRENTCONFIG#)
236
        abso = os.path.join(get_cached_skin_path(), norm)
237
        if os.path.exists(abso):
238
            return abso
239
    # for absolute paths, try opening containing folder if file does not exist
240
    else:
241
        if os.path.exists(norm):
242
            return norm
243
244
        if os.path.exists(os.path.dirname(norm)):
245
            return os.path.dirname(norm)
246
247
    return
248