# coding=utf-8 import json import logging import requests from urlparse import urljoin, parse_qsl from library.yinkayo.api.door import Door from library.yinkayo.api.login import Login from library.yinkayo.constants import RetCode, CommonErrorCode from library.yinkayo.exceptions import FCardWebTimeOutError, FCardWebNetWorkError, FCardWebAuthError from library.yinkayo.constants import DoorOnlineStatus from django.core.cache import cache logger = logging.getLogger(__name__) class FCardWeb(object): urlBase = "https://yun.pc15.net/" urlTestBase = "https://yun.pc15.net/demo_ASPX/" def __init__(self, customer, operator, password, debug=False): self._customer = customer self._operator = operator self._password = password self._debug = debug self._cookie = cache.get(str(self)) self.Login = Login(self) self.Door = Door(self) self._isRetry = False def __str__(self): return "{}-{}-{}".format(self._customer, self._operator, self._password) def _handle_response(self, response): # type:(requests.Response) -> requests.Response try: response.raise_for_status() except requests.RequestException as ree: logger.error("[FCardWeb _handle_response] status_code = {}, error = {}, response = {}".format(response.status_code, ree, response)) raise FCardWebNetWorkError(ree.message) result = response.json() logger.info("[FCardWeb _handle_result] request success, result = {}".format(result)) # 部分分页接口没有retCode if "RetCode" in result: retCode, errorCode = result["RetCode"], result["ErrCode"] else: retCode, errorCode = RetCode.SUCCESS, CommonErrorCode.SUCCESS if retCode != RetCode.SUCCESS: logger.error("[FCardWeb _handle_result] request error, result = {}".format(result)) if errorCode == CommonErrorCode.COOKIE_EXP: if not self._isRetry: cookies = self.get_cookie() body = response.request.body try: data = dict(parse_qsl(body)) except Exception as e: logger.warning("[FCardWeb _handle_result] parse_qsl error, error = {}".format(e)) data = {} return self._post(apiPath=response.request.path_url, cookies=cookies, **data) else: raise FCardWebAuthError(u"登录过期") else: raise FCardWebNetWorkError(u"请求失败") else: return response def _post(self, apiPath, **kwargs): logger.info("[FCardWeb _post] ready to send post request to server, path = {}, data = {}".format(apiPath, kwargs)) if not self._debug: url = urljoin(self.urlBase, apiPath) else: url = urljoin(self.urlTestBase, apiPath) cookies = kwargs.pop("cookies", self._cookie) try: response = requests.post(url, data=kwargs, cookies=cookies) except requests.exceptions.Timeout: raise FCardWebTimeOutError(u"请求超时") return self._handle_response(response) def post(self, apiPath, **kwargs): return self._post(apiPath, **kwargs) def load_login_info(self): return self._customer, self._operator, self._password def get_cookie(self): cookies = self.Login.login() cache.set(str(self), cookies, timeout=60*60*23) self._cookie = cookies return cookies