Completed
Push — master ( fa408c...7460f3 )
by Fox
01:35
created

ServiceGithub.gh_footer()   A

Complexity

Conditions 1

Size

Total Lines 11

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