Passed
Push — develop ( b3bfc7...6fb855 )
by Dean
02:36
created

UserManager.parse_user()   A

Complexity

Conditions 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12
Metric Value
cc 3
dl 0
loc 15
ccs 0
cts 6
cp 0
crap 12
rs 9.4285
1
from plugin.core.filters import Filters
0 ignored issues
show
Bug introduced by
The name filters does not seem to exist in module plugin.core.
Loading history...
Configuration introduced by
Unable to import 'plugin.core.filters' (invalid syntax (<string>, line 196))

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
2
from plugin.core.helpers.variable import to_integer
3
from plugin.managers.core.base import Get, Manager, Update
0 ignored issues
show
Bug introduced by
The name base does not seem to exist in module plugin.managers.core.
Loading history...
Configuration introduced by
Unable to import 'plugin.managers.core.base' (invalid syntax (<string>, line 39))

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
4
from plugin.managers.core.exceptions import UserFilteredException
5
from plugin.models import User, UserRule, PlexAccount
6
7
import apsw
0 ignored issues
show
Configuration introduced by
The import apsw could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
8
import logging
9
import peewee
10
11
log = logging.getLogger(__name__)
12
13
14
class GetUser(Get):
0 ignored issues
show
Coding Style introduced by
This class has no __init__ method.
Loading history...
15
    def __call__(self, user):
16
        user = self.manager.parse_user(user)
0 ignored issues
show
Bug introduced by
The Instance of GetUser does not seem to have a member named manager.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
17
18
        if not user:
19
            return None
20
21
        return super(GetUser, self).__call__(
22
            User.key == to_integer(user['key'])
23
        )
24
25
    def or_create(self, user, fetch=False, match=False, filtered_exception=False):
26
        user = self.manager.parse_user(user)
0 ignored issues
show
Bug introduced by
The Instance of GetUser does not seem to have a member named manager.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
27
28
        if not user:
29
            return None
30
31
        try:
32
            # Create new user
33
            obj = self.manager.create(
0 ignored issues
show
Bug introduced by
The Instance of GetUser does not seem to have a member named manager.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
34
                key=to_integer(user['key'])
35
            )
36
37
            # Update newly created object
38
            self.manager.update(
0 ignored issues
show
Bug introduced by
The Instance of GetUser does not seem to have a member named manager.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
39
                obj, user,
40
41
                fetch=fetch,
42
                match=match,
43
                filtered_exception=filtered_exception
44
            )
45
46
            return obj
47
        except (apsw.ConstraintError, peewee.IntegrityError):
48
            # Return existing user
49
            obj = self(user)
50
51
            if fetch or match:
52
                # Update existing `User`
53
                self.manager.update(
0 ignored issues
show
Bug introduced by
The Instance of GetUser does not seem to have a member named manager.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
54
                    obj, user,
55
56
                    fetch=fetch,
57
                    match=match,
58
                    filtered_exception=filtered_exception
59
                )
60
61
            return obj
62
63
64
class UpdateUser(Update):
0 ignored issues
show
Coding Style introduced by
This class has no __init__ method.
Loading history...
65
    def __call__(self, obj, user, fetch=False, match=False, filtered_exception=False):
66
        user = self.manager.parse_user(user)
0 ignored issues
show
Bug introduced by
The Instance of UpdateUser does not seem to have a member named manager.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
67
68
        if not user:
69
            return None
70
71
        filtered, data = self.to_dict(
72
            obj, user,
73
74
            fetch=fetch,
75
            match=match
76
        )
77
78
        updated = super(UpdateUser, self).__call__(
79
            obj, data
80
        )
81
82
        if filtered and filtered_exception:
83
            raise UserFilteredException
84
85
        return updated
86
87
    def to_dict(self, obj, user, fetch=False, match=False):
0 ignored issues
show
Unused Code introduced by
The argument obj seems to be unused.
Loading history...
Unused Code introduced by
The argument fetch seems to be unused.
Loading history...
88
        result = {}
89
90
        # Fill `result` with available fields
91
        if user.get('title'):
92
            result['name'] = user['title']
93
94
        if user.get('thumb'):
95
            result['thumb'] = user['thumb']
96
97
        filtered = False
98
99
        if match:
100
            # Try match `User` against rules
101
            filtered, result = self.match(
102
                result, user
103
            )
104
105
        return filtered, result
106
107
    @classmethod
108
    def match(cls, result, user):
109
        # Apply global filters
110
        if not Filters.is_valid_user(user):
111
            # User didn't pass filters, update `account` attribute and return
112
            result['account'] = None
113
114
            return True, result
115
116
        # Find matching `UserRule`
117
        rule = (UserRule
118
            .select()
119
            .where(
120
                (UserRule.name == user['title']) |
121
                (UserRule.name == '*') |
122
                (UserRule.name == None)
123
            )
124
            .order_by(
125
                UserRule.priority.asc()
126
            )
127
            .first()
128
        )
129
130
        log.debug('Activity matched against rule: %r', rule)
131
132
        if rule:
133
            # Process rule
134
            if rule.account_function is not None:
135
                result['account'] = cls.account_function(user, rule)
136
            elif rule.account_id is not None:
137
                result['account'] = rule.account_id
138
            else:
139
                return True, result
140
        else:
141
            result['account'] = None
142
143
        return False, result
144
145
    @staticmethod
146
    def account_function(user, rule):
147
        func = rule.account_function
148
149
        # Handle account function
150
        account_id = None
151
152
        if func == '@':
153
            # Map, try automatically finding matching `PlexAccount`
154
            plex_account = (PlexAccount
155
                .select()
156
                .where(
157
                    (PlexAccount.username == user['title']) |
158
                    (PlexAccount.title == user['title'])
159
                )
160
                .first()
161
            )
162
163
            if plex_account:
164
                account_id = plex_account.account_id
165
        else:
166
            log.warn('Unknown account function: %r', func)
167
            return None
168
169
        # Ensure `account_id` is valid
170
        if account_id is None:
171
            log.info('Unable to match user %r against any account', user['title'])
172
            return None
173
174
        log.debug('Matched user %r to account %r', user['title'], account_id)
175
        return account_id
176
177
178
class UserManager(Manager):
0 ignored issues
show
Coding Style introduced by
This class has no __init__ method.
Loading history...
179
    get = GetUser
180
    update = UpdateUser
181
182
    model = User
183
184
    @classmethod
185
    def parse_user(cls, user):
186
        if type(user) is not dict:
187
            # Build user dict from object
188
            user = {
189
                'key': user.id,
190
                'title': user.title,
191
                'thumb': user.thumb
192
            }
193
194
        # Validate `user`
195
        if not user.get('key'):
196
            return None
197
198
        return user
199