Passed
Pull Request — master (#79)
by Jace
01:36
created

find_config_path()   B

Complexity

Conditions 5

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
c 2
b 0
f 0
dl 0
loc 19
ccs 15
cts 15
cp 1
crap 5
rs 8.5454
1
"""Functions to interact with sharing services."""
2
3 1
import os
4 1
import re
5 1
import logging
6
7 1
from .models.application import Application, Versions
8
9
10 1
ROOTS = (
11
    r"C:\Users",
12
    r"/Users",
13
    r"/home",
14
)
15 1
SERVICES = (
16
    'Dropbox',
17
    'Dropbox (Personal)',
18
)
19 1
CONFIG = 'mine.yml'
20 1
CONFLICT_BASE = r"{} \(.+'s conflicted copy \d+-\d+-\d+.*\).*"
21 1
CONFLICT_ANY = CONFLICT_BASE.format(".+")
22 1
CONFLICT_CONFIG = CONFLICT_BASE.format("mine")
23 1
DEPTH = 3  # number of levels to search for the settings file
24 1
APPLICATION = Application("Dropbox", versions=Versions(
25
    mac="Dropbox.app",
26
    windows="Dropbox.exe",
27
    linux="dropbox"))
28
29 1
log = logging.getLogger(__name__)
30
31
32 1
def find_root(top=None):
33
    """Get the root of the shared directory."""
34 1
    top = top or os.path.expanduser('~')
35
36 1
    log.debug("Looking for sharing service in '%s'...", top)
37 1
    for directory in os.listdir(top):
38 1
        if directory in SERVICES:
39 1
            path = os.path.join(top, directory)
40 1
            log.debug("Found sharing service: %s", path)
41 1
            return path
42
43 1
    msg = "no sharing service found"
44 1
    if os.getenv('CI'):
45 1
        log.warning(msg)
46 1
        return top
47
    else:
48 1
        raise EnvironmentError(msg)
49
50
51 1
def find_config_path(top=None, root=None):
52
    """Get the path to the settings file."""
53 1
    log.info("Looking for settings file...")
54 1
    top = top or os.path.expanduser('~')
55 1
    root = root or find_root(top=top)
56
57 1
    log.debug("Looking for '%s' in '%s'...", CONFIG, root)
58 1
    for dirpath, dirnames, _, in os.walk(root):
59 1
        depth = dirpath.count(os.path.sep) - root.count(os.path.sep)
60 1
        if depth >= DEPTH:
61 1
            del dirnames[:]
62 1
            continue
63 1
        path = os.path.join(dirpath, CONFIG)
64 1
        if os.path.isfile(path) and \
65
                not os.path.isfile(os.path.join(path, 'setup.py')):
66 1
            log.info("Found settings file: %s", path)
67 1
            return path
68
69 1
    raise EnvironmentError("No '{}' file found".format(CONFIG))
70
71
72 1
def delete_conflicts(root=None, config_only=False, force=False):
73
    """Delete all files with conflicted filenames."""
74 1
    root = root or find_root()
75
76 1
    log.info("%s conflicted files...", 'Deleting' if force else 'Displaying')
77 1
    pattern = CONFLICT_CONFIG if config_only else CONFLICT_ANY
78 1
    log.debug("Pattern: %r", pattern)
79 1
    regex = re.compile(pattern)
80 1
    count = 0
81 1
    for dirname, _, filenames in os.walk(root):
82 1
        for filename in filenames:
83 1
            if regex.match(filename):
84 1
                count += 1
85 1
                path = os.path.join(dirname, filename)
86 1
                if force:
87 1
                    os.remove(path)
88 1
                print(path)
89
90 1
    if count and not force:
91 1
        print(f"\nRun again with '--force' to delete these {count} conflict(s)")
92 1
        return False
93
94
    return True
95