ServiceGithub.gh_footer()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
dl 0
loc 11
rs 9.4285
1
# coding: utf-8
2
# github
3
from github3 import GitHub
4
5
# django classes
6
from django.conf import settings
7
from logging import getLogger
8
from django.core.cache import caches
9
from django.utils.translation import ugettext as _
10
11
# django_th classes
12
from django_th.services.services import ServicesMgr
13
from django_th.models import update_result
14
from th_github.models import Github
15
16
"""
17
    handle process with github
18
    put the following in settings.py
19
20
    TH_GITHUB = {
21
        'username': 'username',
22
        'password': 'password',
23
        'consumer_key': 'my key',
24
        'consumer_secret': 'my secret'
25
    }
26
27
28
    TH_SERVICES = (
29
        ...
30
        'th_github.my_github.ServiceGithub',
31
        ...
32
    )
33
34
"""
35
36
logger = getLogger('django_th.trigger_happy')
37
38
cache = caches['django_th']
39
40
41
class ServiceGithub(ServicesMgr):
42
    """
43
        Service Github
44
    """
45
    def __init__(self, token=None, **kwargs):
46
        super(ServiceGithub, self).__init__(token, **kwargs)
47
        self.scope = ['public_repo']
48
        self.REQ_TOKEN = 'https://github.com/login/oauth/authorize'
49
        self.AUTH_URL = 'https://github.com/login/oauth/authorize'
50
        self.ACC_TOKEN = 'https://github.com/login/oauth/access_token'
51
        self.username = settings.TH_GITHUB_KEY['username']
52
        self.password = settings.TH_GITHUB_KEY['password']
53
        self.consumer_key = settings.TH_GITHUB_KEY['consumer_key']
54
        self.consumer_secret = settings.TH_GITHUB_KEY['consumer_secret']
55
        self.token = token
56
        self.oauth = 'oauth1'
57
        self.service = 'ServiceGithub'
58
        if self.token:
59
            token_key, token_secret = self.token.split('#TH#')
60
            self.gh = GitHub(token=token_key)
61
        else:
62
            self.gh = GitHub(username=self.username, password=self.password)
63
64
    def gh_footer(self, trigger, issue):
65
66
        link = 'https://github.com/{0}/{1}/issues/{2}'.format(
67
            trigger.repo, trigger.project, issue.id)
68
69
        provided_by = _('Provided by')
70
        provided_from = _('from')
71
        footer_from = "<br/><br/>{} <em>{}</em> {} <a href='{}'>{}</a>"
72
73
        return footer_from.format(provided_by, trigger.trigger.description,
74
                                  provided_from, link, link)
75
76
    def read_data(self, **kwargs):
77
        """
78
            get the data from the service
79
            :param kwargs: contain keyword args : trigger_id at least
80
            :type kwargs: dict
81
            :rtype: list
82
        """
83
        trigger_id = kwargs.get('trigger_id')
84
        date_triggered = str(kwargs.get('date_triggered')).replace(' ', 'T')
85
        data = list()
86
        if self.token:
87
            # check if it remains more than 1 access
88
            # then we can create an issue
89
            if self.gh.ratelimit_remaining > 1:
90
91
                import pypandoc
92
93
                trigger = Github.objects.get(trigger_id=trigger_id)
94
                issues = self.gh.issues_on(trigger.repo,
95
                                           trigger.project,
96
                                           since=date_triggered)
97
98
                for issue in issues:
99
100
                    content = pypandoc.convert(issue.body, 'md', format='html')
101
                    content += self.gh_footer(trigger, issue)
102
103
                    data.append({'title': issue.title, 'content': content})
104
                    # digester
105
                    self.send_digest_event(trigger_id,
106
                                           issue.title,
107
                                           '')
108
                cache.set('th_github_' + str(trigger_id), data)
109
            else:
110
                # rate limit reach, do nothing right now
111
                logger.warn("Rate limit reached")
112
                update_result(trigger_id, msg="Rate limit reached",
113
                              status=True)
114
        else:
115
            logger.critical("no token provided")
116
            update_result(trigger_id, msg="No token provided", status=True)
117
        return data
118
119
    def save_data(self, trigger_id, **data):
120
        """
121
            let's save the data
122
            :param trigger_id: trigger ID from which to save data
123
            :param data: the data to check to be used and save
124
            :type trigger_id: int
125
            :type data:  dict
126
            :return: the status of the save statement
127
            :rtype: boolean
128
        """
129
        if self.token:
130
            title = self.set_title(data)
131
            body = self.set_content(data)
132
            # get the details of this trigger
133
            trigger = Github.objects.get(trigger_id=trigger_id)
134
135
            # check if it remains more than 1 access
136
            # then we can create an issue
137
            limit = self.gh.ratelimit_remaining
138
            if limit > 1:
139
                # repo goes to "owner"
140
                # project goes to "repository"
141
                r = self.gh.create_issue(trigger.repo,
142
                                         trigger.project,
143
                                         title,
144
                                         body)
145
            else:
146
                # rate limit reach
147
                logger.warn("Rate limit reached")
148
                update_result(trigger_id, msg="Rate limit reached",
149
                              status=True)
150
                # put again in cache the data that could not be
151
                # published in Github yet
152
                cache.set('th_github_' + str(trigger_id), data, version=2)
153
                return True
154
            sentence = str('github {} created').format(r)
155
            logger.debug(sentence)
156
            status = True
157
        else:
158
            sentence = "no token or link provided for " \
159
                       "trigger ID {} ".format(trigger_id)
160
            logger.critical(sentence)
161
            update_result(trigger_id, msg=sentence, status=False)
162
            status = False
163
164
        return status
165
166
    def auth(self, request):
167
        """
168
            let's auth the user to the Service
169
            :param request: request object
170
            :return: callback url
171
            :rtype: string that contains the url to redirect after auth
172
        """
173
        auth = self.gh.authorize(self.username,
174
                                 self.password,
175
                                 self.scope,
176
                                 '',
177
                                 '',
178
                                 self.consumer_key,
179
                                 self.consumer_secret)
180
        request.session['oauth_token'] = auth.token
181
        request.session['oauth_id'] = auth.id
182
        return self.callback_url(request)
183
184
    def callback(self, request, **kwargs):
185
        """
186
            Called from the Service when the user accept to activate it
187
            :param request: request object
188
            :return: callback url
189
            :rtype: string , path to the template
190
        """
191
        access_token = request.session['oauth_token'] + "#TH#"
192
        access_token += str(request.session['oauth_id'])
193
        kwargs = {'access_token': access_token}
194
        return super(ServiceGithub, self).callback(request, **kwargs)
195