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

ServiceWallabag.callback()   A

Complexity

Conditions 2

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 2
dl 0
loc 17
rs 9.4285
c 2
b 1
f 0
1
# coding: utf-8
2
# add here the call of any native lib of python like datetime etc.
3
4
# add the python API here if needed
5
from wallabag_api.wallabag import Wallabag as Wall
6
# django classes
7
from django.core.urlresolvers import reverse
8
from django.utils.log import getLogger
9
from django.core.cache import caches
10
11
# django_th classes
12
from django_th.services.services import ServicesMgr
13
from django_th.html_entities import HtmlEntities
14
from django_th.models import UserService, ServicesActivated
15
16
"""
17
    handle process with wallabag
18
    put the following in settings.py
19
20
    TH_SERVICES = (
21
        ...
22
        'th_wallabag.my_wallabag.ServiceWallabag',
23
        ...
24
    )
25
"""
26
27
logger = getLogger('django_th.trigger_happy')
28
29
cache = caches['th_wallabag']
30
31
32
class ServiceWallabag(ServicesMgr):
33
34
    def __init__(self, token=None):
35
        super(ServiceWallabag, self).__init__(token)
36
        self.token = token
37
        if token:
38
            try:
39
                us = UserService.objects.get(token=token, name='ServiceWallabag')
40
41
                self.service_username = us.username
42
                self.service_password = us.password
43
                self.service_host = us.host
44
                self.service_client_secret = us.client_secret
45
                self.service_client_id = us.client_id
46
47
                self.wall = Wall(host=self.service_host,
48
                                 client_secret=self.service_client_secret,
49
                                 client_id=self.service_client_id,
50
                                 token=self.token)
51
52
                self.us_not_found = False
53
54
            except UserService.DoesNotExist:
55
                self.us_not_found = True
56
57
    def read_data(self, **kwargs):
58
        """
59
            get the data from the service
60
            as the pocket service does not have any date
61
            in its API linked to the note,
62
            add the triggered date to the dict data
63
            thus the service will be triggered when data will be found
64
65
            :param kwargs: contain keyword args : trigger_id at least
66
            :type kwargs: dict
67
68
            :rtype: list
69
        """
70
        data = list()
71
        trigger_id = kwargs['trigger_id']
72
        cache.set('th_wallabag_' + str(trigger_id), data)
73
74
    def process_data(self, **kwargs):
75
        """
76
            get the data from the cache
77
            :param kwargs: dict
78
            :type kwargs: dict
79
        """
80
        kw = {'cache_stack': 'th_wallabag',
81
              'trigger_id': str(kwargs['trigger_id'])}
82
        return super(ServiceWallabag, self).process_data(**kw)
83
84
    def save_data(self, trigger_id, **data):
85
        """
86
            let's save the data
87
88
            :param trigger_id: trigger ID from which to save data
89
            :param data: the data to check to be used and save
90
            :type trigger_id: int
91
            :type data:  dict
92
            :return: the status of the save statement
93
            :rtype: boolean
94
        """
95
        from th_wallabag.models import Wallabag
96
97
        status = False
98
99
        if self.token and 'link' in data and data['link'] is not None\
100
                and len(data['link']) > 0:
101
            # get the data of this trigger
102
            trigger = Wallabag.objects.get(trigger_id=trigger_id)
103
104
            title = self.set_title(data)
105
            # convert htmlentities
106
            title = HtmlEntities(title).html_entity_decode
107
108
            if self.us_not_found:
109
                us = UserService.objects.get(id=data['userservice_id'])
110
                self.service_host = us.host
111
                self.service_client_secret = us.client_secret
112
                self.service_client_id = us.client_id
113
                self.token = us.token
114
115
                self.wall = Wall(host=self.service_host,
116
                                 client_secret=self.service_client_secret,
117
                                 client_id=self.service_client_id,
118
                                 token=self.token)
119
120
            try:
121
                self.wall.post_entries(url=data['link'],
122
                                       title=title,
123
                                       tags=(trigger.tag.lower()))
124
125
                sentence = str('wallabag {} created').format(data['link'])
126
                logger.debug(sentence)
127
                status = True
128
            except Exception as e:
129
                if e.errno == 401:
130
                    new_token = self.refresh_token()
131
                    UserService.objects.filter(
132
                        id=data['userservice_id']).update(
133
                        token=new_token)
134
135
                    # new wallabag session with new token
136
                    new_wall = Wall(host=self.service_host,
137
                                    client_secret=self.service_client_secret,
138
                                    client_id=self.service_client_id,
139
                                    token=new_token)
140
                    try:
141
                        return new_wall.post_entries(url=data['link'],
142
                                                     title=title,
143
                                                     tags=(trigger.tag.lower())
144
                                                     )
145
                    except Exception as e:
146
                        logger.critical(e.errno, e.strerror)
147
                        status = False
148
                else:
149
                    logger.critical(e.errno, e.strerror)
150
                    status = False
151
152
        elif self.token and 'link' in data and data['link'] is not None\
153
                and len(data['link']) == 0:
154
            logger.warning(
155
                "no link provided for trigger ID {}, so we ignore it".format(trigger_id))
156
            status = True
157
        else: 
158
            logger.critical(
159
                "no token provided for trigger ID {}".format(trigger_id))
160
            status = False
161
        return status
162
163
    def auth(self, request):
164
        """
165
            let's auth the user to the Service
166
            :param request: request object
167
            :return: callback url
168
            :rtype: string that contains the url to redirect after auth
169
 
170
        """
171
        service = UserService.objects.get(user=request.user, name='ServiceWallabag')
172
        callback_url = 'http://%s%s' % (
173
            request.get_host(), reverse('wallabag_callback'))
174
        params = {'username': service.username,
175
                  'password': service.password,
176
                  'client_id': service.client_id,
177
                  'client_secret': service.client_secret}
178
        access_token = Wall.get_token(host=service.host, **params)
179
        request.session['oauth_token'] = access_token
180
        return callback_url
181
182
    def callback(self, request, **kwargs):
183
        """
184
            Called from the Service when the user accept to activate it
185
            :param request: request object
186
            :return: callback url
187
            :rtype: string , path to the template
188
        """
189
190
        try:
191
            UserService.objects.filter(
192
                user=request.user,
193
                name=ServicesActivated.objects.get(name='ServiceWallabag')
194
            )
195
        except KeyError:
196
            return '/'
197
198
        return 'wallabag/callback.html'
199
200
    def refresh_token(self):
201
        """
202
            refresh the expired token
203
            :return: boolean
204
        """
205
        params = {'username': self.service_username,
206
                  'password': self.service_password,
207
                  'client_id': self.service_client_id,
208
                  'client_secret': self.service_client_secret}
209
        return Wall.get_token(host=self.service_host, **params)
210