Passed
Push — beta ( 72a57d...7d0ef0 )
by Dean
03:02
created

UpdateClient   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 19
dl 0
loc 121
ccs 0
cts 41
cp 0
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
B fetch() 0 27 4
A __call__() 0 18 3
B match() 0 46 6
B to_dict() 0 26 6
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 merge
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 ClientFilteredException
5
from plugin.models import Client, ClientRule
6
7
from plex import Plex
8
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...
9
import logging
10
import peewee
11
12
log = logging.getLogger(__name__)
13
14
15 View Code Duplication
class GetClient(Get):
0 ignored issues
show
Coding Style introduced by
This class has no __init__ method.
Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
16
    def __call__(self, player):
17
        player = self.manager.parse_player(player)
0 ignored issues
show
Bug introduced by
The Instance of GetClient 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...
18
19
        return super(GetClient, self).__call__(
20
            Client.key == player['key']
21
        )
22
23
    def or_create(self, player, fetch=False, match=False, filtered_exception=False):
24
        player = self.manager.parse_player(player)
0 ignored issues
show
Bug introduced by
The Instance of GetClient 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...
25
26
        try:
27
            # Create new client
28
            obj = self.manager.create(
0 ignored issues
show
Bug introduced by
The Instance of GetClient 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...
29
                key=player['key']
30
            )
31
32
            # Update newly created object
33
            self.manager.update(
0 ignored issues
show
Bug introduced by
The Instance of GetClient 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
                obj, player,
35
36
                fetch=fetch,
37
                match=match,
38
                filtered_exception=filtered_exception
39
            )
40
41
            return obj
42
        except (apsw.ConstraintError, peewee.IntegrityError):
43
            # Return existing user
44
            obj = self(player)
45
46
            if fetch or match:
47
                # Update existing `User`
48
                self.manager.update(
0 ignored issues
show
Bug introduced by
The Instance of GetClient 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...
49
                    obj, player,
50
51
                    fetch=fetch,
52
                    match=match,
53
                    filtered_exception=filtered_exception
54
                )
55
56
            return obj
57
58
59
class UpdateClient(Update):
0 ignored issues
show
Coding Style introduced by
This class has no __init__ method.
Loading history...
60
    def __call__(self, obj, player, fetch=False, match=False, filtered_exception=False):
61
        player = self.manager.parse_player(player)
0 ignored issues
show
Bug introduced by
The Instance of UpdateClient 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...
62
63
        filtered, data = self.to_dict(
64
            obj, player,
65
66
            fetch=fetch,
67
            match=match
68
        )
69
70
        updated = super(UpdateClient, self).__call__(
71
            obj, data
72
        )
73
74
        if filtered and filtered_exception:
75
            raise ClientFilteredException
76
77
        return updated
78
79
    def to_dict(self, obj, player, fetch=False, match=False):
0 ignored issues
show
Unused Code introduced by
The argument obj seems to be unused.
Loading history...
80
        result = {
81
            'name': player['title']
82
        }
83
84
        # Fill `result` with available fields
85
        if player.get('platform'):
86
            result['platform'] = player['platform']
87
88
        if player.get('product'):
89
            result['product'] = player['product']
90
91
        client = None
92
        filtered = False
93
94
        if fetch or match:
95
            # Fetch client from plex server
96
            result, client = self.fetch(result, player)
97
98
        if match:
99
            # Try match client against a rule
100
            filtered, result = self.match(
101
                result, client, player
102
            )
103
104
        return filtered, result
105
106
    @staticmethod
107
    def fetch(result, player):
108
        # Fetch client details
109
        client = Plex.clients().get(player['key'])
0 ignored issues
show
Bug introduced by
The Class Plex does not seem to have a member named clients.

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...
110
111
        if not client:
112
            log.info('Unable to find client with key %r', player['key'])
113
            return result, None
114
115
        # Merge client details from plex API
116
        result = merge(result, dict([
117
            (key, getattr(client, key)) for key in [
118
                'device_class',
119
                'product',
120
                'version',
121
122
                'host',
123
                'address',
124
                'port',
125
126
                'protocol',
127
                'protocol_capabilities',
128
                'protocol_version'
129
            ] if getattr(client, key)
130
        ]))
131
132
        return result, client
133
134
    @staticmethod
135
    def match(result, client, player):
136
        # Apply global filters
137
        if not Filters.is_valid_client(player) or\
138
           not Filters.is_valid_address(client):
139
            # Client didn't pass filters, update `account` attribute and return
140
            result['account'] = None
141
142
            return True, result
143
144
        # Find matching `ClientRule`
145
        address = client['address'] if client else None
146
147
        rule = (ClientRule
148
            .select()
149
            .where(
150
                (ClientRule.key == player['key']) |
151
                (ClientRule.key == '*') |
152
                (ClientRule.key == None),
153
154
                (ClientRule.name == player['title']) |
155
                (ClientRule.name == '*') |
156
                (ClientRule.name == None),
157
158
                (ClientRule.address == address) |
159
                (ClientRule.address == '*') |
160
                (ClientRule.address == None)
161
            )
162
            .order_by(
163
                ClientRule.priority.asc()
164
            )
165
            .first()
166
        )
167
168
        log.debug('Activity matched against rule: %r', rule)
169
170
        if rule:
171
            # Process rule
172
            if rule.account_id is not None:
173
                result['account'] = rule.account_id
174
            else:
175
                return True, result
176
        else:
177
            result['account'] = None
178
179
        return False, result
180
181
182
class ClientManager(Manager):
0 ignored issues
show
Coding Style introduced by
This class has no __init__ method.
Loading history...
183
    get = GetClient
184
    update = UpdateClient
185
186
    model = Client
187
188
    @classmethod
189
    def parse_player(cls, player):
190
        if type(player) is not dict:
191
            # Build user dict from object
192
            player = {
193
                'key': player.machine_identifier,
194
                'title': player.title,
195
196
                'platform': player.platform,
197
                'product': player.product
198
            }
199
200
        # Strip "_Video" suffix from the `key`
201
        if player.get('key') and player['key'].endswith('_Video'):
202
            # Update player key
203
            player['key'] = player['key'].rstrip('_Video')
204
205
        return player
206