Lists   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 152
Duplicated Lines 29.61 %

Test Coverage

Coverage 6.67%

Importance

Changes 0
Metric Value
wmc 21
c 0
b 0
f 0
dl 45
loc 152
ccs 4
cts 60
cp 0.0667
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
B process_update() 45 45 5
F process_sort() 0 78 13
B process() 0 25 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
import logging
6
7 1
log = logging.getLogger(__name__)
8
9
10 1
class Lists(PullListsMode):
0 ignored issues
show
Bug introduced by
The method run which was declared abstract in the super-class Mode
was not overridden.

Methods which raise NotImplementedError should be overridden in concrete child classes.

Loading history...
11 1
    def process(self, data, p_playlists, p_sections_map, t_list):
12
        log.debug('Processing list: %r', t_list)
13
14
        # Create/retrieve plex list
15
        p_playlist = self.get_playlist(
16
            p_playlists,
17
            uri='trakt://list/%s/%s' % (self.current.account.id, t_list.id),
18
            title=t_list.name
19
        )
20
21
        if not p_playlist:
22
            return
23
24
        # Retrieve trakt list items from cache
25
        t_list_items = self.trakt[(SyncMedia.Lists, data, t_list.id)]
26
27
        if t_list_items is None:
28
            log.warn('Unable to retrieve list items for: %r', t_list)
29
            return
30
31
        # Update (add/remove) list items
32
        self.process_update(data, p_playlist, p_sections_map, t_list, t_list_items.itervalues())
33
34
        # Sort list items
35
        self.process_sort(data, p_playlist, p_sections_map, t_list, t_list_items.itervalues())
36
37 1 View Code Duplication
    def process_update(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.
Loading history...
38
        # Construct playlist mapper
39
        mapper = PlaylistMapper(self.current, p_sections_map)
40
41
        # Parse plex playlist items
42
        mapper.plex.load(p_playlist)
43
44
        # Parse trakt list items
45
        mapper.trakt.load(t_list, t_list_items)
46
47
        # Match playlist items and expand shows/seasons
48
        m_trakt, m_plex = mapper.match()
49
50
        log.debug(
51
            'Update - Mapper Result (%d items)\nt_items:\n%s\n\np_items:\n%s',
52
            len(m_trakt) + len(m_plex),
53
            '\n'.join(self.format_mapper_result(m_trakt)),
54
            '\n'.join(self.format_mapper_result(m_plex))
55
        )
56
57
        # Iterate over matched trakt items
58
        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...
59
            # Expand shows/seasons into episodes
60
            for p_item, t_item in self.expand(p_items, t_items):
61
                if not t_item:
62
                    continue
63
64
                # Get `SyncMedia` for `t_item`
65
                media = self.get_media(t_item)
66
67
                if media is None:
68
                    log.warn('Unable to identify media of "t_item" (p_item: %r, t_item: %r)', p_item, t_item)
69
                    continue
70
71
                # Execute handler
72
                self.execute_handlers(
73
                    self.mode, media, data,
74
75
                    p_sections_map=p_sections_map,
76
                    p_playlist=p_playlist,
77
78
                    key=key,
79
80
                    p_item=p_item,
81
                    t_item=t_item
82
                )
83
84 1
    def process_sort(self, data, p_playlist, p_sections_map, t_list, t_list_items):
0 ignored issues
show
Unused Code introduced by
The argument data seems to be unused.
Loading history...
85
        # Construct playlist mapper
86
        mapper = PlaylistMapper(self.current, p_sections_map)
87
88
        # Parse plex playlist items
89
        mapper.plex.load(p_playlist)
90
91
        # Parse trakt list items
92
        mapper.trakt.load(t_list, t_list_items)
93
94
        # Match playlist items and expand shows/seasons
95
        m_trakt, m_plex = mapper.match()
96
97
        log.debug(
98
            'Sort - Mapper Result (%d items)\nt_items:\n%s\n\np_items:\n%s',
99
            len(m_trakt) + len(m_plex),
100
            '\n'.join(self.format_mapper_result(m_trakt)),
101
            '\n'.join(self.format_mapper_result(m_plex))
102
        )
103
104
        # Build a list of plex items (sorted by `p_index`)
105
        p_playlist_items = []
106
107
        for item in mapper.plex.items.itervalues():
0 ignored issues
show
Bug introduced by
The Instance of dict does not seem to have a member named itervalues.

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...
108
            p_playlist_items.append(item)
109
110
        p_playlist_items = [
111
            i[1]
112
            for i in sorted(p_playlist_items, key=lambda i: i[0])
113
        ]
114
115
        # Iterate over trakt items, re-order plex items
116
        t_index = 0
117
118
        for key, _, (_, p_items), (_, t_items) in m_trakt:
0 ignored issues
show
Unused Code introduced by
The variable key seems to be unused.
Loading history...
119
            # Expand shows/seasons into episodes
120
            for p_item, t_item in self.expand(p_items, t_items):
121
                if not p_item:
122
                    continue
123
124
                if p_item not in p_playlist_items:
125
                    log.info('Unable to find %r in "p_playlist_items"', p_item)
126
                    t_index += 1
127
                    continue
128
129
                p_index = p_playlist_items.index(p_item)
130
131
                if p_index == t_index:
132
                    t_index += 1
133
                    continue
134
135
                p_after = p_playlist_items[t_index - 1] if t_index > 0 else None
136
137
                log.info('[%2d:%2d] p_item: %r, t_item: %r (move after: %r)',
138
                    p_index, t_index,
139
                    p_item, t_item,
140
                    p_after
141
                )
142
143
                # Move item in plex playlist
144
                p_playlist.move(
145
                    p_item.playlist_item_id,
146
                    p_after.playlist_item_id if p_after else None
147
                )
148
149
                # Remove item from current position
150
                if t_index > p_index:
151
                    p_playlist_items[p_index] = None
152
                else:
153
                    p_playlist_items.pop(p_index)
154
155
                # Insert at new position
156
                if p_playlist_items[t_index] is None:
157
                    p_playlist_items[t_index] = p_item
158
                else:
159
                    p_playlist_items.insert(t_index, p_item)
160
161
                t_index += 1
162