Test Failed
Push — beta ( 0690ba...d810a3 )
by Dean
03:56
created

Base.build_request()   D

Complexity

Conditions 10

Size

Total Lines 59

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 59
ccs 0
cts 30
cp 0
rs 4.8648
cc 10
crap 110

How to fix   Long Method    Complexity   

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:

Complexity

Complex classes like Base.build_request() 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
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.core.identifier import Identifier
4
from plugin.managers.session.base import UpdateSession
0 ignored issues
show
Bug introduced by
The name base does not seem to exist in module plugin.managers.session.
Loading history...
Configuration introduced by
Unable to import 'plugin.managers.session.base' (invalid syntax (<string>, line 67))

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...
5
from plugin.modules.core.manager import ModuleManager
0 ignored issues
show
Bug introduced by
The name manager does not seem to exist in module plugin.modules.core.
Loading history...
Configuration introduced by
Unable to import 'plugin.modules.core.manager' (invalid syntax (<string>, line 40))

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...
6
7
from plex.objects.library.metadata.episode import Episode
8
from plex.objects.library.metadata.movie import Movie
9
from plex_metadata import Metadata, Guid
10
import logging
11
12
log = logging.getLogger(__name__)
13
14
15
class Base(object):
16
    name = None
17
18
    @classmethod
19
    def build_request(cls, session, part=None, rating_key=None, view_offset=None):
20
        # Retrieve metadata for session
21
        if part is None:
22
            part = session.part
23
24
        if rating_key is None:
25
            rating_key = session.rating_key
26
27
        # Retrieve metadata
28
        metadata = Metadata.get(rating_key)
29
30
        # Queue a flush for the metadata cache
31
        Metadata.cache.flush_queue()
32
33
        # Validate metadata
34
        if not metadata:
35
            log.warn('Unable to retrieve metadata for rating_key %r', rating_key)
36
            return None
37
38
        if metadata.type not in ['movie', 'episode']:
39
            log.info('Ignoring session with type %r for rating_key %r', metadata.type, rating_key)
40
            return None
41
42
        # Apply library/section filter
43
        if not Filters.is_valid_metadata_section(metadata):
44
            log.info('Ignoring session in filtered section: %r', metadata.section.title)
45
            return None
46
47
        # Parse guid
48
        guid = Guid.parse(metadata.guid)
49
50
        # Build request from guid/metadata
51
        if type(metadata) is Movie:
52
            result = cls.build_movie(metadata, guid, part)
53
        elif type(metadata) is Episode:
54
            result = cls.build_episode(metadata, guid, part)
55
        else:
56
            log.warn('Unknown metadata type: %r', type(metadata))
57
            return None
58
59
        if not result:
60
            log.warn('Unable to build request for session: %r', session)
61
            return None
62
63
        # Retrieve media progress
64
        if view_offset is not None:
65
            # Calculate progress from `view_offset` parameter
66
            progress = UpdateSession.get_progress(
67
                metadata.duration, view_offset,
68
                part, session.part_count, session.part_duration
69
            )
70
        else:
71
            # Use session progress
72
            progress = session.progress
73
74
        # Merge progress into request
75
        return merge(result, {
76
            'progress': progress
77
        })
78
79
    @classmethod
80
    def build_episode(cls, episode, guid, part):
81
        ids = Identifier.get_ids(guid, strict=False)
82
83
        if not ids:
84
            # Try map episode to a supported service (with OEM)
85
            _, request = ModuleManager['mapper'].request_episode(
86
                guid, episode,
87
                part=part
88
            )
89
            return request
90
91
        # Retrieve episode number
92
        season_num, episodes = ModuleManager['matcher'].process(episode)
93
94
        if len(episodes) > 0 and part - 1 < len(episodes):
95
            episode_num = episodes[part - 1]
96
        elif len(episodes) > 1:
97
            log.warn('Part %s doesn\'t exist in episodes: %r', part, episodes)
98
            episode_num = episodes[0]
99
        else:
100
            log.warn('Matcher didn\'t return a valid result - season_num: %r, episodes: %r', season_num, episodes)
101
            episode_num = episode.index
102
103
        # Build request
104
        return {
105
            'show': {
106
                'title': episode.show.title,
107
                'year': episode.year,
108
109
                'ids': ids
110
            },
111
            'episode': {
112
                'title': episode.title,
113
114
                'season': season_num,
115
                'number': episode_num
116
            }
117
        }
118
119
    @staticmethod
120
    def build_movie(movie, guid, part):
121
        ids = Identifier.get_ids(guid, strict=False)
122
123
        if not ids:
124
            # Try map episode to a supported service (with OEM)
125
            _, request = ModuleManager['mapper'].request_movie(
126
                guid, movie,
127
                part=part
128
            )
129
            return request
130
131
        return {
132
            'movie': {
133
                'title': movie.title,
134
                'year': movie.year,
135
136
                'ids': ids
137
            }
138
        }
139
140
    @staticmethod
141
    def session_jumped(session, view_offset):
142
        if session.view_offset is None or view_offset is None:
143
            return False
144
145
        view_delta = view_offset - session.view_offset
146
147
        jump_offset = session.duration - session.view_offset - view_delta
148
        jump_perc = float(view_delta) / session.duration
149
150
        if jump_perc >= 0.98 and jump_offset < 1000:
151
            log.info('Session jumped: %r -> %r (delta: %r, jump_offset: %r, jump_perc: %r)', session.view_offset, view_offset, view_delta, jump_offset, jump_perc)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (162/120).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
152
            return True
153
154
        return False
155