Test Setup Failed
Push — develop ( e459d6...12ef70 )
by Dean
02:19
created

Lists   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 231
Duplicated Lines 0 %

Test Coverage

Coverage 6.93%
Metric Value
dl 0
loc 231
ccs 7
cts 101
cp 0.0693
rs 8.2857
wmc 39

6 Methods

Rating   Name   Duplication   Size   Complexity  
B process() 0 30 6
B update_full() 0 42 4
C get_changed_lists() 0 21 8
D get_changed_items() 0 28 8
C update_changed() 0 70 8
B process_list() 0 29 5
1 1
from plugin.sync.core.enums import SyncMedia
2 1
from plugin.sync.core.playlist.mapper import PlaylistMapper
3 1
from plugin.sync.modes.core.base import PullListsMode
4
5 1
from trakt_sync.cache.main import Cache
6 1
import logging
7
8 1
log = logging.getLogger(__name__)
9
10
11 1
class Lists(PullListsMode):
0 ignored issues
show
Coding Style introduced by
This class has no __init__ method.
Loading history...
12 1
    def process(self, data, p_playlists, p_sections_map):
13
        # Iterate over trakt list changes
14
        for key, result in self.get_changed_lists(data):
15
            if 'lists' not in result.changes:
16
                log.warn('Unable to find "lists" key in changes: %r', result.changes)
17
                continue
18
19
            for action, t_items in result.changes['lists'].items():
20
                for t_list_id, t_item in t_items.items():
0 ignored issues
show
Unused Code introduced by
The variable t_item seems to be unused.
Loading history...
21
                    # Try retrieve trakt list
22
                    t_list = self.trakt[key].get(t_list_id)
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named trakt.

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...
23
24
                    # Execute handlers for list
25
                    self.execute_handlers(
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named execute_handlers.

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...
26
                        SyncMedia.Lists, data,
27
                        action=action,
28
29
                        p_playlists=p_playlists,
30
31
                        key=t_list_id,
32
33
                        t_list=t_list
34
                    )
35
36
                    if action == 'removed':
37
                        # No changes to list items required
38
                        continue
39
40
                    # Process list items
41
                    self.process_list(action, data, p_playlists, p_sections_map, t_list)
42
43 1
    def process_list(self, action, data, p_playlists, p_sections_map, t_list):
44
        log.debug('Processing list: %r', t_list)
45
46
        # Create/retrieve plex list
47
        p_playlist = self.get_playlist(
48
            p_playlists,
49
            uri='trakt://list/%s/%s' % (self.current.account.id, t_list.id),
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named current.

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...
50
            title=t_list.name
51
        )
52
53
        if not p_playlist:
54
            log.warn('Unable to create/retrieve playlist with name: %r', t_list.name)
55
            return
56
57
        # Retrieve trakt list items from cache
58
        t_list_items = self.trakt[(SyncMedia.Lists, data, t_list.id)]
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named trakt.

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...
59
60
        if t_list_items is None:
61
            log.warn('Unable to retrieve list items for: %r', t_list)
62
            return
63
64
        # Update (add/remove) list items
65
        if action == 'added':
66
            self.update_full(data, p_playlist, p_sections_map, t_list, t_list_items.itervalues())
67
        elif action == 'changed':
68
            self.update_changed(data, p_playlist, p_sections_map, t_list, t_list_items.itervalues())
69
        else:
70
            log.warn('Unsupported action for process(): %r', action)
71
            return
72
73
        # TODO Sort list items
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
74
        # self.process_sort(data, p_playlist, p_sections_map, t_list, t_list_items.itervalues())
75
76 1
    def update_changed(self, data, p_playlist, p_sections_map, t_list=None, t_list_items=None):
77
        # Retrieve changed items
78
        t_changes = self.get_changed_items(data)
79
80
        if not t_changes:
81
            log.debug('No changes detected in %r collection', data)
82
            return
83
84
        # Construct playlist mapper
85
        mapper = PlaylistMapper(self.current, p_sections_map)
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named current.

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...
86
87
        # Parse plex playlist items
88
        mapper.plex.load(p_playlist)
89
90
        # Parse trakt list items
91
        mapper.trakt.load(t_list, t_list_items)
92
93
        # Match playlist items and expand shows/seasons
94
        m_trakt, m_plex = mapper.match()
95
96
        log.debug(
97
            'Update - Mapper Result (%d items)\nt_items:\n%s\n\np_items:\n%s',
98
            len(m_trakt) + len(m_plex),
99
            '\n'.join(self.format_mapper_result(m_trakt)),
100
            '\n'.join(self.format_mapper_result(m_plex))
101
        )
102
103
        log.debug(
104
            'Update - Changes (%d keys)\n%s',
105
            len(t_changes),
106
            '\n'.join(self.format_changes(t_changes)),
107
        )
108
109
        # Iterate over matched trakt items
110
        for key, index, (p_index, p_items), (t_index, t_items) in m_trakt:
0 ignored issues
show
Unused Code introduced by
The variable t_index seems to be unused.
Loading history...
Unused Code introduced by
The variable index seems to be unused.
Loading history...
Unused Code introduced by
The variable p_index seems to be unused.
Loading history...
111
            # Expand shows/seasons into episodes
112
            for p_item, t_item in self.expand(p_items, t_items):
113
                if len(key) < 1:
114
                    log.warn('Invalid "key" format: %r', key)
115
                    continue
116
117
                actions = list(t_changes.get(key[0], []))
118
119
                if not actions:
120
                    continue
121
122
                if len(actions) > 1:
123
                    log.warn('Multiple actions returned for %r: %r', key[0], actions)
124
                    continue
125
126
                # Get `SyncMedia` for `t_item`
127
                media = self.get_media(t_item)
128
129
                if media is None:
130
                    log.warn('Unable to identify media of "t_item" (p_item: %r, t_item: %r)', p_item, t_item)
131
                    continue
132
133
                # Execute handler
134
                self.execute_handlers(
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named execute_handlers.

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...
135
                    media, data,
136
137
                    action=actions[0],
138
139
                    p_sections_map=p_sections_map,
140
                    p_playlist=p_playlist,
141
142
                    key=key,
143
144
                    p_item=p_item,
145
                    t_item=t_item
146
                )
147
148 1
    def update_full(self, data, p_playlist, p_sections_map, t_list=None, t_list_items=None):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
149
        # Construct playlist mapper
150
        mapper = PlaylistMapper(self.current, p_sections_map)
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named current.

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...
151
152
        # Parse plex playlist items
153
        mapper.plex.load(p_playlist)
154
155
        # Parse trakt list items
156
        mapper.trakt.load(t_list, t_list_items)
157
158
        # Match playlist items and expand shows/seasons
159
        m_trakt, m_plex = mapper.match()
160
161
        log.debug(
162
            'Update - Mapper Result (%d items)\nt_items:\n%s\n\np_items:\n%s',
163
            len(m_trakt) + len(m_plex),
164
            '\n'.join(self.format_mapper_result(m_trakt)),
165
            '\n'.join(self.format_mapper_result(m_plex))
166
        )
167
168
        # Iterate over matched trakt items
169
        for key, index, (p_index, p_items), (t_index, t_items) in m_trakt:
0 ignored issues
show
Unused Code introduced by
The variable t_index seems to be unused.
Loading history...
Unused Code introduced by
The variable index seems to be unused.
Loading history...
Unused Code introduced by
The variable p_index seems to be unused.
Loading history...
170
            # Expand shows/seasons into episodes
171
            for p_item, t_item in self.expand(p_items, t_items):
172
                # Get `SyncMedia` for `t_item`
173
                media = self.get_media(t_item)
174
175
                if media is None:
176
                    log.warn('Unable to identify media of "t_item" (p_item: %r, t_item: %r)', p_item, t_item)
177
                    continue
178
179
                # Execute handler
180
                self.execute_handlers(
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named execute_handlers.

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...
181
                    media, data,
182
183
                    p_sections_map=p_sections_map,
184
                    p_playlist=p_playlist,
185
186
                    key=key,
187
188
                    p_item=p_item,
189
                    t_item=t_item
190
                )
191
192 1
    def get_changed_lists(self, data, extra=None):
193
        for key, result in self.trakt.changes:
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named trakt.

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...
194
            m, d = key[0:2]
195
196
            if len(key) > 2:
197
                e = key[2:]
198
            else:
199
                e = None
200
201
            if m != SyncMedia.Lists:
202
                continue
203
204
            if d != data:
205
                continue
206
207
            if extra is True and e is None:
208
                continue
209
            elif e != extra:
210
                continue
211
212
            yield key, result
213
214 1
    def get_changed_items(self, data):
215
        changes = {}
216
217
        for key, result in self.trakt.changes:
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named trakt.

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...
218
            m, d = key[0:2]
0 ignored issues
show
Unused Code introduced by
The variable m seems to be unused.
Loading history...
219
220
            if d != data:
221
                # Ignore non-watchlist data
222
                continue
223
224
            if not self.is_data_enabled(d):
0 ignored issues
show
Bug introduced by
The Instance of Lists does not seem to have a member named is_data_enabled.

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...
225
                # Data type has been disabled
226
                continue
227
228
            data_name = Cache.Data.get(d)
229
230
            if data_name not in result.changes:
231
                # No changes for collection
232
                continue
233
234
            for action, t_items in result.changes[data_name].items():
235
                for guid, t_item in t_items.items():
0 ignored issues
show
Unused Code introduced by
The variable t_item seems to be unused.
Loading history...
236
                    if guid not in changes:
237
                        changes[guid] = set()
238
239
                    changes[guid].add(action)
240
241
        return changes
242