Completed
Branch master (5db784)
by Fox
01:52 queued 20s
created

ServiceGithub.process_data()   A

Complexity

Conditions 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
c 1
b 1
f 0
dl 0
loc 9
rs 9.6666
1
# coding: utf-8
2
# github
3
from github3 import GitHub
4
5
# django classes
6
from django.conf import settings
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.models import UserService, ServicesActivated
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):
43
        super(ServiceGithub, self).__init__(token)
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
        if self.token:
54
            token_key, token_secret = self.token.split('#TH#')
55
            self.gh = GitHub(token=token_key)
56
        else:
57
            self.gh = GitHub(username=self.username, password=self.password)
58
59
    def read_data(self, **kwargs):
60
        """
61
            get the data from the service
62
            :param kwargs: contain keyword args : trigger_id at least
63
            :type kwargs: dict
64
            :rtype: list
65
        """
66
        trigger_id = kwargs['trigger_id']
67
        data = list()
68
        cache.set('th_github_' + str(trigger_id), data)
69
70
    def save_data(self, trigger_id, **data):
71
        """
72
            let's save the data
73
            :param trigger_id: trigger ID from which to save data
74
            :param data: the data to check to be used and save
75
            :type trigger_id: int
76
            :type data:  dict
77
            :return: the status of the save statement
78
            :rtype: boolean
79
        """
80
        from th_github.models import Github
81
        if self.token:
82
            title = self.set_title(data)
83
            body = self.set_content(data)
84
            # get the details of this trigger
85
            trigger = Github.objects.get(trigger_id=trigger_id)
86
87
            # check if it remains more than 1 access
88
            # then we can create an issue
89
            limit = self.gh.ratelimit_remaining
90
            if limit > 1:
91
                # repo goes to "owner"
92
                # project goes to "repository"
93
                r = self.gh.create_issue(trigger.repo,
94
                                         trigger.project,
95
                                         title,
96
                                         body)
97
            else:
98
                # rate limit reach
99
                logger.warn("Rate limit reached")
100
                # put again in cache the data that could not be
101
                # published in Github yet
102
                cache.set('th_github_' + str(trigger_id), data, version=2)
103
                return True
104
            sentence = str('github {} created').format(r)
105
            logger.debug(sentence)
106
            status = True
107
        else:
108
            sentence = "no token or link provided for trigger ID {} "
109
            logger.critical(sentence.format(trigger_id))
110
            status = False
111
112
        return status
113
114
    def auth(self, request):
115
        """
116
            let's auth the user to the Service
117
            :param request: request object
118
            :return: callback url
119
            :rtype: string that contains the url to redirect after auth
120
        """
121
        callback_url = 'http://%s%s' % (
122
            request.get_host(), reverse('github_callback'))
123
        auth = self.gh.authorize(self.username,
124
                                 self.password,
125
                                 self.scope,
126
                                 '',
127
                                 '',
128
                                 self.consumer_key,
129
                                 self.consumer_secret)
130
        request.session['oauth_token'] = auth.token
131
        request.session['oauth_id'] = auth.id
132
        return callback_url
133
134
    def callback(self, request, **kwargs):
135
        """
136
            Called from the Service when the user accept to activate it
137
            :param request: request object
138
            :return: callback url
139
            :rtype: string , path to the template
140
        """
141
        try:
142
            # finally we save the user auth token
143
            # As we already stored the object ServicesActivated
144
            # from the UserServiceCreateView now we update the same
145
            # object to the database so :
146
            # 1) we get the previous objet
147
            us = UserService.objects.get(
148
                user=request.user,
149
                name=ServicesActivated.objects.get(name='ServiceGithub'))
150
            # 2) Readability API require to use 4 params consumer_key/secret +
151
            # token_key/secret instead of usually get just the token
152
            # from an access_token request. So we need to add a string
153
            # separator for later use to split on this one
154
            access_token = request.session['oauth_token'] + "#TH#"
155
            access_token += str(request.session['oauth_id'])
156
            us.token = access_token
157
            # 3) and save everything
158
            us.save()
159
        except KeyError:
160
            return '/'
161
162
        return 'github/callback.html'
163