move AnkiRequestsClient into its own file

It should still be accessible via anki.sync as well.
This commit is contained in:
Damien Elmes 2020-01-18 15:45:14 +10:00
parent bead03e858
commit 0d1a25eb5b
5 changed files with 83 additions and 72 deletions

79
pylib/anki/httpclient.py Normal file
View File

@ -0,0 +1,79 @@
# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
"""
Wrapper for requests that adds hooks for tracking upload/download progress.
The hooks http_data_did_send and http_data_did_receive will be called for each
chunk or partial read, on the thread that is running the request.
"""
import io
import os
from typing import Any, Dict, Optional
import requests
from requests import Response
from anki import hooks
HTTP_BUF_SIZE = 64 * 1024
class AnkiRequestsClient:
verify = True
timeout = 60
def __init__(self) -> None:
self.session = requests.Session()
def post(self, url: str, data: Any, headers: Optional[Dict[str, str]]) -> Response:
data = _MonitoringFile(data) # pytype: disable=wrong-arg-types
headers["User-Agent"] = self._agentName()
return self.session.post(
url,
data=data,
headers=headers,
stream=True,
timeout=self.timeout,
verify=self.verify,
) # pytype: disable=wrong-arg-types
def get(self, url, headers=None) -> Response:
if headers is None:
headers = {}
headers["User-Agent"] = self._agentName()
return self.session.get(
url, stream=True, headers=headers, timeout=self.timeout, verify=self.verify
)
def streamContent(self, resp) -> bytes:
resp.raise_for_status()
buf = io.BytesIO()
for chunk in resp.iter_content(chunk_size=HTTP_BUF_SIZE):
hooks.http_data_did_receive(len(chunk))
buf.write(chunk)
return buf.getvalue()
def _agentName(self) -> str:
from anki import version
return "Anki {}".format(version)
# allow user to accept invalid certs in work/school settings
if os.environ.get("ANKI_NOVERIFYSSL"):
AnkiRequestsClient.verify = False
import warnings
warnings.filterwarnings("ignore")
class _MonitoringFile(io.BufferedReader):
def read(self, size=-1) -> bytes:
data = io.BufferedReader.read(self, HTTP_BUF_SIZE)
hooks.http_data_did_send(len(data))
return data

View File

@ -11,20 +11,15 @@ import random
import sqlite3
from typing import Any, Dict, List, Optional, Tuple, Union
import requests
import anki
from anki.consts import *
from anki.db import DB, DBError
from anki.utils import checksum, devMode, ids2str, intTime, platDesc, versionWithBuild
from . import hooks
from .httpclient import AnkiRequestsClient
from .lang import ngettext
# syncing vars
HTTP_TIMEOUT = 90
HTTP_BUF_SIZE = 64 * 1024
class UnexpectedSchemaChange(Exception):
pass
@ -464,69 +459,6 @@ from notes where %s"""
self.col.conf = conf
# Wrapper for requests that tracks upload/download progress
##########################################################################
class AnkiRequestsClient:
verify = True
timeout = 60
def __init__(self) -> None:
self.session = requests.Session()
def post(self, url, data, headers) -> Any:
data = _MonitoringFile(data) # pytype: disable=wrong-arg-types
headers["User-Agent"] = self._agentName()
return self.session.post(
url,
data=data,
headers=headers,
stream=True,
timeout=self.timeout,
verify=self.verify,
) # pytype: disable=wrong-arg-types
def get(self, url, headers=None) -> requests.models.Response:
if headers is None:
headers = {}
headers["User-Agent"] = self._agentName()
return self.session.get(
url, stream=True, headers=headers, timeout=self.timeout, verify=self.verify
)
def streamContent(self, resp) -> bytes:
resp.raise_for_status()
buf = io.BytesIO()
for chunk in resp.iter_content(chunk_size=HTTP_BUF_SIZE):
hooks.http_data_did_receive(len(chunk))
buf.write(chunk)
return buf.getvalue()
def _agentName(self) -> str:
from anki import version
return "Anki {}".format(version)
# allow user to accept invalid certs in work/school settings
if os.environ.get("ANKI_NOVERIFYSSL"):
AnkiRequestsClient.verify = False
import warnings
warnings.filterwarnings("ignore")
class _MonitoringFile(io.BufferedReader):
def read(self, size=-1) -> bytes:
data = io.BufferedReader.read(self, HTTP_BUF_SIZE)
hooks.http_data_did_send(len(data))
return data
# HTTP syncing tools
##########################################################################

View File

@ -17,8 +17,8 @@ from send2trash import send2trash
import aqt
import aqt.forms
from anki.httpclient import AnkiRequestsClient
from anki.lang import _, ngettext
from anki.sync import AnkiRequestsClient
from anki.utils import intTime
from aqt.downloader import download
from aqt.qt import *

View File

@ -7,8 +7,8 @@ import time
import aqt
from anki import hooks
from anki.httpclient import AnkiRequestsClient
from anki.lang import _
from anki.sync import AnkiRequestsClient
from aqt.qt import *

View File

@ -20,9 +20,9 @@ from bs4 import BeautifulSoup
import aqt
import aqt.sound
from anki.hooks import runFilter
from anki.httpclient import AnkiRequestsClient
from anki.lang import _
from anki.notes import Note
from anki.sync import AnkiRequestsClient
from anki.utils import checksum, isWin, namedtmp, stripHTMLMedia
from aqt import AnkiQt, gui_hooks
from aqt.qt import *