import argparse import json import os import random import sys from pathlib import Path from shutil import rmtree from subprocess import Popen, PIPE from tempfile import mkdtemp from urllib.parse import urlencode from OpenSSL import SSL from twisted.internet import defer, reactor, ssl from twisted.internet.task import deferLater from twisted.names import dns, error from twisted.names.server import DNSServerFactory from twisted.web.resource import EncodingResourceWrapper, Resource from twisted.web.server import GzipEncoderFactory, NOT_DONE_YET, Site from twisted.web.static import File from twisted.web.test.test_webclient import PayloadResource from twisted.web.util import redirectTo from scrapy.utils.python import to_bytes, to_unicode from scrapy.utils.ssl import SSL_OP_NO_TLSv1_3 from scrapy.utils.test import get_testenv def getarg(request, name, default=None, type=None): if name in request.args: value = request.args[name][0] if type is not None: value = type(value) return value else: return default class LeafResource(Resource): isLeaf = True def deferRequest(self, request, delay, f, *a, **kw): def _cancelrequest(_): # silence CancelledError d.addErrback(lambda _: None) d.cancel() d = deferLater(reactor, delay, f, *a, **kw) request.notifyFinish().addErrback(_cancelrequest) return d class Follow(LeafResource): def render(self, request): total = getarg(request, b"total", 100, type=int) show = getarg(request, b"show", 1, type=int) order = getarg(request, b"order", b"desc") maxlatency = getarg(request, b"maxlatency", 0, type=float) n = getarg(request, b"n", total, type=int) if order == b"rand": nlist = [random.randint(1, total) for _ in range(show)] else: # order == "desc" nlist = range(n, max(n - show, 0), -1) lag = random.random() * maxlatency self.deferRequest(request, lag, self.renderRequest, request, nlist) return NOT_DONE_YET def renderRequest(self, request, nlist): s = """
""" args = request.args.copy() for nl in nlist: args[b"n"] = [to_bytes(str(nl))] argstr = urlencode(args, doseq=True) s += f"follow {nl}