ServiceReddit.__init__()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 2
c 3
b 0
f 0
dl 0
loc 13
rs 9.4285
1
# coding: utf-8
2
import arrow
3
# add the python API here if needed
4
from praw import Reddit as RedditApi
5
# django classes
6
from django.conf import settings
7
from django.core.cache import caches
8
from django.core.urlresolvers import reverse
9
from logging import getLogger
10
11
# django_th classes
12
from django_th.services.services import ServicesMgr
13
from django_th.models import update_result, UserService
14
from th_reddit.models import Reddit
15
16
17
"""
18
put the following in settings.py
19
TH_REDDIT_KEY = {
20
    'client_id': 'abcdefghijklmnopqrstuvwxyz',
21
    'client_secret': 'abcdefghijklmnopqrstuvwxyz',
22
    'user_agent': '<platform>:<app ID>:<version> (by /u/<reddit username>)'
23
}
24
25
TH_SERVICES = (
26
    ...
27
    'th_reddit.my_reddit.ServiceReddit',
28
    ...
29
)
30
"""
31
32
logger = getLogger('django_th.trigger_happy')
33
34
cache = caches['django_th']
35
36
37
class ServiceReddit(ServicesMgr):
38
    """
39
        service Reddit
40
    """
41
    def __init__(self, token=None, **kwargs):
42
        super(ServiceReddit, self).__init__(token, **kwargs)
43
        self.consumer_key = settings.TH_REDDIT_KEY['client_id']
44
        self.consumer_secret = settings.TH_REDDIT_KEY['client_secret']
45
        self.user_agent = settings.TH_REDDIT_KEY['user_agent']
46
        self.service = 'ServiceReddit'
47
        self.oauth = 'oauth2'
48
        if token:
49
            self.token = token
50
            self.reddit = RedditApi(client_id=self.consumer_key,
51
                                    client_secret=self.consumer_secret,
52
                                    refresh_token=self.token,
53
                                    user_agent=self.user_agent)
54
55
    def read_data(self, **kwargs):
56
        """
57
            get the data from the service
58
            as the pocket service does not have any date
59
            in its API linked to the note,
60
            add the triggered date to the dict data
61
            thus the service will be triggered when data will be found
62
63
            :param kwargs: contain keyword args : trigger_id at least
64
            :type kwargs: dict
65
66
            :rtype: list
67
        """
68
        trigger_id = kwargs.get('trigger_id')
69
        trigger = Reddit.objects.get(trigger_id=trigger_id)
70
        date_triggered = kwargs.get('date_triggered')
71
        data = list()
72
        submissions = self.reddit.subreddit(trigger.subreddit).top('all')
73
        for submission in submissions:
74
            title = 'From Reddit ' + submission.title
75
            created = arrow.get(submission.created)
76
            if created > date_triggered and submission.selftext is not None \
77
                    and trigger.share_link:
78
                body = submission.selftext if submission.selftext \
79
                    else submission.url
80
                data.append({'title': title, 'content': body})
81
                self.send_digest_event(trigger_id, title, '')
82
83
        cache.set('th_reddit_' + str(trigger_id), data)
84
        return data
85
86
    def save_data(self, trigger_id, **data):
87
        """
88
            let's save the data
89
            :param trigger_id: trigger ID from which to save data
90
            :param data: the data to check to be used and save
91
            :type trigger_id: int
92
            :type data:  dict
93
            :return: the status of the save statement
94
            :rtype: boolean
95
        """
96
        # convert the format to be released in Markdown
97
        status = False
98
        data['output_format'] = 'md'
99
        title, content = super(ServiceReddit, self).save_data(trigger_id,
100
                                                              **data)
101
        if self.token:
102
103
            trigger = Reddit.objects.get(trigger_id=trigger_id)
104
            if trigger.share_link:
105
                status = self.reddit.subreddit(trigger.subreddit)\
106
                    .submit(title=title, url=content)
107
            else:
108
                status = self.reddit.subreddit(trigger.subreddit)\
109
                    .submit(title=title, selftext=content)
110
            sentence = str('reddit submission {} created').format(title)
111
            logger.debug(sentence)
112
        else:
113
            msg = "no token or link provided for trigger " \
114
                  "ID {} ".format(trigger_id)
115
            logger.critical(msg)
116
            update_result(trigger_id, msg=msg, status=False)
117
        return status
118
119
    def auth(self, request):
120
        """
121
122
        :param request:
123
        :return:
124
        """
125
        redirect_uri = '%s://%s%s' % (request.scheme, request.get_host(),
126
                                      reverse("reddit_callback"))
127
        reddit = RedditApi(client_id=self.consumer_key,
128
                           client_secret=self.consumer_secret,
129
                           redirect_uri=redirect_uri,
130
                           user_agent=self.user_agent)
131
        auth_url = reddit.auth.url(['identity', 'read', 'submit', 'save'],
132
                                   'redirect_uri')
133
        return auth_url
134
135
    def callback(self, request, **kwargs):
136
        """
137
            Called from the Service when the user accept to activate it
138
            the url to go back after the external service call
139
            :param request: contains the current session
140
            :param kwargs: keyword args
141
            :type request: dict
142
            :type kwargs: dict
143
            :rtype: string
144
        """
145
        code = request.GET.get('code', '')
146
        redirect_uri = '%s://%s%s' % (request.scheme, request.get_host(),
147
                                      reverse("reddit_callback"))
148
        reddit = RedditApi(client_id=self.consumer_key,
149
                           client_secret=self.consumer_secret,
150
                           redirect_uri=redirect_uri,
151
                           user_agent=self.user_agent)
152
153
        token = reddit.auth.authorize(code)
154
155
        UserService.objects.filter(user=request.user,
156
                                   name='ServiceReddit'
157
                                   ).update(token=token)
158
159
        return 'reddit/callback.html'
160