Passed
Push — beta ( 8fb445...6d3439 )
by Dean
02:27
created

Lists.update_changed()   D

Complexity

Conditions 9

Size

Total Lines 73

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 81.9024
Metric Value
cc 9
dl 0
loc 73
ccs 1
cts 29
cp 0.0345
crap 81.9024
rs 4.1001

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 p_index seems to be unused.
Loading history...
Unused Code introduced by
The variable 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 not t_item:
114
                    continue
115
116
                if len(key) < 1:
117
                    log.warn('Invalid "key" format: %r', key)
118
                    continue
119
120
                actions = list(t_changes.get(key[0], []))
121
122
                if not actions:
123
                    continue
124
125
                if len(actions) > 1:
126
                    log.warn('Multiple actions returned for %r: %r', key[0], actions)
127
                    continue
128
129
                # Get `SyncMedia` for `t_item`
130
                media = self.get_media(t_item)
131
132
                if media is None:
133
                    log.warn('Unable to identify media of "t_item" (p_item: %r, t_item: %r)', p_item, t_item)
134
                    continue
135
136
                # Execute handler
137
                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...
138
                    media, data,
139
140
                    action=actions[0],
141
142
                    p_sections_map=p_sections_map,
143
                    p_playlist=p_playlist,
144
145
                    key=key,
146
147
                    p_item=p_item,
148
                    t_item=t_item
149
                )
150
151 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...
152
        # Construct playlist mapper
153
        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...
154
155
        # Parse plex playlist items
156
        mapper.plex.load(p_playlist)
157
158
        # Parse trakt list items
159
        mapper.trakt.load(t_list, t_list_items)
160
161
        # Match playlist items and expand shows/seasons
162
        m_trakt, m_plex = mapper.match()
163
164
        log.debug(
165
            'Update - Mapper Result (%d items)\nt_items:\n%s\n\np_items:\n%s',
166
            len(m_trakt) + len(m_plex),
167
            '\n'.join(self.format_mapper_result(m_trakt)),
168
            '\n'.join(self.format_mapper_result(m_plex))
169
        )
170
171
        # Iterate over matched trakt items
172
        for key, index, (p_index, p_items), (t_index, t_items) in m_trakt:
0 ignored issues
show
Unused Code introduced by
The variable p_index seems to be unused.
Loading history...
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...
173
            # Expand shows/seasons into episodes
174
            for p_item, t_item in self.expand(p_items, t_items):
175
                if not t_item:
176
                    continue
177
178
                # Get `SyncMedia` for `t_item`
179
                media = self.get_media(t_item)
180
181
                if media is None:
182
                    log.warn('Unable to identify media of "t_item" (p_item: %r, t_item: %r)', p_item, t_item)
183
                    continue
184
185
                # Execute handler
186
                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...
187
                    media, data,
188
189
                    p_sections_map=p_sections_map,
190
                    p_playlist=p_playlist,
191
192
                    key=key,
193
194
                    p_item=p_item,
195
                    t_item=t_item
196
                )
197
198 1
    def get_changed_lists(self, data, extra=None):
199
        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...
200
            m, d = key[0:2]
201
202
            if len(key) > 2:
203
                e = key[2:]
204
            else:
205
                e = None
206
207
            if m != SyncMedia.Lists:
208
                continue
209
210
            if d != data:
211
                continue
212
213
            if extra is True and e is None:
214
                continue
215
            elif e != extra:
216
                continue
217
218
            yield key, result
219
220 1
    def get_changed_items(self, data):
221
        changes = {}
222
223
        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...
224
            m, d = key[0:2]
0 ignored issues
show
Unused Code introduced by
The variable m seems to be unused.
Loading history...
225
226
            if d != data:
227
                # Ignore non-watchlist data
228
                continue
229
230
            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...
231
                # Data type has been disabled
232
                continue
233
234
            data_name = Cache.Data.get(d)
235
236
            if data_name not in result.changes:
237
                # No changes for collection
238
                continue
239
240
            for action, t_items in result.changes[data_name].items():
241
                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...
242
                    if guid not in changes:
243
                        changes[guid] = set()
244
245
                    changes[guid].add(action)
246
247
        return changes
248