From fac149132234d7bdd14de13e4ac7677042f357d5 Mon Sep 17 00:00:00 2001 From: Ethan Dalool Date: Mon, 7 Nov 2016 20:48:43 -0800 Subject: [PATCH] else --- Downloady/downloady.py | 4 +- Instathief/instathief.py | 4 +- OpenDirDL/opendirdl.py | 6 ++- OpenDirDL/requirements.txt | 3 ++ Pathclass/pathclass.py | 12 +++-- ServerReference/simpleserver.py | 6 +-- SpinalTap/spinal.py | 8 ++-- ThreadedDL/threaded_dl.py | 4 +- WebstreamZip/test.zip | Bin 0 -> 10240 bytes WebstreamZip/tester.py | 7 +++ WebstreamZip/webstreamzip.py | 81 ++++++++++++++++++++++++++++++++ _voussoirkit/voussoirkit.zip | Bin 15815 -> 15992 bytes 12 files changed, 117 insertions(+), 18 deletions(-) create mode 100644 OpenDirDL/requirements.txt create mode 100644 WebstreamZip/test.zip create mode 100644 WebstreamZip/tester.py create mode 100644 WebstreamZip/webstreamzip.py diff --git a/Downloady/downloady.py b/Downloady/downloady.py index f3d526f..5b729b3 100644 --- a/Downloady/downloady.py +++ b/Downloady/downloady.py @@ -9,8 +9,8 @@ import warnings try: sys.path.append('C:\\git\\else\\Bytestring') - sys.path.append('C:\\git\\else\\clipext'); - sys.path.append('C:\\git\\else\\ratelimiter'); + sys.path.append('C:\\git\\else\\clipext') + sys.path.append('C:\\git\\else\\ratelimiter') import bytestring import ratelimiter import clipext diff --git a/Instathief/instathief.py b/Instathief/instathief.py index 39cdeca..1d4f1d7 100644 --- a/Instathief/instathief.py +++ b/Instathief/instathief.py @@ -7,8 +7,8 @@ import requests import sys try: - sys.path.append('C:\\git\\else\\Clipext'); - sys.path.append('C:\\git\\else\\Downloady'); + sys.path.append('C:\\git\\else\\Clipext') + sys.path.append('C:\\git\\else\\Downloady') import clipext import downloady except ImportError: diff --git a/OpenDirDL/opendirdl.py b/OpenDirDL/opendirdl.py index 078e7be..a5e974e 100644 --- a/OpenDirDL/opendirdl.py +++ b/OpenDirDL/opendirdl.py @@ -113,6 +113,7 @@ tree: import argparse ## import bs4 import collections +import concurrent.futures ## import hashlib import os ## import re @@ -124,8 +125,8 @@ import sys import urllib.parse try: - sys.path.append('C:\\git\\else\\Bytestring'); - sys.path.append('C:\\git\\else\\Downloady'); + sys.path.append('C:\\git\\else\\Bytestring') + sys.path.append('C:\\git\\else\\Downloady') import bytestring import downloady except ImportError: @@ -299,6 +300,7 @@ class Walker: self.fullscan = bool(fullscan) self.queue = collections.deque() self.seen_directories = set() + self.threadpool = concurrent.futures.ThreadPoolExecutor(4) def smart_insert(self, url=None, head=None, commit=True): ''' diff --git a/OpenDirDL/requirements.txt b/OpenDirDL/requirements.txt new file mode 100644 index 0000000..a751733 --- /dev/null +++ b/OpenDirDL/requirements.txt @@ -0,0 +1,3 @@ +https://github.com/voussoir/else/raw/master/_voussoirkit/voussoirkit.zip +bs4 +requests \ No newline at end of file diff --git a/Pathclass/pathclass.py b/Pathclass/pathclass.py index f285d1b..d2da2b0 100644 --- a/Pathclass/pathclass.py +++ b/Pathclass/pathclass.py @@ -10,13 +10,19 @@ class Path: self.absolute_path = path def __contains__(self, other): - return other.absolute_path.startswith(self.absolute_path) + this = os.path.normcase(self.absolute_path) + that = os.path.normcase(other.absolute_path) + return that.startswith(this) def __eq__(self, other): - return hasattr(other, 'absolute_path') and self.absolute_path == other.absolute_path + if not hasattr(other, 'absolute_path'): + return False + this = os.path.normcase(self.absolute_path) + that = os.path.normcase(other.absolute_path) + return this == that def __hash__(self): - return hash(self.absolute_path) + return hash(os.path.normcase(self.absolute_path)) def __repr__(self): return '{c}({path})'.format(c=self.__class__.__name__, path=repr(self.absolute_path)) diff --git a/ServerReference/simpleserver.py b/ServerReference/simpleserver.py index 6bb1eff..5442b1d 100644 --- a/ServerReference/simpleserver.py +++ b/ServerReference/simpleserver.py @@ -9,9 +9,9 @@ import sys import types try: - sys.path.append('C:\\git\\else\\Bytestring'); - sys.path.append('C:\\git\\else\\Pathclass'); - sys.path.append('C:\\git\\else\\Ratelimiter'); + sys.path.append('C:\\git\\else\\Bytestring') + sys.path.append('C:\\git\\else\\Pathclass') + sys.path.append('C:\\git\\else\\Ratelimiter') import bytestring import pathclass import ratelimiter diff --git a/SpinalTap/spinal.py b/SpinalTap/spinal.py index 90fc53b..8b95fad 100644 --- a/SpinalTap/spinal.py +++ b/SpinalTap/spinal.py @@ -11,9 +11,9 @@ import sys import time try: - sys.path.append('C:\\git\\else\\Bytestring'); - sys.path.append('C:\\git\\else\\Pathclass'); - sys.path.append('C:\\git\\else\\Ratelimiter'); + sys.path.append('C:\\git\\else\\Bytestring') + sys.path.append('C:\\git\\else\\Pathclass') + sys.path.append('C:\\git\\else\\Ratelimiter') import bytestring import pathclass import ratelimiter @@ -24,7 +24,7 @@ except ImportError: from voussoirkit import pathclass from voussoirkit import ratelimiter -logging.basicConfig(level=logging.DEBUG) +logging.basicConfig(level=logging.CRITICAL) log = logging.getLogger(__name__) CHUNK_SIZE = 128 * bytestring.KIBIBYTE diff --git a/ThreadedDL/threaded_dl.py b/ThreadedDL/threaded_dl.py index 8c807c4..496b0be 100644 --- a/ThreadedDL/threaded_dl.py +++ b/ThreadedDL/threaded_dl.py @@ -4,8 +4,8 @@ import threading import time try: - sys.path.append('C:\\git\\else\\Clipext'); - sys.path.append('C:\\git\\else\\Downloady'); + sys.path.append('C:\\git\\else\\Clipext') + sys.path.append('C:\\git\\else\\Downloady') import clipext import downloady except ImportError: diff --git a/WebstreamZip/test.zip b/WebstreamZip/test.zip new file mode 100644 index 0000000000000000000000000000000000000000..a2f3957e3b473c1cc8c409c83224a8787686301e GIT binary patch literal 10240 zcmeIvu};G<5C-7PmHH01vC!BlRfkB7Aa#I&7eJ;lwIPYE^QEXfJq{J6VytMV{}xBd zpS#?b&aa)ZZP_)&*-GbHE|&An*k#A8i}} literal 0 HcmV?d00001 diff --git a/WebstreamZip/tester.py b/WebstreamZip/tester.py new file mode 100644 index 0000000..f158cfb --- /dev/null +++ b/WebstreamZip/tester.py @@ -0,0 +1,7 @@ +import webstreamzip + +g = webstreamzip.stream_zip({'C:\\git\\else\\readme.md':'michael.md'}) + +x = open('test.zip', 'wb') +for chunk in g: + x.write(chunk) \ No newline at end of file diff --git a/WebstreamZip/webstreamzip.py b/WebstreamZip/webstreamzip.py new file mode 100644 index 0000000..9f92781 --- /dev/null +++ b/WebstreamZip/webstreamzip.py @@ -0,0 +1,81 @@ +import threading +import zipfile +import tarfile + + +class Stream: + def __init__(self): + self.active_chunk = None + self.write_ready = threading.Event() + self.read_ready = threading.Event() + self.write_ready.set() + self.all_done = False + + def write(self, chunk): + if chunk == b'': + self.all_done = True + + if self.all_done: + return 0 + + self.write_ready.wait() + #print('writing', chunk) + self.active_chunk = chunk + self.write_ready.clear() + self.read_ready.set() + return 0 + + def tell(self): + return 0 + + def read(self, size=None): + if self.all_done: + return b'' + + self.read_ready.wait() + chunk = self.active_chunk + self.active_chunk = None + self.read_ready.clear() + self.write_ready.set() + return chunk + + def close(self): + #print('Internal close') + self.all_done = True + while not self.write_ready.is_set(): + #print('writeset') + self.write_ready.set() + while not self.read_ready.is_set(): + #print('readset') + self.read_ready.set() + + def flush(self): + #print('flushy') + pass + +def _stream_tar(memstream, filenames): + z = tarfile.TarFile(fileobj=memstream, mode='w') + if isinstance(filenames, dict): + for (realpath, fakepath) in filenames.items(): + z.add(realpath, arcname=fakepath) + else: + for filename in filenames: + z.add(filename) + #print('zclosing') + z.close() + memstream.close() + #print('zclosed') + return + +def stream_tar(filenames): + memstream = Stream() + zip_thread = threading.Thread(target=_stream_tar, args=(memstream, filenames)) + zip_thread.start() + while True: + #print('reading') + chunk = memstream.read() + yield chunk + if not chunk: + break + memstream.close() + #print('ending') diff --git a/_voussoirkit/voussoirkit.zip b/_voussoirkit/voussoirkit.zip index c1c68346f0d3800d2cfbf882e37c2e0ceafc84d9..78d4fe9eab0f2ca4d5d7aa78a64876566dc7e71c 100644 GIT binary patch delta 10340 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 M->OO)_rGTU1v^{j9smFU delta 10230 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