Passed
Push — master ( 99dfe8...9dca66 )
by dai
05:48
created

BaseUserClient.switch_proxy()   A

Complexity

Conditions 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nop 1
dl 0
loc 13
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
import requests
6
7
from school_api.client.utils import get_time_list
8
from school_api.client.api.base import BaseSchoolApi
9
10
from school_api.client.api.utils import get_view_state_from_html
11
from school_api.client.login_management import LoginManagement
12
from school_api.session.memorystorage import MemoryStorage
13
from school_api.utils import to_text, ObjectDict
14
from school_api.config import URL_ENDPOINT, CLASS_TIME
15
16
17
def _is_api_endpoint(obj):
18
    return isinstance(obj, BaseSchoolApi)
19
20
21
class BaseSchoolClient(object):
22
23
    def __init__(self, url, **kwargs):
24
        url = url.split('/default')[0] if url[-4:] == 'aspx' else url
25
        class_time_list = kwargs.get('class_time_list') or CLASS_TIME
26
        time_list = get_time_list(class_time_list)
27
28
        self.school = {
29
            'url': url,
30
            'debug': kwargs.get('debug'),
31
            'name': to_text(kwargs.get('name')),
32
            'code': kwargs.get('code'),
33
            'use_ex_handle': kwargs.get('use_ex_handle', True),
34
            'exist_verify': kwargs.get('exist_verify', True),
35
            'lan_url': kwargs.get('lan_url'),
36
            'proxies': kwargs.get('proxies'),
37
            'priority_proxy': kwargs.get('priority_proxy'),
38
            'timeout': kwargs.get('timeout', 10),
39
            'login_url': kwargs.get('login_url_path', '/default2.aspx'),
40
            'url_endpoint': kwargs.get('url_endpoint') or URL_ENDPOINT,
41
            'time_list': time_list
42
        }
43
        storage = kwargs.get('session', MemoryStorage)
44
        self.session = storage(self.school['code'])
45
        self.school = ObjectDict(self.school)
46
47
48
class BaseUserClient(LoginManagement):
49
    """docstring for BaseUserClient"""
50
51
    _proxy = None
52
53
    def __new__(cls, *args):
54
        self = super(BaseUserClient, cls).__new__(cls)
55
        api_endpoints = inspect.getmembers(self, _is_api_endpoint)
56
        for name, api in api_endpoints:
57
            api_cls = type(api)
58
            api = api_cls(self)
59
            setattr(self, name, api)
60
        return self
61
62
    def __init__(self, school, account, password, user_type):
63
        self._http = requests.Session()
64
65
        self.account = to_text(account)
66
        self.password = password
67
        self.user_type = user_type
68
        self.school = school.school
69
        self.base_url = self.school.url
70
        self.session = school.session
71
72
        self._http.headers.update({
73
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) '
74
                          'AppleWebKit/537.36 (KHTML, like Gecko) '
75
                          'Chrome/62.0.3202.89 Safari/537.36',
76
            'Content-Type': 'application/x-www-form-urlencoded',
77
            'Referer': self.base_url + self.school.login_url
78
        })
79
        if self.school.priority_proxy:
80
            self.switch_proxy()
81
82
    def _request(self, method, url_or_endpoint, **kwargs):
83
        if not url_or_endpoint.startswith(('http://', 'https://')):
84
            url = '{base}{endpoint}'.format(
85
                base=self.base_url,
86
                endpoint=url_or_endpoint
87
            )
88
        else:
89
            url = url_or_endpoint
90
91
        kwargs['timeout'] = kwargs.get('timeout', self.school.timeout)
92
        res = self._http.request(
93
            method=method,
94
            url=url,
95
            proxies=self._proxy,
96
            **kwargs
97
        )
98
        return res
99
100
    def get(self, url, **kwargs):
101
        return self._request(
102
            method='GET',
103
            url_or_endpoint=url,
104
            **kwargs
105
        )
106
107
    def post(self, url, **kwargs):
108
        return self._request(
109
            method='POST',
110
            url_or_endpoint=url,
111
            **kwargs
112
        )
113
114
    def head(self, url, **kwargs):
115
        return self._request(
116
            method='HEAD',
117
            url_or_endpoint=url,
118
            **kwargs
119
        )
120
121
    def switch_proxy(self):
122
        """ 设置代理 """
123
        self.base_url = self.school.lan_url or self.base_url
124
        self._proxy = self.school.proxies
125
        self._http.headers.update({
126
            'Referer': self.base_url + self.school.login_url
127
        })
128
129
        if not self.school.priority_proxy:
130
            # 检查是否有登录会话
131
            return self._get_login_session()
132
133
        self.school.priority_proxy = True
134
135
    def get_view_state(self, url_suffix, **kwargs):
136
        """ 获取页面 view_state 值"""
137
        res = self.get(url_suffix, allow_redirects=False, **kwargs)
138
        res.raise_for_status()
139
        if res.status_code == 302:
140
            raise requests.TooManyRedirects
141
142
        return get_view_state_from_html(res.text)
143