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

PullListsMode   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 148
Duplicated Lines 0 %

Test Coverage

Coverage 11.49%
Metric Value
dl 0
loc 148
ccs 10
cts 87
cp 0.1149
rs 8.3999
wmc 46

9 Methods

Rating   Name   Duplication   Size   Complexity  
F expand() 0 26 10
B expand_items() 0 14 7
B format_mapper_result() 0 20 5
A format_changes() 0 9 3
A get_playlists() 0 9 3
B get_playlist() 0 13 5
B get_media() 0 21 6
B get_items() 0 12 5
A create_playlist() 0 14 2

How to fix   Complexity   

Complex Class

Complex classes like PullListsMode often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1 1
from plugin.sync.core.enums import SyncMedia
2 1
from plugin.sync.modes.core.base.mode import Mode
0 ignored issues
show
Bug introduced by
The name mode does not seem to exist in module plugin.sync.modes.core.base.
Loading history...
Configuration introduced by
Unable to import 'plugin.sync.modes.core.base.mode' (invalid syntax (<string>, line 149))

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...
3
4 1
from plex import Plex
5 1
import logging
6 1
import trakt.objects
7
8 1
log = logging.getLogger(__name__)
9
10
11 1
class PullListsMode(Mode):
0 ignored issues
show
Coding Style introduced by
This class has no __init__ method.
Loading history...
12 1
    @staticmethod
13
    def get_media(t_item):
14
        if not t_item:
15
            return None
16
17
        t_type = type(t_item)
18
19
        if t_type is trakt.objects.Movie:
20
            return SyncMedia.Movies
21
22
        if t_type is trakt.objects.Show:
23
            return SyncMedia.Shows
24
25
        if t_type is trakt.objects.Season:
26
            return SyncMedia.Seasons
27
28
        if t_type is trakt.objects.Episode:
29
            return SyncMedia.Episodes
30
31
        log.warn('Unknown "t_item" type: %r', t_type)
32
        return None
33
34 1
    @staticmethod
35
    def get_playlists():
36
        container = Plex['playlists'].all(playlist_type='video')
37
38
        if not container:
39
            return
40
41
        for playlist in container:
42
            yield playlist.title.lower(), playlist
43
44 1
    def get_playlist(self, p_playlists, uri, title):
45
        if p_playlists is None or not uri or not title:
46
            log.warn('Unable to create/retrieve playlist for: %r', title)
47
            return None
48
49
        # Try find existing playlist
50
        p_playlist = p_playlists.get(title.lower())
51
52
        if p_playlist:
53
            return p_playlist
54
55
        # Create new playlist
56
        return self.create_playlist(uri, title)
57
58 1
    def get_items(self, data, media):
59
        for m in media:
60
            # Retrieve trakt watchlist items from cache
61
            t_items = self.trakt[(m, data)]
0 ignored issues
show
Bug introduced by
The Instance of PullListsMode 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...
62
63
            if t_items is None:
64
                log.warn('Unable to retrieve items for %r watchlist', m)
65
                continue
66
67
            for item in t_items.itervalues():
68
                for t_item in self.expand_items(m, item):
69
                    yield t_item
70
71 1
    def create_playlist(self, uri, title):
72
        log.debug('Creating new playlist %r for account %r', title, self.current.account.id)
0 ignored issues
show
Bug introduced by
The Instance of PullListsMode 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...
73
74
        p_playlist = Plex['playlists'].create(
75
            type='video',
76
            title=title,
77
            uri=uri
78
        ).first()
79
80
        if p_playlist is None:
81
            log.warn('Unable to create/retrieve playlist for: %r', title)
82
            return None
83
84
        return p_playlist
85
86 1
    @classmethod
87
    def expand(cls, p_items, t_items):
88
        p_type = type(p_items)
89
        t_type = type(t_items)
90
91
        if p_type is not dict and t_type is not dict:
92
            return [(p_items, t_items)]
93
94
        result = []
95
96
        if p_type is dict and t_type is dict:
97
            # Match items by key
98
            for key, t_item in t_items.iteritems():
99
                result.extend(cls.expand(p_items.get(key), t_item))
100
        elif p_type is dict:
101
            # Iterate over plex items
102
            for p_item in p_items.itervalues():
103
                result.extend(cls.expand(p_item, t_items))
104
        elif t_type is dict:
105
            # Iterate over trakt items
106
            for t_item in t_items.itervalues():
107
                result.extend(cls.expand(p_items, t_item))
108
        else:
109
            log.warn('Unsupported items (p_items: %r, t_items: %r)', p_items, t_items)
110
111
        return result
112
113 1
    @staticmethod
114
    def expand_items(media, item):
115
        if media in [SyncMedia.Movies, SyncMedia.Shows]:
116
            yield item
117
        elif media == SyncMedia.Seasons:
118
            # Yield each season in show
119
            for t_season in item.seasons.itervalues():
120
                yield t_season
121
        elif media == SyncMedia.Episodes:
122
            # Iterate over each season in show
123
            for t_season in item.seasons.itervalues():
124
                # Yield each episode in season
125
                for t_episode in t_season.episodes.itervalues():
126
                    yield t_episode
127
128 1
    @staticmethod
129
    def format_changes(changes):
130
        for key, actions in changes.items():
131
            # Build key
132
            key = list(key)
133
            key = '/'.join([str(x) for x in key])
134
135
            yield '    [%-16s] actions: %r' % (
136
                key, actions
137
            )
138
139 1
    @staticmethod
140
    def format_mapper_result(items):
141
        for key, index, (p_index, p_item), (t_index, t_item) in items:
142
            # Build key
143
            key = list(key)
144
            key[0] = '/'.join(key[0])
145
146
            key = '/'.join([str(x) for x in key])
147
148
            # Build indices
149
            if p_index is None:
150
                p_index = '---'
151
152
            if t_index is None:
153
                t_index = '---'
154
155
            yield '    [%-16s](%3s) - %68s <[%3s] - [%3s]> %r' % (
156
                key, index,
157
                p_item, p_index,
158
                t_index, t_item
159
            )
160