school_api.client.base.BaseUserClient.post()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 3
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
from __future__ import absolute_import, unicode_literals
3
4
import inspect
5
6
import requests
7
8
from school_api.client.api.base import BaseSchoolApi
9
from school_api.client.api.utils import get_view_state_from_html
10
from school_api.client.login_management import LoginManagement
11
from school_api.utils import to_text, ObjectDict
12
13
14
def _is_api_endpoint(obj):
15
    return isinstance(obj, BaseSchoolApi)
16
17
18
class BaseUserClient(LoginManagement):
19
    """docstring for BaseUserClient"""
20
21
    _proxy = None
22
    url_token = ''
23
24
    def __new__(cls, *args):
25
        self = super(BaseUserClient, cls).__new__(cls)
26
        api_endpoints = inspect.getmembers(self, _is_api_endpoint)
27
        for name, api in api_endpoints:
28
            api_cls = type(api)
29
            api = api_cls(self)
30
            setattr(self, name, api)
31
        return self
32
33
    def __init__(self, school_obj, account, password, user_type):
34
        self._http = requests.Session()
35
        self.school = school_obj.school
36
        self.base_url = school_obj.base_url
37
        self.session = school_obj.session
38
        self.user = ObjectDict({
39
            'account': to_text(account),
40
            'password': password,
41
            'user_type': user_type,
42
            'proxy_state': False
43
        })
44
        self._http.headers.update({
45
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) '
46
                          'AppleWebKit/537.36 (KHTML, like Gecko) '
47
                          'Chrome/62.0.3202.89 Safari/537.36',
48
            'Content-Type': 'application/x-www-form-urlencoded',
49
            'Referer': self.base_url + self.school.login_url
50
        })
51
        if self.school.priority_proxy:
52
            self.switch_proxy(True)
53
54
    def _request(self, url_suffix, **kwargs):
55
56
        url = '{base}{url_token}{url_suffix}'.format(
57
            base=self.base_url,
58
            url_suffix=url_suffix,
59
            url_token=self.url_token
60
        )
61
        kwargs['timeout'] = kwargs.get('timeout', self.school.timeout)
62
        res = self._http.request(
63
            url=url,
64
            proxies=self._proxy,
65
            allow_redirects=False,
66
            **kwargs
67
        )
68
        res.raise_for_status()
69
70
        if res.status_code == 302:
71
            raise requests.TooManyRedirects(response=res)
72
73
        return res
74
75
    def get(self, url, **kwargs):
76
        return self._request(url, method='GET', **kwargs)
77
78
    def post(self, url, **kwargs):
79
        return self._request(url, method='POST', **kwargs)
80
81
    def head(self, url, **kwargs):
82
        return self._request(url, method='HEAD', **kwargs)
83
84
    def switch_proxy(self, init=False):
85
        """ 设置代理 """
86
        self.user.proxy_state = True
87
        self.base_url = self.school.lan_url or self.base_url
88
        self._proxy = self.school.proxies
89
        self._http.headers.update({
90
            'Referer': self.base_url + self.school.login_url
91
        })
92
        if not init:
93
            # 非初始化,检查是否存在有效会话登录会话
94
            return self.session_management()
95
96
    def get_view_state(self, url_suffix, **kwargs):
97
        """ 获取页面 view_state 值"""
98
        res = self.get(url_suffix, **kwargs)
99
        return get_view_state_from_html(res.text)
100
101
    def update_url_token(self, url_token):
102
        # 兼容含token的教务系统请求地址 http://xxx.xxx/(35yxiq45pv0ojz45wcopgz45)/Default2.aspx
103
        self.url_token = url_token
104