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.
Completed
Push — master ( ea393e...747c84 )
by thatsIch
01:12
created

guess_path_from_user_documents()   B

Complexity

Conditions 4

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
c 1
b 0
f 0
dl 0
loc 33
rs 8.5806
1
"""
2
This module is about path resolving for the skin path.
3
4
This is particular useful if you for example try create new skins
5
or open an existing one.
6
"""
7
8
import getpass
9
import io
10
import os
11
import platform
12
import re
13
from functools import lru_cache
14
import winreg
15
16
import sublime
17
18
from .. import logger
19
20
from .program_path_provider import get_cached_program_path
21
from .setting_path_provider import get_cached_setting_path
22
23
24
def get_path_from_st_settings():
25
    """Load the value from the "rainmeter_skins_path" setting."""
26
    loaded_settings = sublime.load_settings("Rainmeter.sublime-settings")
27
    skinspath = loaded_settings.get("rainmeter_skins_path", None)
28
29
    # if it's found, return it
30
    # We trust the user to enter something meaningful here
31
    # and don't check anything.
32
    if skinspath:
33
        logger.info("Skins path '" + skinspath + "' found in sublime-settings file.")
34
        return os.path.normpath(skinspath) + "\\"
35
36
37
def get_path_from_rm_settings(rm_path, settings_path):
38
    """We check the Rainmeter.ini for the installation path."""
39
    # If it's not set, try to detect it automagically
40
    if not rm_path or not settings_path:
41
        return
42
43
    # First, try to read the SkinPath setting from Rainmeter.ini
44
    fhnd = io.open(os.path.join(settings_path, "Rainmeter.ini"))
45
    lines = fhnd.read()
46
    fhnd.close()
47
48
    # Find the skinspath setting in the file
49
    match = re.search(r"""(?imsx)
50
51
                     # Find the first [Rainmeter] section
52
                     (^\s*\[\s*Rainmeter\s*\]\s*$)
53
                     (.*?
54
55
                         # Find the "SkinPath" and "="
56
                         (^\s*SkinPath\s*=\s*
57
58
                             # Read until the next line ending and store
59
                             # in named group
60
                             (?P<skinpath>[^$]+?)\s*?$
61
                         )
62
                     ).*?
63
64
                     # All of this needs to happen before the next section
65
                     (?:^\s*\[\s*[^\[\]\s]+\s*\]\s*$)
66
                     """, lines)
67
68
    # if skinspath setting was found, return it
69
    if match:
70
        logger.info("Skins path found in Rainmeter.ini.")
71
        return match.group("skinpath").strip().replace("/", "\\")
72
73
74
def get_path_from_portable_rm_installation(rm_path, settings_path):
0 ignored issues
show
Coding Style Naming introduced by
The name get_path_from_portable_rm_installation does not conform to the function naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
75
    """
76
    If program path and setting path are equal, we have a portable installation.
77
78
    In this case, the Skins folder is inside the rainmeter path.
79
    """
80
    if os.path.samefile(rm_path, settings_path):
81
        logger.info("Skin path found in #PROGRAMPATH#" +
82
                    " because portable installation")
83
        return os.path.join(rm_path, "Skins") + "\\"
84
85
86
def get_path_from_registry():
87
    """
88
    If it's not a portable installation, we try looking into the "My Documents" folder.
89
90
    Since it could be relocated by the user, we have to query its value from the registry."""
91
    try:
92
        regkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
93
                                r"Software\Microsoft\Windows" +
94
                                r"\CurrentVersion\Explorer" +
95
                                r"\User Shell Folders")
96
        keyval = winreg.QueryValueEx(regkey, "Personal")
97
98
        pathrep = keyval[0]
99
100
        # The path could (and most likely, will) contain environment
101
        # variables that have to be expanded first
102
        pathrep = os.path.expandvars(pathrep)
103
104
        logger.info("Guessed Skin path from My Documents" +
105
                    " location in registry")
106
        return os.path.join(pathrep, "Rainmeter\\Skins") + "\\"
107
108
    except OSError:
0 ignored issues
show
Unused Code introduced by
This except handler seems to be unused and could be removed.

Except handlers which only contain pass and do not have an else clause can usually simply be removed:

try:
    raises_exception()
except:  # Could be removed
    pass
Loading history...
109
        pass
110
111
112
def guess_path_from_user_documents():
113
    """If the value could not be retrieved from the registry, we try some educated guesses about default locations."""
114
115
    try:
116
        username = getpass.getuser()
117
    except Exception:  # pylint: disable=W0703; The docs to not specify the exception type
0 ignored issues
show
Best Practice introduced by
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
118
        logger.info("Skins path could not be located." +
119
                    " Please set the \"skins_path\" setting in your Rainmeter" +
120
                    " settings file.")
121
        return
122
    else:
123
        # check if windows version is XP
124
        winversion = platform.version()
125
        if int(winversion[0]) < 6:
126
            mydocuments = os.path.join("C:\\Documents and Settings",
127
                                       username,
128
                                       "My Documents") + "\\"
129
130
            logger.info("Found Windows XP or lower." +
131
                        " Skins path assumed to be " + mydocuments +
132
                        "Rainmeter\\Skins\\")
133
        else:
134
            mydocuments = os.path.join("C:\\Users",
135
                                       username,
136
                                       "Documents") + "\\"
137
138
            logger.info("Found Windows Vista or higher." +
139
                        " Skins path assumed to be " + mydocuments +
140
                        "Rainmeter\\Skins\\")
141
142
        logger.info("Skin path guessed from user name" +
143
                    " and Windows version")
144
        return os.path.join(mydocuments, "Rainmeter\\Skins") + "\\"
145
146
147
@lru_cache(maxsize=None)
148
def get_cached_skin_path():
149
    """
150
    Get the value of the #SKINSPATH# variable.
151
152
    This can be collected from various installation locations,
153
    since there are numerous ways to install Rainmeter.
154
155
    The easiest solution is, if the user tells Sublime Rainmeter,
156
    that he installed Rainmeter in a specific folder. We trust,
157
    that the user knows where he installed it.
158
159
    If we know, where the rainmeter settings are,
160
    we can parse that from the Raimeter.ini.
161
162
    If the user chose a portable installation,
163
    it is also directly in the Rainmeter installation path.
164
165
    If the user chose a default installation,
166
    and enabled Rainmeter to store the information in the registry,
167
    we can use that to determine the path.
168
169
    If all fails we start guessing from the user document folder upwards.
170
    """
171
172
    rm_path = get_cached_program_path()
173
    settings_path = get_cached_setting_path()
174
175
    return get_path_from_st_settings() \
176
        or get_path_from_rm_settings(rm_path, settings_path) \
177
        or get_path_from_portable_rm_installation(rm_path, settings_path) \
178
        or get_path_from_registry() \
179
        or guess_path_from_user_documents()
180