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

ServiceReadability.save_data()   F

Complexity

Conditions 12

Size

Total Lines 42

Duplication

Lines 29
Ratio 69.05 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 12
dl 29
loc 42
rs 2.7855
c 2
b 1
f 0

How to fix   Complexity   

Complexity

Complex classes like ServiceReadability.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
# readability API
3
from readability import ReaderClient
4
5
# django classes
6
from django.conf import settings
7
from django.utils.log import getLogger
8
from django.core.cache import caches
9
10
# django_th classes
11
from django_th.services.services import ServicesMgr
12
from th_readability.models import Readability
13
14
"""
15
    handle process with readability
16
    put the following in settings.py
17
18
    TH_READABILITY = {
19
        'consumer_key': 'abcdefghijklmnopqrstuvwxyz',
20
        'consumer_secret': 'abcdefghijklmnopqrstuvwxyz',
21
    }
22
23
    TH_SERVICES = (
24
        ...
25
        'th_readability.my_readability.ServiceReadability',
26
        ...
27
    )
28
29
"""
30
31
logger = getLogger('django_th.trigger_happy')
32
33
cache = caches['th_readability']
34
35
36
class ServiceReadability(ServicesMgr):
37
38 View Code Duplication
    def __init__(self, token=None):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
39
        super(ServiceReadability, self).__init__(token)
40
        base = 'https://www.readability.com'
41
        self.AUTH_URL = '{}/api/rest/v1/oauth/authorize/'.format(base)
42
        self.REQ_TOKEN = '{}/api/rest/v1/oauth/request_token/'.format(base)
43
        self.ACC_TOKEN = '{}/api/rest/v1/oauth/access_token/'.format(base)
44
        self.consumer_key = settings.TH_READABILITY['consumer_key']
45
        self.consumer_secret = settings.TH_READABILITY['consumer_secret']
46
        self.token = token
47
        kwargs = {'consumer_key': self.consumer_key,
48
                  'consumer_secret': self.consumer_secret}
49
        if token:
50
            token_key, token_secret = self.token.split('#TH#')
51
            self.client = ReaderClient(token_key, token_secret, **kwargs)
52
53
    def read_data(self, **kwargs):
54
        """
55
            get the data from the service
56
57
            :param kwargs: contain keyword args : trigger_id at least
58
            :type kwargs: dict
59
60
            :rtype: list
61
        """
62
        date_triggered = kwargs['date_triggered']
63
        trigger_id = kwargs['trigger_id']
64
        data = []
65
66
        if self.token is not None:
67
68
            bookmarks = self.client.get_bookmarks(
69
                added_since=date_triggered).content
70
71
            for bookmark in bookmarks.values():
72
73
                for b in bookmark:
74
                    if 'article' in b:
75
                        title = ''
76
                        if 'title' in b['article']:
77
                            title = b['article']['title']
78
79
                        link = ''
80
                        if 'url' in b['article']:
81
                            link = b['article']['url']
82
83
                        content = ''
84
                        if 'excerpt' in b['article']:
85
                            content = b['article']['excerpt']
86
87
                        data.append(
88
                            {'title': title,
89
                             'link': link,
90
                             'content': content})
91
92
            cache.set('th_readability_' + str(trigger_id), data)
93
94
        return data
95
96
    def process_data(self, **kwargs):
97
        """
98
            get the data from the cache
99
            :param kwargs: contain keyword args : trigger_id at least
100
            :type kwargs: dict
101
        """
102
        kw = {'cache_stack': 'th_readability',
103
              'trigger_id': str(kwargs['trigger_id'])}
104
        return super(ServiceReadability, self).process_data(**kw)
105
106
    def save_data(self, trigger_id, **data):
107
        """
108
            let's save the data
109
110
            :param trigger_id: trigger ID from which to save data
111
            :param data: the data to check to be used and save
112
            :type trigger_id: int
113
            :type data:  dict
114
            :return: the status of the save statement
115
            :rtype: boolean
116
        """
117
        status = False
118 View Code Duplication
        if self.token and 'link' in data and\
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
119
           data['link'] is not None and\
120
           len(data['link']) > 0:
121
            # get the data of this trigger
122
            trigger = Readability.objects.get(trigger_id=trigger_id)
123
124
            bookmark_id = self.client.add_bookmark(url=data['link'])
125
126
            if trigger.tag is not None and len(trigger.tag) > 0:
127
                try:
128
                    self.client.add_tags_to_bookmark(
129
                        bookmark_id, tags=(trigger.tag.lower()))
130
                    sentence = str('readability {} created item id {}').format(
131
                        data['link'], bookmark_id)
132
                    logger.debug(sentence)
133
                    status = True
134
                except Exception as e:
135
                    logger.critical(e)
136
                    status = False
137
138
        elif self.token and 'link' in data and data['link'] is not None\
139
                and len(data['link']) == 0:
140
            logger.warning(
141
                "no link provided for trigger ID {}, so we ignore it".format(trigger_id))
142
            status = True
143
        else: 
144
            logger.critical(
145
                "no token provided for trigger ID {}".format(trigger_id))
146
            status = False
147
        return status
148
149
    def auth(self, request):
150
        """
151
            let's auth the user to the Service
152
            :param request: request object
153
            :return: callback url
154
            :rtype: string that contains the url to redirect after auth
155
        """
156
        request_token = super(ServiceReadability, self).auth(request)
157
        callback_url = self.callback_url(request, 'readability')
158
159
        # URL to redirect user to, to authorize your app
160
        auth_url_str = '%s?oauth_token=%s&oauth_callback=%s'
161
        auth_url = auth_url_str % (self.AUTH_URL,
162
                                   request_token['oauth_token'],
163
                                   callback_url)
164
165
        return auth_url
166
167
    def callback(self, request, **kwargs):
168
        """
169
            Called from the Service when the user accept to activate it
170
            :param request: request object
171
            :return: callback url
172
            :rtype: string , path to the template
173
        """
174
        kwargs = {'access_token': '', 'service': 'ServiceReadability',
175
                  'return': 'readability'}
176
        return super(ServiceReadability, self).callback(request, **kwargs)
177