[pixiv] cache login sessions

This commit is contained in:
Mike Fährmann
2016-03-06 21:00:42 +01:00
parent 738c65d54f
commit c8e83f6560
2 changed files with 34 additions and 46 deletions

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2014, 2015 Mike Fährmann
# Copyright 2014-2016 Mike Fährmann
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -10,6 +10,7 @@
from .common import Extractor, Message
from .. import config, text
from ..cache import cache
import re
import json
import time
@@ -192,10 +193,7 @@ class PixivBookmarkExtractor(PixivFavoriteExtractor):
def require_login(func):
"""Decorator: auto-login before api-calls"""
def wrap(self, *args):
now = time.time()
if now - self.last_login > PixivAPI.token_timeout:
self.login()
self.last_login = now
self.login()
return func(self, *args)
return wrap
@@ -207,52 +205,19 @@ class PixivAPI():
For in-depth information regarding the Pixiv Public-API, see
- http://blog.imaou.com/opensource/2014/10/09/pixiv_api_for_ios_update.html
"""
token_timeout = 50*60 # 50 minutes
def __init__(self, session):
self.last_login = 0
self.session = session
self.session.headers.update({
"Referer": "http://www.pixiv.net/",
"User-Agent": "PixivIOSApp/5.8.0",
})
config.setdefault(("extractor", "pixiv"), {})
self.username = config.interpolate(("extractor", "pixiv", "username"))
self.password = config.interpolate(("extractor", "pixiv", "password"))
def login(self):
"""Login and gain a Pixiv Public-API access token"""
pconf = config.get(("extractor", "pixiv"))
token = pconf.get("access-token")
now = time.time()
if token:
timestamp = pconf.get("access-token-timestamp", 0)
if now - timestamp > PixivAPI.token_timeout:
token = None
if not token:
data = {
"username": pconf.get("username"),
"password": pconf.get("password"),
"grant_type": "password",
"client_id": "bYGKuGVw91e0NMfPGp44euvGt59s",
"client_secret": "HP3RmkgAmEGro0gn1x9ioawQE8WMfvLXDz3ZqxpK",
}
response = self.session.post(
"https://oauth.secure.pixiv.net/auth/token", data=data
)
if response.status_code not in (200, 301, 302):
raise Exception("login() failed! check username and password.\n"
"HTTP %s: %s" % (response.status_code, response.text))
try:
response = self._parse(response)["response"]
token = response["access_token"]
self.token_timeout = response["expires_in"]
self.user_id = response["user"]["id"]
except:
raise Exception("Get access_token error! Response: %s" % (token))
pconf["access-token"] = token
pconf["access-token-timestamp"] = now - 1
self.session.headers["Authorization"] = (
"Bearer " + token
)
self.user_id, token = self._do_login(self.username, self.password)
self.session.headers["Authorization"] = "Bearer " + token
@require_login
def user(self, user_id):
@@ -304,6 +269,29 @@ class PixivAPI():
)
return self._parse(response)
@cache(maxage=50*60, keyarg=1)
def _do_login(self, username, password):
data = {
"username": username,
"password": password,
"grant_type": "password",
"client_id": "bYGKuGVw91e0NMfPGp44euvGt59s",
"client_secret": "HP3RmkgAmEGro0gn1x9ioawQE8WMfvLXDz3ZqxpK",
}
response = self.session.post(
"https://oauth.secure.pixiv.net/auth/token", data=data
)
if response.status_code not in (200, 301, 302):
raise Exception("login() failed! check username and password.\n"
"HTTP %s: %s" % (response.status_code, response.text))
try:
response = self._parse(response)["response"]
token = response["access_token"]
user = response["user"]["id"]
except:
raise Exception("Get access_token error! Response: %s" % (token))
return user, token
@staticmethod
def _parse(response):
"""Parse a Pixiv Public-API response"""