Completed
Push — master ( 2f8f24...c1b989 )
by Tomaz
28s
created

BaseGithubAction._web_session()   A

Complexity

Conditions 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
1
from github import Github
2
import requests
3
from bs4 import BeautifulSoup
4
import json
5
6
from st2actions.runners.pythonrunner import Action
7
8
__all__ = [
9
    'BaseGithubAction'
10
]
11
12
# Default Github web URL (used by tasks which directly scrape data from HTML)
13
# pages
14
DEFAULT_WEB_URL = 'https://github.com'
15
16
# Default Github API url
17
DEFAULT_API_URL = 'https://api.github.com'
18
19
20
class BaseGithubAction(Action):
21
    def __init__(self, config):
22
        super(BaseGithubAction, self).__init__(config=config)
23
        token = self.config.get('token', None)
24
        self.token = token or None
25
        self.github_url = self.config.get('github_url', DEFAULT_API_URL)
26
        self.enterprise_url = self.config.get('enterprise_url', None)
27
        self.default_github_type = self.config.get('github_type', None)
28
29
        self._client = Github(self.token, base_url=self.github_url)
30
        self._session = requests.Session()
31
32
    def _web_session(self):
33
        '''Returns a requests session to scrape off the web'''
34
        login_url = DEFAULT_WEB_URL + '/login'
35
        session = requests.Session()
36
        request = session.get(login_url).text
37
        html = BeautifulSoup(request)
38
        token = html.find('input', {'name': 'authenticity_token'}).attrs['value']
39
        commit_value = html.find('input', {'name': 'commit'}).attrs['value']
40
        session_path = html.find('form', {'method': 'post'}).attrs['action']
41
42
        login_data = {
43
            'login': self.config['user'],
44
            'password': self.config['password'],
45
            'commit': commit_value,
46
            'authenticity_token': token
47
        }
48
49
        session_url = DEFAULT_WEB_URL + session_path
50
        session.post(session_url, data=login_data)
51
        return session
52
53
    def _get_analytics(self, category, repo):
54
        url = DEFAULT_WEB_URL + repo + '/graphs/' + category + '.json'
55
        s = self._web_session()
56
        response = s.get(url)
57
        return response.json()
58
59
    def _is_enterprise(self, github_type):
60
61
        if github_type == "enterprise":
62
            return True
63
        elif github_type == "online":
64
            return False
65
        elif self.default_github_type == "enterprise":
66
            return True
67
        elif self.default_github_type == "online":
68
            return False
69
        else:
70
            raise ValueError("Default GitHub Invalid!")
71
72
    def _get_user_token(self, user, enterprise):
73
        if enterprise:
74
            token_name = "token_enterprise_{}".format(user)
75
        else:
76
            token_name = "token_{}".format(user)
77
78
        return self.action_service.get_value(token_name)
79
80
    def _change_to_user_token(self, user, enterprise=False):
81
        token = self._get_user_token(user, enterprise)
82
83
        if enterprise:
84
            self._client = Github(token, base_url=self.enterprise_url)
85
        else:
86
            self._client = Github(token, base_url=self.github_url)
87
88
        return True
89
90
    def _request(self, method, uri, payload, token, enterprise):
91
        headers = {'Authorization': 'token {}'.format(token)}
92
93
        if enterprise:
94
            url = "{}{}".format(self.enterprise_url, uri)
95
        else:
96
            url = "{}{}".format(self.github_url, uri)
97
98
        try:
99
            r = self._session.request(method,
100
                                      url,
101
                                      data=json.dumps(payload),
102
                                      headers=headers,
103
                                      verify=False)
104
            r.raise_for_status()
105
        except requests.exceptions.HTTPError:
106
            raise Exception(
107
                "ERROR: '{}'ing to '{}' - status code: {} payload: {}".format(
108
                    method, url, r.status_code, json.dumps(payload)))
109
        except requests.exceptions.ConnectionError, e:
110
            raise Exception("Could not connect to: {} : {}".format(url, e))
111
        else:
112
            if r.status_code == 204:
113
                return None
114
            else:
115
                return r.json()
116