Completed
Branch master (28ef54)
by Fox
01:25
created

ServicePocket.save_data()   F

Complexity

Conditions 10

Size

Total Lines 45

Duplication

Lines 29
Ratio 64.44 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 10
dl 29
loc 45
rs 3.1304
c 2
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like ServicePocket.save_data() 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
# coding: utf-8
2
import datetime
3
import time
4
import arrow
5
6
# pocket API
7
from pocket import Pocket
8
9
# django classes
10
from django.conf import settings
11
from django.utils.log import getLogger
12
from django.core.cache import caches
13
14
# django_th classes
15
from django_th.services.services import ServicesMgr
16
from django_th.html_entities import HtmlEntities
17
18
"""
19
    handle process with pocket
20
    put the following in settings.py
21
22
    TH_POCKET = {
23
        'consumer_key': 'abcdefghijklmnopqrstuvwxyz',
24
    }
25
26
    TH_SERVICES = (
27
        ...
28
        'th_pocket.my_pocket.ServicePocket',
29
        ...
30
    )
31
32
"""
33
34
logger = getLogger('django_th.trigger_happy')
35
36
cache = caches['th_pocket']
37
38
39
class ServicePocket(ServicesMgr):
40
41
    def __init__(self, token=None):
42
        super(ServicePocket, self).__init__(token)
43
        self.consumer_key = settings.TH_POCKET['consumer_key']
44
        self.token = token
45
        if token:
46
            self.pocket = Pocket(self.consumer_key, token)
47
48
    def read_data(self, **kwargs):
49
        """
50
            get the data from the service
51
            as the pocket service does not have any date
52
            in its API linked to the note,
53
            add the triggered date to the dict data
54
            thus the service will be triggered when data will be found
55
56
            :param kwargs: contain keyword args : trigger_id at least
57
            :type kwargs: dict
58
59
            :rtype: list
60
        """
61
        trigger_id = kwargs['trigger_id']
62
        date_triggered = kwargs['date_triggered']
63
64
        data = list()
65
        # pocket uses a timestamp date format
66
        since = int(
67
            time.mktime(datetime.datetime.timetuple(date_triggered)))
68
69
        if self.token is not None:
70
71
            # get the data from the last time the trigger have been started
72
            # timestamp form
73
            pockets = self.pocket.get(since=since, state="unread")
74
            content = ''
75
            if pockets is not None and len(pockets[0]['list']) > 0:
76
                for my_pocket in pockets[0]['list'].values():
77
                    if my_pocket['excerpt']:
78
                        content = my_pocket['excerpt']
79
                    elif my_pocket['given_title']:
80
                        content = my_pocket['given_title']
81
                    my_date = arrow.get(str(date_triggered),
82
                                        'YYYY-MM-DD HH:mm:ss')\
83
                                   .to(settings.TIME_ZONE)
84
                    data.append({'my_date': str(my_date),
85
                                 'tag': '',
86
                                 'link': my_pocket['given_url'],
87
                                 'title': my_pocket['given_title'],
88
                                 'content': content,
89
                                 'tweet_id': 0})
90
                cache.set('th_pocket_' + str(trigger_id), data)
91
92
        return data
93
94
    def process_data(self, **kwargs):
95
        """
96
            get the data from the cache
97
            :param kwargs: contain keyword args : trigger_id at least
98
            :type kwargs: dict
99
        """
100
        kw = {'cache_stack': 'th_pocket',
101
              'trigger_id': str(kwargs['trigger_id'])}
102
        return super(ServicePocket, self).process_data(**kw)
103
104
    def save_data(self, trigger_id, **data):
105
        """
106
            let's save the data
107
108
            :param trigger_id: trigger ID from which to save data
109
            :param data: the data to check to be used and save
110
            :type trigger_id: int
111
            :type data:  dict
112
            :return: the status of the save statement
113
            :rtype: boolean
114
        """
115
        from th_pocket.models import Pocket as PocketModel
116
117
        status = False
118
119 View Code Duplication
        if self.token and 'link' in data and data['link'] is not None\
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
120
                and len(data['link']) > 0:
121
            # get the pocket data of this trigger
122
            trigger = PocketModel.objects.get(trigger_id=trigger_id)
123
124
            title = self.set_title(data)
125
            # convert htmlentities
126
            title = HtmlEntities(title).html_entity_decode
127
128
            try:
129
                self.pocket.add(
130
                    url=data['link'], title=title, tags=(trigger.tag.lower()))
131
132
                sentence = str('pocket {} created').format(data['link'])
133
                logger.debug(sentence)
134
                status = True
135
            except Exception as e:
136
                logger.critical(e)
137
                status = False
138
139
        elif self.token and 'link' in data and data['link'] is not None\
140
                and len(data['link']) == 0:
141
            logger.warning(
142
                "no link provided for trigger ID {}, so we ignore it".format(trigger_id))
143
            status = True
144
        else: 
145
            logger.critical(
146
                "no token provided for trigger ID {}".format(trigger_id))
147
            status = False
148
        return status
149
150
    def auth(self, request):
151
        """
152
            let's auth the user to the Service
153
            :param request: request object
154
            :return: callback url
155
            :rtype: string that contains the url to redirect after auth
156
        """
157
        callback_url = self.callback_url(request, 'pocket')
158
159
        request_token = Pocket.get_request_token(
160
            consumer_key=self.consumer_key,
161
            redirect_uri=callback_url)
162
163
        # Save the request token information for later
164
        request.session['request_token'] = request_token
165
166
        # URL to redirect user to, to authorize your app
167
        auth_url = Pocket.get_auth_url(
168
            code=request_token, redirect_uri=callback_url)
169
170
        return auth_url
171
172
    def callback(self, request, **kwargs):
173
        """
174
            Called from the Service when the user accept to activate it
175
            :param request: request object
176
            :return: callback url
177
            :rtype: string , path to the template
178
        """
179
        access_token = Pocket.get_access_token(
180
            consumer_key=self.consumer_key,
181
            code=request.session['request_token'])
182
183
        kwargs = {'access_token': access_token, 'service': 'ServicePocket',
184
                  'return': 'pocket'}
185
186
        return super(ServicePocket, self).callback(request, **kwargs)
187