mirror of
https://github.com/clinton-hall/nzbToMedia.git
synced 2025-08-14 18:47:09 -07:00
Move Windows libs to libs/windows
This commit is contained in:
parent
3975aaceb2
commit
3a692c94a5
684 changed files with 4 additions and 1 deletions
0
libs/win/jaraco/ui/__init__.py
Normal file
0
libs/win/jaraco/ui/__init__.py
Normal file
77
libs/win/jaraco/ui/cmdline.py
Normal file
77
libs/win/jaraco/ui/cmdline.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
import argparse
|
||||
|
||||
import six
|
||||
from jaraco.classes import meta
|
||||
from jaraco import text
|
||||
|
||||
|
||||
@six.add_metaclass(meta.LeafClassesMeta)
|
||||
class Command(object):
|
||||
"""
|
||||
A general-purpose base class for creating commands for a command-line
|
||||
program using argparse. Each subclass of Command represents a separate
|
||||
sub-command of a program.
|
||||
|
||||
For example, one might use Command subclasses to implement the Mercurial
|
||||
command set::
|
||||
|
||||
class Commit(Command):
|
||||
@staticmethod
|
||||
def add_arguments(cls, parser):
|
||||
parser.add_argument('-m', '--message')
|
||||
|
||||
@classmethod
|
||||
def run(cls, args):
|
||||
"Run the 'commit' command with args (parsed)"
|
||||
|
||||
class Merge(Command): pass
|
||||
class Pull(Command): pass
|
||||
...
|
||||
|
||||
Then one could create an entry point for Mercurial like so::
|
||||
|
||||
def hg_command():
|
||||
Command.invoke()
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def add_subparsers(cls, parser):
|
||||
subparsers = parser.add_subparsers()
|
||||
[cmd_class.add_parser(subparsers) for cmd_class in cls._leaf_classes]
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
cmd_string = text.words(cls.__name__).lowered().dash_separated()
|
||||
parser = subparsers.add_parser(cmd_string)
|
||||
parser.set_defaults(action=cls)
|
||||
cls.add_arguments(parser)
|
||||
return parser
|
||||
|
||||
@classmethod
|
||||
def add_arguments(cls, parser):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def invoke(cls):
|
||||
"""
|
||||
Invoke the command using ArgumentParser
|
||||
"""
|
||||
parser = argparse.ArgumentParser()
|
||||
cls.add_subparsers(parser)
|
||||
args = parser.parse_args()
|
||||
args.action.run(args)
|
||||
|
||||
|
||||
class Extend(argparse.Action):
|
||||
"""
|
||||
Argparse action to take an nargs=* argument
|
||||
and add any values to the existing value.
|
||||
|
||||
>>> parser = argparse.ArgumentParser()
|
||||
>>> _ = parser.add_argument('--foo', nargs='*', default=[], action=Extend)
|
||||
>>> args = parser.parse_args(['--foo', 'a=1', '--foo', 'b=2', 'c=3'])
|
||||
>>> args.foo
|
||||
['a=1', 'b=2', 'c=3']
|
||||
"""
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
getattr(namespace, self.dest).extend(values)
|
108
libs/win/jaraco/ui/editor.py
Normal file
108
libs/win/jaraco/ui/editor.py
Normal file
|
@ -0,0 +1,108 @@
|
|||
from __future__ import unicode_literals, absolute_import
|
||||
|
||||
import tempfile
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import mimetypes
|
||||
import collections
|
||||
import io
|
||||
import difflib
|
||||
|
||||
import six
|
||||
|
||||
class EditProcessException(RuntimeError): pass
|
||||
|
||||
class EditableFile(object):
|
||||
"""
|
||||
EditableFile saves some data to a temporary file, launches a
|
||||
platform editor for interactive editing, and then reloads the data,
|
||||
setting .changed to True if the data was edited.
|
||||
|
||||
e.g.::
|
||||
|
||||
x = EditableFile('foo')
|
||||
x.edit()
|
||||
|
||||
if x.changed:
|
||||
print(x.data)
|
||||
|
||||
The EDITOR environment variable can define which executable to use
|
||||
(also XML_EDITOR if the content-type to edit includes 'xml'). If no
|
||||
EDITOR is defined, defaults to 'notepad' on Windows and 'edit' on
|
||||
other platforms.
|
||||
"""
|
||||
platform_default_editors = collections.defaultdict(
|
||||
lambda: 'edit',
|
||||
win32 = 'notepad',
|
||||
linux2 = 'vi',
|
||||
)
|
||||
encoding = 'utf-8'
|
||||
|
||||
def __init__(self, data='', content_type='text/plain'):
|
||||
self.data = six.text_type(data)
|
||||
self.content_type = content_type
|
||||
|
||||
def __enter__(self):
|
||||
extension = mimetypes.guess_extension(self.content_type) or ''
|
||||
fobj, self.name = tempfile.mkstemp(extension)
|
||||
os.write(fobj, self.data.encode(self.encoding))
|
||||
os.close(fobj)
|
||||
return self
|
||||
|
||||
def read(self):
|
||||
with open(self.name, 'rb') as f:
|
||||
return f.read().decode(self.encoding)
|
||||
|
||||
def __exit__(self, *tb_info):
|
||||
os.remove(self.name)
|
||||
|
||||
def edit(self):
|
||||
"""
|
||||
Edit the file
|
||||
"""
|
||||
self.changed = False
|
||||
with self:
|
||||
editor = self.get_editor()
|
||||
cmd = [editor, self.name]
|
||||
try:
|
||||
res = subprocess.call(cmd)
|
||||
except Exception as e:
|
||||
print("Error launching editor %(editor)s" % locals())
|
||||
print(e)
|
||||
return
|
||||
if res != 0:
|
||||
msg = '%(editor)s returned error status %(res)d' % locals()
|
||||
raise EditProcessException(msg)
|
||||
new_data = self.read()
|
||||
if new_data != self.data:
|
||||
self.changed = self._save_diff(self.data, new_data)
|
||||
self.data = new_data
|
||||
|
||||
@staticmethod
|
||||
def _search_env(keys):
|
||||
"""
|
||||
Search the environment for the supplied keys, returning the first
|
||||
one found or None if none was found.
|
||||
"""
|
||||
matches = (os.environ[key] for key in keys if key in os.environ)
|
||||
return next(matches, None)
|
||||
|
||||
def get_editor(self):
|
||||
"""
|
||||
Give preference to an XML_EDITOR or EDITOR defined in the
|
||||
environment. Otherwise use a default editor based on platform.
|
||||
"""
|
||||
env_search = ['EDITOR']
|
||||
if 'xml' in self.content_type:
|
||||
env_search.insert(0, 'XML_EDITOR')
|
||||
default_editor = self.platform_default_editors[sys.platform]
|
||||
return self._search_env(env_search) or default_editor
|
||||
|
||||
@staticmethod
|
||||
def _save_diff(*versions):
|
||||
def get_lines(content):
|
||||
return list(io.StringIO(content))
|
||||
lines = map(get_lines, versions)
|
||||
diff = difflib.context_diff(*lines)
|
||||
return tuple(diff)
|
26
libs/win/jaraco/ui/input.py
Normal file
26
libs/win/jaraco/ui/input.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This module currently provides a cross-platform getch function
|
||||
"""
|
||||
|
||||
try:
|
||||
# Windows
|
||||
from msvcrt import getch
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
# Unix
|
||||
import sys
|
||||
import tty
|
||||
import termios
|
||||
|
||||
def getch():
|
||||
fd = sys.stdin.fileno()
|
||||
old = termios.tcgetattr(fd)
|
||||
try:
|
||||
tty.setraw(fd)
|
||||
return sys.stdin.read(1)
|
||||
finally:
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, old)
|
||||
except ImportError:
|
||||
pass
|
34
libs/win/jaraco/ui/menu.py
Normal file
34
libs/win/jaraco/ui/menu.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
from __future__ import print_function, absolute_import, unicode_literals
|
||||
|
||||
import itertools
|
||||
|
||||
import six
|
||||
|
||||
class Menu(object):
|
||||
"""
|
||||
A simple command-line based menu
|
||||
"""
|
||||
def __init__(self, choices=None, formatter=str):
|
||||
self.choices = choices or list()
|
||||
self.formatter = formatter
|
||||
|
||||
def get_choice(self, prompt="> "):
|
||||
n = len(self.choices)
|
||||
number_width = len(str(n)) + 1
|
||||
menu_fmt = '{number:{number_width}}) {choice}'
|
||||
formatted_choices = map(self.formatter, self.choices)
|
||||
for number, choice in zip(itertools.count(1), formatted_choices):
|
||||
print(menu_fmt.format(**locals()))
|
||||
print()
|
||||
try:
|
||||
answer = int(six.moves.input(prompt))
|
||||
result = self.choices[answer - 1]
|
||||
except ValueError:
|
||||
print('invalid selection')
|
||||
result = None
|
||||
except IndexError:
|
||||
print('invalid selection')
|
||||
result = None
|
||||
except KeyboardInterrupt:
|
||||
result = None
|
||||
return result
|
152
libs/win/jaraco/ui/progress.py
Normal file
152
libs/win/jaraco/ui/progress.py
Normal file
|
@ -0,0 +1,152 @@
|
|||
# deprecated -- use TQDM
|
||||
|
||||
from __future__ import (print_function, absolute_import, unicode_literals,
|
||||
division)
|
||||
|
||||
import time
|
||||
import sys
|
||||
import itertools
|
||||
import abc
|
||||
import datetime
|
||||
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class AbstractProgressBar(object):
|
||||
def __init__(self, unit='', size=70):
|
||||
"""
|
||||
Size is the nominal size in characters
|
||||
"""
|
||||
self.unit = unit
|
||||
self.size = size
|
||||
|
||||
def report(self, amt):
|
||||
sys.stdout.write('\r%s' % self.get_bar(amt))
|
||||
sys.stdout.flush()
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_bar(self, amt):
|
||||
"Return the string to be printed. Should be size >= self.size"
|
||||
|
||||
def summary(self, str):
|
||||
return ' (' + self.unit_str(str) + ')'
|
||||
|
||||
def unit_str(self, str):
|
||||
if self.unit:
|
||||
str += ' ' + self.unit
|
||||
return str
|
||||
|
||||
def finish(self):
|
||||
print()
|
||||
|
||||
def __enter__(self):
|
||||
self.report(0)
|
||||
return self
|
||||
|
||||
def __exit__(self, exc, exc_val, tb):
|
||||
if exc is None:
|
||||
self.finish()
|
||||
else:
|
||||
print()
|
||||
|
||||
def iterate(self, iterable):
|
||||
"""
|
||||
Report the status as the iterable is consumed.
|
||||
"""
|
||||
with self:
|
||||
for n, item in enumerate(iterable, 1):
|
||||
self.report(n)
|
||||
yield item
|
||||
|
||||
|
||||
class SimpleProgressBar(AbstractProgressBar):
|
||||
|
||||
_PROG_DISPGLYPH = itertools.cycle(['|', '/', '-', '\\'])
|
||||
|
||||
def get_bar(self, amt):
|
||||
bar = next(self._PROG_DISPGLYPH)
|
||||
template = ' [{bar:^{bar_len}}]'
|
||||
summary = self.summary('{amt}')
|
||||
template += summary
|
||||
empty = template.format(
|
||||
bar='',
|
||||
bar_len=0,
|
||||
amt=amt,
|
||||
)
|
||||
bar_len = self.size - len(empty)
|
||||
return template.format(**locals())
|
||||
|
||||
@classmethod
|
||||
def demo(cls):
|
||||
bar3 = cls(unit='cubes', size=30)
|
||||
with bar3:
|
||||
for x in six.moves.range(1, 759):
|
||||
bar3.report(x)
|
||||
time.sleep(0.01)
|
||||
|
||||
|
||||
class TargetProgressBar(AbstractProgressBar):
|
||||
def __init__(self, total=None, unit='', size=70):
|
||||
"""
|
||||
Size is the nominal size in characters
|
||||
"""
|
||||
self.total = total
|
||||
super(TargetProgressBar, self).__init__(unit, size)
|
||||
|
||||
def get_bar(self, amt):
|
||||
template = ' [{bar:<{bar_len}}]'
|
||||
completed = amt / self.total
|
||||
percent = int(completed * 100)
|
||||
percent_str = ' {percent:3}%'
|
||||
template += percent_str
|
||||
summary = self.summary('{amt}/{total}')
|
||||
template += summary
|
||||
empty = template.format(
|
||||
total=self.total,
|
||||
bar='',
|
||||
bar_len=0,
|
||||
**locals()
|
||||
)
|
||||
bar_len = self.size - len(empty)
|
||||
bar = '=' * int(completed * bar_len)
|
||||
return template.format(total=self.total, **locals())
|
||||
|
||||
@classmethod
|
||||
def demo(cls):
|
||||
bar1 = cls(100, 'blocks')
|
||||
with bar1:
|
||||
for x in six.moves.range(1, 101):
|
||||
bar1.report(x)
|
||||
time.sleep(0.05)
|
||||
|
||||
bar2 = cls(758, size=50)
|
||||
with bar2:
|
||||
for x in six.moves.range(1, 759):
|
||||
bar2.report(x)
|
||||
time.sleep(0.01)
|
||||
|
||||
def finish(self):
|
||||
self.report(self.total)
|
||||
super(TargetProgressBar, self).finish()
|
||||
|
||||
|
||||
def countdown(template, duration=datetime.timedelta(seconds=5)):
|
||||
"""
|
||||
Do a countdown for duration, printing the template (which may accept one
|
||||
positional argument). Template should be something like
|
||||
``countdown complete in {} seconds.``
|
||||
"""
|
||||
now = datetime.datetime.now()
|
||||
deadline = now + duration
|
||||
remaining = deadline - datetime.datetime.now()
|
||||
while remaining:
|
||||
remaining = deadline - datetime.datetime.now()
|
||||
remaining = max(datetime.timedelta(), remaining)
|
||||
msg = template.format(remaining.total_seconds())
|
||||
print(msg, end=' '*10)
|
||||
sys.stdout.flush()
|
||||
time.sleep(.1)
|
||||
print('\b'*80, end='')
|
||||
sys.stdout.flush()
|
||||
print()
|
Loading…
Add table
Add a link
Reference in a new issue