Completed
Push — master ( 4378c2...80cf9a )
by Fox
56s
created

ServiceReddit.callback()   B

Complexity

Conditions 1

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 25
rs 8.8571
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
            us = UserService.objects.get(token=token)
51
            self.reddit = RedditApi(client_id=self.consumer_key,
52
                                    client_secret=self.consumer_secret,
53
                                    username=us.username,
54
                                    password=us.password,
55
                                    user_agent=self.user_agent)
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
        trigger_id = kwargs.get('trigger_id')
71
        trigger = Reddit.objects.get(trigger_id=trigger_id)
72
        date_triggered = kwargs.get('date_triggered')
73
        data = list()
74
        submissions = self.reddit.subreddit(trigger.subreddit).top('all')
75
        for submission in submissions:
76
            title = 'From Reddit ' + submission.title
77
            created = arrow.get(submission.created)
78
            if created > date_triggered and submission.selftext is not None \
79
                    and trigger.share_link:
80
                body = submission.selftext if submission.selftext \
81
                    else submission.url
82
                data.append({'title': title, 'content': body})
83
                self.send_digest_event(trigger_id, title, '')
84
85
        cache.set('th_reddit_' + str(trigger_id), data)
86
        return data
87
88
    def save_data(self, trigger_id, **data):
89
        """
90
            let's save the data
91
            :param trigger_id: trigger ID from which to save data
92
            :param data: the data to check to be used and save
93
            :type trigger_id: int
94
            :type data:  dict
95
            :return: the status of the save statement
96
            :rtype: boolean
97
        """
98
        # convert the format to be released in Markdown
99
        data['output_format'] = 'md'
100
        title, content = super(ServiceReddit, self).save_data(trigger_id,
101
                                                              **data)
102
        if self.token:
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'], 'redirect_uri')
132
        return auth_url
133
134
    def callback(self, request, **kwargs):
135
        """
136
            Called from the Service when the user accept to activate it
137
            the url to go back after the external service call
138
            :param request: contains the current session
139
            :param kwargs: keyword args
140
            :type request: dict
141
            :type kwargs: dict
142
            :rtype: string
143
        """
144
        code = request.GET.get('code', '')
145
        redirect_uri = '%s://%s%s' % (request.scheme, request.get_host(),
146
                                      reverse("reddit_callback"))
147
        reddit = RedditApi(client_id=self.consumer_key,
148
                           client_secret=self.consumer_secret,
149
                           redirect_uri=redirect_uri,
150
                           user_agent=self.user_agent)
151
152
        token = reddit.auth.authorize(code)
153
154
        UserService.objects.filter(user=request.user,
155
                                   name='ServiceReddit'
156
                                   ).update(token=token)
157
158
        return 'reddit/callback.html'
159