From b0187f326956c18899187e2539d4c7084681c118 Mon Sep 17 00:00:00 2001 From: Ethan Dalool Date: Thu, 17 Nov 2016 22:24:52 -0800 Subject: [PATCH] else --- OpenDirDL/README.md | 14 +++++++++-- RateMeter/speedtest.py | 2 +- Toddo/toddo.py | 24 +++++++++++++------ Toolbox/bitrate_chart.py | 49 +++++++++++++++++++++++++++++++++++++++ Toolbox/clipboard.py | 12 ++++++++++ Toolbox/contentreplace.py | 35 ++++++++++++++++++++++++++++ Toolbox/ffrename.py | 43 ++++++++++++++++++++++++++++++++++ Toolbox/filepull.py | 37 +++++++++++++++++++++++++++++ Toolbox/fileswith.py | 27 +++++++++++++++++++++ Toolbox/kbps.py | 32 +++++++++++++++++++++++++ Toolbox/kbpsr.py | 35 ++++++++++++++++++++++++++++ Toolbox/randomfile.py | 46 ++++++++++++++++++++++++++++++++++++ Toolbox/rejpg.py | 44 +++++++++++++++++++++++++++++++++++ Toolbox/touch.py | 15 ++++++++++++ 14 files changed, 405 insertions(+), 10 deletions(-) create mode 100644 Toolbox/bitrate_chart.py create mode 100644 Toolbox/clipboard.py create mode 100644 Toolbox/contentreplace.py create mode 100644 Toolbox/ffrename.py create mode 100644 Toolbox/filepull.py create mode 100644 Toolbox/fileswith.py create mode 100644 Toolbox/kbps.py create mode 100644 Toolbox/kbpsr.py create mode 100644 Toolbox/randomfile.py create mode 100644 Toolbox/rejpg.py create mode 100644 Toolbox/touch.py diff --git a/OpenDirDL/README.md b/OpenDirDL/README.md index 6044c50..871d6c7 100644 --- a/OpenDirDL/README.md +++ b/OpenDirDL/README.md @@ -3,8 +3,18 @@ Open Dir DL The open directory downloader. +## Installation + + pip install requirements.txt + +## Usage + See inside opendirdl.py for usage instructions. +  + +### Changelog + - **[addition]** A new feature was added. - **[bugfix]** Incorrect behavior was fixed. - **[change]** An existing feature was slightly modified or parameters were renamed. @@ -33,7 +43,7 @@ See inside opendirdl.py for usage instructions. - 2016 08 10 - **[addition]** Added clickable links to each directory on HTML tree pages. - **[bugfix]** Fixed bug in smart_insert caused by 404's being considered falsey, triggering the 'one and only one' exception. - - **[bugfix]** Fixed bug in smart_insert where 404'd URLs were not being dele`ted from the database. + - **[bugfix]** Fixed bug in smart_insert where 404'd URLs were not being deleted from the database. - 2016 08 02 - **[cleanup]** Removed the need for div IDs on the Tree pages by making the collapse button use `this.nextSibling`. @@ -52,7 +62,7 @@ See inside opendirdl.py for usage instructions. - 2016 07 25 - **[change]** Bytespersecond is now parsed by `bytestring.parsebytes` rather than `eval`, so you can write "100k" as opposed to "100 * 1024" etc. - - **[removal]** Removed the `Downloader` class after watching [this Jack Diederich talk](https://youtu.be/o9pEzgHorH0) about unecessary classes. + - **[removal]** Removed the `Downloader` class and replaced it with a function, because it only had one real method anyway. - 2016 07 19 - **[addition]** Gave the HTML tree divs a very gentle shadow and alternating colors to help with depth perception. diff --git a/RateMeter/speedtest.py b/RateMeter/speedtest.py index 8223c76..57b0079 100644 --- a/RateMeter/speedtest.py +++ b/RateMeter/speedtest.py @@ -1,4 +1,4 @@ -import bytestring +from voussoirkit import bytestring import downloady import ratemeter import requests diff --git a/Toddo/toddo.py b/Toddo/toddo.py index 65d7e27..d42a122 100644 --- a/Toddo/toddo.py +++ b/Toddo/toddo.py @@ -233,7 +233,7 @@ def colorama_print(text): alternator = False terminal_size = shutil.get_terminal_size()[0] for line in text.split('\n'): - line += ' ' * (terminal_size - (len(line)+1)) + line = line.ljust(terminal_size, ' ') if HAS_COLORAMA: if alternator: sys.stdout.write(colorama.Fore.BLACK) @@ -242,7 +242,8 @@ def colorama_print(text): sys.stdout.write(colorama.Fore.WHITE) sys.stdout.write(colorama.Back.BLACK) alternator = not alternator - print(line) + # \r because the ljust puts us on the next line, no need for \n + print(line, end='\r', flush=True) if HAS_COLORAMA: sys.stdout.write(colorama.Back.RESET) sys.stdout.write(colorama.Fore.RESET) @@ -274,11 +275,20 @@ def multi_line_input(): return userinput.strip() def nicewrap(message, width, paddingleft): - # http://stackoverflow.com/a/26538082 ########################## - message = '\n'.join(['\n'.join(textwrap.wrap(line, width,####### - break_long_words=True, replace_whitespace=False))########## - for line in message.split('\n')])########################## - ################################################################ + # http://stackoverflow.com/a/26538082 + message = message.split('\n') + message = [ + textwrap.wrap( + line, + width, + break_long_words=True, + replace_whitespace=False, + ) + for line in message + ] + message = ['\n'.join(line) for line in message] + message = '\n'.join(message) + message = message.strip() message = message.replace('\n', '\n' + (' '*paddingleft)) return message diff --git a/Toolbox/bitrate_chart.py b/Toolbox/bitrate_chart.py new file mode 100644 index 0000000..bb11139 --- /dev/null +++ b/Toolbox/bitrate_chart.py @@ -0,0 +1,49 @@ +''' + bitrate | 01 | 1:00 | 30:00 | 1:00:00 | 1:30:00 | 2:00:00 + -: | -: | -: | -: | -: | -: | -: + 128 kbps | 16.000 KiB | 960.000 KiB | 28.125 MiB | 56.250 MiB | 84.375 MiB | 112.500 MiB + 256 kbps | 32.000 KiB | 1.875 MiB | 56.250 MiB | 112.500 MiB | 168.750 MiB | 225.000 MiB + 320 kbps | 40.000 KiB | 2.344 MiB | 70.312 MiB | 140.625 MiB | 210.938 MiB | 281.250 MiB + 500 kbps | 62.500 KiB | 3.662 MiB | 109.863 MiB | 219.727 MiB | 329.590 MiB | 439.453 MiB + 640 kbps | 80.000 KiB | 4.688 MiB | 140.625 MiB | 281.250 MiB | 421.875 MiB | 562.500 MiB + 738 kbps | 92.250 KiB | 5.405 MiB | 162.158 MiB | 324.316 MiB | 486.475 MiB | 648.633 MiB + 1024 kbps | 128.000 KiB | 7.500 MiB | 225.000 MiB | 450.000 MiB | 675.000 MiB | 900.000 MiB + 2048 kbps | 256.000 KiB | 15.000 MiB | 450.000 MiB | 900.000 MiB | 1.318 GiB | 1.758 GiB + 2330 kbps | 291.271 KiB | 17.067 MiB | 512.000 MiB | 1.000 GiB | 1.500 GiB | 2.000 GiB + 3072 kbps | 384.000 KiB | 22.500 MiB | 675.000 MiB | 1.318 GiB | 1.978 GiB | 2.637 GiB + 4096 kbps | 512.000 KiB | 30.000 MiB | 900.000 MiB | 1.758 GiB | 2.637 GiB | 3.516 GiB + 4660 kbps | 582.543 KiB | 34.133 MiB | 1.000 GiB | 2.000 GiB | 3.000 GiB | 4.000 GiB + 6144 kbps | 768.000 KiB | 45.000 MiB | 1.318 GiB | 2.637 GiB | 3.955 GiB | 5.273 GiB + 8192 kbps | 1.000 MiB | 60.000 MiB | 1.758 GiB | 3.516 GiB | 5.273 GiB | 7.031 GiB +12288 kbps | 1.500 MiB | 90.000 MiB | 2.637 GiB | 5.273 GiB | 7.910 GiB | 10.547 GiB +16384 kbps | 2.000 MiB | 120.000 MiB | 3.516 GiB | 7.031 GiB | 10.547 GiB | 14.062 GiB +''' +import sys +sys.path.append('C:\\git\\else\\bytestring') +import bytestring +import kbps +times = ['01', '1:00', '30:00', '1:00:00', '1:30:00', '2:00:00'] +rates = [128, 256, 320, 500, 640, 738, 1024, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 2330.17, 4660.34] + +times.sort(key=lambda x: kbps.hms_s(x)) +rates.sort() + +table = [] +table.append('bitrate | ' + ' | '.join(times)) +table.append('-: | ' * (len(times)+1)) +for r in rates: + l = [] + l.append('%d kbps' % r) + for t in times: + l.append(bytestring.bytestring(kbps.calc(kbps.hms_s(t), r))) + l = ' | '.join(l) + table.append(l) + +#print('\n'.join(table)) +columns = [[b.strip() for b in a] for a in zip(*[x.split('|') for x in table])] +for (index, column) in enumerate(columns): + width = max((len(x) for x in column)) + columns[index] = [x.rjust(width, ' ') for x in column] +table = [' | '.join(a) for a in zip(*columns)] +#print(columns) +print('\n'.join(table)) \ No newline at end of file diff --git a/Toolbox/clipboard.py b/Toolbox/clipboard.py new file mode 100644 index 0000000..640280c --- /dev/null +++ b/Toolbox/clipboard.py @@ -0,0 +1,12 @@ +import pyperclip +import sys + + +if len(sys.argv) > 1: + sys.path.append('C:\\git\\else\\Clipext'); import clipext + stuff = clipext.resolve(sys.argv[1]) + pyperclip.copy(stuff) +else: + text = pyperclip.paste() + text = text.replace('\r', '') + print(text) diff --git a/Toolbox/contentreplace.py b/Toolbox/contentreplace.py new file mode 100644 index 0000000..c90ece6 --- /dev/null +++ b/Toolbox/contentreplace.py @@ -0,0 +1,35 @@ +import codecs +import sys +filename = sys.argv[1] +replace_from = sys.argv[2] +replace_to = sys.argv[3] +try: + automatic = sys.argv[4] == '-y' +except IndexError: + automatic = False + +replace_from = codecs.decode(replace_from, 'unicode_escape') +replace_to = codecs.decode(replace_to, 'unicode_escape') + +f = open(filename, 'r', encoding='utf-8') +with f: + content = f.read() + +occurances = content.count(replace_from) +if occurances == 0: + print('No occurances') + exit() + +print('Found %d occurances.' % occurances) +if automatic: + permission = 'y' +else: + permission = input('Replace? ') +if permission.lower() not in ['y', 'yes']: + exit() + +content = content.replace(replace_from, replace_to) + +f = open(filename, 'w', encoding='utf-8') +with f: + f.write(content) \ No newline at end of file diff --git a/Toolbox/ffrename.py b/Toolbox/ffrename.py new file mode 100644 index 0000000..900d296 --- /dev/null +++ b/Toolbox/ffrename.py @@ -0,0 +1,43 @@ +import converter +import os +import re +import subprocess +import sys +import time + +def main(filename): + assert os.path.isfile(filename) + ffmpeg = converter.Converter() + probe = ffmpeg.probe(filename) + new_name = filename + if '_x_' in filename: + dimensions = '%dx%d' % (probe.video.video_width, probe.video.video_height) + new_name = new_name.replace('_x_', dimensions) + if '___' in filename: + video_codec = probe.video.codec + + audios = [stream for stream in probe.streams if stream.type == 'audio'] + audio = max(audios, key=lambda x: x.bitrate) + + audio_codec = probe.audio.codec + + if any(not x for x in [video_codec, probe.video.bitrate, audio_codec, probe.audio.bitrate]): + print('Could not identify media info') + else: + video_bitrate = probe.video.bitrate // 1000 + audio_bitrate = probe.audio.bitrate // 1000 + video = '%s-%d' % (video_codec, video_bitrate) + audio = '%s-%d' % (audio_codec, audio_bitrate) + + video = video.upper() + audio = audio.upper() + video = video.replace('H264', 'h264') + video = video.replace('HEVC', 'h265') + info = '{v}, {a}'.format(v=video, a=audio) + new_name = new_name.replace('___', info) + print(new_name) + if input('Okay?').lower() in ['y', 'yes']: + os.rename(filename, new_name) + +if __name__ == '__main__': + main(sys.argv[1]) \ No newline at end of file diff --git a/Toolbox/filepull.py b/Toolbox/filepull.py new file mode 100644 index 0000000..6ffdd98 --- /dev/null +++ b/Toolbox/filepull.py @@ -0,0 +1,37 @@ +import os +import sys + +sys.path.append('C:\\git\\else\\spinaltap') +import spinal + +def main(): + files = list(spinal.walk_generator()) + cwd = os.getcwd() + files = [f for f in files if os.path.split(f.absolute_path)[0] != cwd] + + if len(files) == 0: + print('No files to move') + return + + duplicate_count = {} + for f in files: + basename = f.basename + duplicate_count.setdefault(basename, []) + duplicate_count[basename].append(f.absolute_path) + + duplicates = ['\n'.join(sorted(copies)) for (basename, copies) in duplicate_count.items() if len(copies) > 1] + duplicates = sorted(duplicates) + if len(duplicates) > 0: + raise Exception('duplicate names:\n' + '\n'.join(duplicates)) + + for f in files: + print(f.basename) + + print('Move %d files?' % len(files)) + if input('> ').lower() in ['y', 'yes']: + for f in files: + local = os.path.join('.', f.basename) + os.rename(f.absolute_path, local) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/Toolbox/fileswith.py b/Toolbox/fileswith.py new file mode 100644 index 0000000..69b935c --- /dev/null +++ b/Toolbox/fileswith.py @@ -0,0 +1,27 @@ +import fnmatch +import glob +import re +import sys +sys.path.append('C:\\git\\else\\spinaltap'); import spinal + +filepattern = sys.argv[1] +searchpattern = sys.argv[2] + +for filename in spinal.walk_generator(): + filename = filename.absolute_path + if not fnmatch.fnmatch(filename, filepattern): + continue + matches = [] + handle = open(filename, 'r', encoding='utf-8') + try: + with handle: + for (index, line) in enumerate(handle): + if re.search(searchpattern, line, flags=re.IGNORECASE): + line = '%d | %s' % (index, line.strip()) + matches.append(line) + except: + pass + if matches: + print(filename) + print('\n'.join(matches)) + print() \ No newline at end of file diff --git a/Toolbox/kbps.py b/Toolbox/kbps.py new file mode 100644 index 0000000..00461b0 --- /dev/null +++ b/Toolbox/kbps.py @@ -0,0 +1,32 @@ +import sys +try: + sys.path.append('C:\\git\\else\\Bytestring') + import bytestring +except ImportError: + # pip install + # https://raw.githubusercontent.com/voussoir/else/master/_voussoirkit/voussoirkit.zip + from vousoirkit import bytestring + +def hms_s(hms): + hms = hms.split(':') + seconds = 0 + if len(hms) == 3: + seconds += int(hms[0])*3600 + hms.pop(0) + if len(hms) == 2: + seconds += int(hms[0])*60 + hms.pop(0) + if len(hms) == 1: + seconds += int(hms[0]) + return seconds + +def calc(seconds, kbps): + final_kilobits = kbps * seconds + final_bytes = final_kilobits * 128 + return final_bytes + +if __name__ == '__main__': + length = sys.argv[1] # HH:MM:SS + kbps = int(sys.argv[2]) + seconds = hms_s(length) + print(bytestring.bytestring(calc(seconds, kbps))) \ No newline at end of file diff --git a/Toolbox/kbpsr.py b/Toolbox/kbpsr.py new file mode 100644 index 0000000..81bfaff --- /dev/null +++ b/Toolbox/kbpsr.py @@ -0,0 +1,35 @@ +import sys + +try: + sys.path.append('C:\\git\\else\\Bytestring') + import bytestring +except ImportError: + # pip install + # https://raw.githubusercontent.com/voussoir/else/master/_voussoirkit/voussoirkit.zip + from vousoirkit import bytestring + +def hms_s(hms): + hms = hms.split(':') + seconds = 0 + if len(hms) == 3: + seconds += int(hms[0])*3600 + hms.pop(0) + if len(hms) == 2: + seconds += int(hms[0])*60 + hms.pop(0) + if len(hms) == 1: + seconds += int(hms[0]) + return seconds + +def calc(seconds, goal_bytes): + goal_kibs = goal_bytes / 1024 + goal_kilobits = goal_kibs * 8 + goal_kbps = goal_kilobits / seconds + goal_kbps = round(goal_kbps, 2) + return goal_kbps + +if __name__ == '__main__': + length = sys.argv[1] # HH:MM:SS + goal_bytes = bytestring.parsebytes(sys.argv[2]) + seconds = hms_s(length) + print(calc(seconds, goal_bytes), 'kbps') \ No newline at end of file diff --git a/Toolbox/randomfile.py b/Toolbox/randomfile.py new file mode 100644 index 0000000..33c5295 --- /dev/null +++ b/Toolbox/randomfile.py @@ -0,0 +1,46 @@ +import math +import random +import sys +import bytestring +CHUNK_SIZE = 512 * (2 ** 10) +def listget(li, index, fallback=None): + try: + return li[index] + except IndexError: + return fallback + +def rid(length=8): + import random + bits = length * 4 + bits = random.getrandbits(bits) + identifier = '{:02x}'.format(bits).rjust(length, '0') + return identifier + +def make_randomfile(length, filename=None): + if filename is None: + filename = rid(8) + '.txt' + chunks = math.ceil(length / CHUNK_SIZE) + written = 0 + f = open(filename, 'w') + for x in range(chunks): + b = min(CHUNK_SIZE, length-written) + f.write(rid(b)) + written += b + f.close() + print('Created %s' % filename) + + +bytes = listget(sys.argv, 1, None) +if bytes is None: + bytes = 2 ** 10 +else: + bytes = bytestring.parsebytes(bytes) + +filecount = 1 +filename = listget(sys.argv, 2, None) +if filename is not None and filename.isdigit(): + filecount = int(filename) + filename = None + +for x in range(filecount): + make_randomfile(bytes, filename) \ No newline at end of file diff --git a/Toolbox/rejpg.py b/Toolbox/rejpg.py new file mode 100644 index 0000000..927caa1 --- /dev/null +++ b/Toolbox/rejpg.py @@ -0,0 +1,44 @@ +from voussoirkit import bytestring +import io +import os +import PIL.Image +import PIL.ImageFile +import string +import sys + +PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True + +if '/r' in sys.argv: + sys.path.append('C:\\git\\else\\spinaltap') + import spinal + walker = spinal.walk_generator() + files = list(walker) + files = [f.absolute_path for f in files] + +else: + files = os.listdir() + files = [f for f in files if os.path.isfile(f)] + +files = [f for f in files if any(ext in f.lower() for ext in ['.jpg', '.jpeg'])] + +bytes_saved = 0 +remaining_size = 0 +for filename in files: + print(''.join(c for c in filename if c in string.printable)) + bytesio = io.BytesIO() + i = PIL.Image.open(filename) + i.save(bytesio, format='jpeg', quality=80) + + bytesio.seek(0) + new_bytes = bytesio.read() + old_size = os.path.getsize(filename) + new_size = len(new_bytes) + remaining_size += new_size + if new_size < old_size: + bytes_saved += (old_size - new_size) + f = open(filename, 'wb') + f.write(new_bytes) + f.close() + +print('Saved', bytestring.bytestring(bytes_saved)) +print('Remaining are', bytestring.bytestring(remaining_size)) \ No newline at end of file diff --git a/Toolbox/touch.py b/Toolbox/touch.py new file mode 100644 index 0000000..d4fc3ae --- /dev/null +++ b/Toolbox/touch.py @@ -0,0 +1,15 @@ +import glob +import os +import sys + + +glob_patterns = sys.argv[1:] +for glob_pattern in glob_patterns: + filenames = glob.glob(glob_pattern) + if len(filenames) == 0: + print(glob_pattern) + open(glob_pattern, 'a').close() + else: + for filename in filenames: + print(filename) + os.utime(filename)