Compare commits
10 commits
e0e12c0184
...
75b75a1d55
| Author | SHA1 | Date | |
|---|---|---|---|
| 75b75a1d55 | |||
| 013e79cd6b | |||
| 0881f43d85 | |||
| 0d66651c5c | |||
| 81d5621785 | |||
| 9803730675 | |||
| 5a06d78a65 | |||
| eb4e381022 | |||
| 019bba23f2 | |||
| 6fe7e5e5a6 |
8 changed files with 90 additions and 10 deletions
2
setup.py
2
setup.py
|
|
@ -3,7 +3,7 @@ import setuptools
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name='voussoirkit',
|
name='voussoirkit',
|
||||||
packages=setuptools.find_packages(),
|
packages=setuptools.find_packages(),
|
||||||
version='0.0.74',
|
version='0.0.76',
|
||||||
author='voussoir',
|
author='voussoir',
|
||||||
author_email='pypi@voussoir.net',
|
author_email='pypi@voussoir.net',
|
||||||
description='voussoir\'s toolkit',
|
description='voussoir\'s toolkit',
|
||||||
|
|
|
||||||
|
|
@ -518,8 +518,13 @@ def make_helptext(
|
||||||
|
|
||||||
# PUT IT ALL TOGETHER
|
# PUT IT ALL TOGETHER
|
||||||
|
|
||||||
|
if command_name is None:
|
||||||
|
header_name = program_name
|
||||||
|
else:
|
||||||
|
header_name = f'{program_name} {command_name}'
|
||||||
|
|
||||||
parts = [
|
parts = [
|
||||||
niceprints.equals_header(program_name) if do_headline else None,
|
niceprints.equals_header(header_name) if do_headline else None,
|
||||||
program_description,
|
program_description,
|
||||||
main_invocation,
|
main_invocation,
|
||||||
'\n\n'.join(argument_helps),
|
'\n\n'.join(argument_helps),
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,7 @@ def prepare_plan(
|
||||||
if do_head:
|
if do_head:
|
||||||
# I'm using a GET instead of an actual HEAD here because some servers respond
|
# I'm using a GET instead of an actual HEAD here because some servers respond
|
||||||
# differently, even though they're not supposed to.
|
# differently, even though they're not supposed to.
|
||||||
head = request('get', url, stream=True, headers=temp_headers, auth=auth)
|
head = request('get', url, stream=True, headers=temp_headers, auth=auth, verify_ssl=verify_ssl)
|
||||||
remote_total_bytes = head.headers.get('content-length', None)
|
remote_total_bytes = head.headers.get('content-length', None)
|
||||||
remote_total_bytes = None if remote_total_bytes is None else int(remote_total_bytes)
|
remote_total_bytes = None if remote_total_bytes is None else int(remote_total_bytes)
|
||||||
server_respects_range = (head.status_code == 206 and 'content-range' in head.headers)
|
server_respects_range = (head.status_code == 206 and 'content-range' in head.headers)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import exifread
|
||||||
import io
|
import io
|
||||||
import PIL.ExifTags
|
import PIL.ExifTags
|
||||||
import PIL.Image
|
import PIL.Image
|
||||||
|
import PIL.ImageCms
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from voussoirkit import pathclass
|
from voussoirkit import pathclass
|
||||||
|
|
@ -40,6 +41,20 @@ def checkerboard_image(color_1, color_2, image_size, checker_size) -> PIL.Image:
|
||||||
offset = not offset
|
offset = not offset
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
def convert_to_srgb(image):
|
||||||
|
'''
|
||||||
|
Thank you Andriy Makukha
|
||||||
|
https://stackoverflow.com/a/50623824
|
||||||
|
'''
|
||||||
|
icc = image.info.get('icc_profile', '')
|
||||||
|
if icc:
|
||||||
|
image = PIL.ImageCms.profileToProfile(
|
||||||
|
image,
|
||||||
|
inputProfile=PIL.ImageCms.ImageCmsProfile(io.BytesIO(icc)),
|
||||||
|
outputProfile=PIL.ImageCms.createProfile('sRGB'),
|
||||||
|
)
|
||||||
|
return image
|
||||||
|
|
||||||
def fit_into_bounds(
|
def fit_into_bounds(
|
||||||
image_width,
|
image_width,
|
||||||
image_height,
|
image_height,
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,14 @@ def main_log_context(subject, level, **kwargs):
|
||||||
log = vlogging.getLogger()
|
log = vlogging.getLogger()
|
||||||
handler = LogHandler(subject, **kwargs)
|
handler = LogHandler(subject, **kwargs)
|
||||||
handler.setLevel(level)
|
handler.setLevel(level)
|
||||||
handler.setFormatter(vlogging.Formatter('{levelname}:{name}:{message}', style='{'))
|
datefmt = '%Y-%m-%dT%H:%M:%S'
|
||||||
|
formatter = vlogging.Formatter(
|
||||||
|
'[{asctime}.{msecs:03.0f}] {levelname}:{name}:{message}',
|
||||||
|
style='{',
|
||||||
|
datefmt=datefmt,
|
||||||
|
)
|
||||||
|
formatter.default_msec_format = '%s.%03d'
|
||||||
|
handler.setFormatter(formatter)
|
||||||
context = LogHandlerContext(log, handler)
|
context = LogHandlerContext(log, handler)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,12 +54,15 @@ def add_loud(log):
|
||||||
|
|
||||||
def add_root_handler(level):
|
def add_root_handler(level):
|
||||||
handler = StreamHandler()
|
handler = StreamHandler()
|
||||||
|
datefmt = '%Y-%m-%dT%H:%M:%S'
|
||||||
if level <= LOUD:
|
if level <= LOUD:
|
||||||
handler.setFormatter(Formatter('{levelname}:{name}.{funcName}.{lineno}:{message}', style='{'))
|
formatter = Formatter('[{asctime}.{msecs:03.0f}] {levelname}:{name}.{funcName}.{lineno}:{message}', style='{', datefmt=datefmt)
|
||||||
elif level <= DEBUG:
|
elif level <= DEBUG:
|
||||||
handler.setFormatter(Formatter('{levelname}:{name}.{funcName}:{message}', style='{'))
|
formatter = Formatter('[{asctime}.{msecs:03.0f}] {levelname}:{name}.{funcName}:{message}', style='{', datefmt=datefmt)
|
||||||
else:
|
else:
|
||||||
handler.setFormatter(Formatter('{levelname}:{name}:{message}', style='{'))
|
formatter = Formatter('[{asctime}.{msecs:03.0f}] {levelname}:{name}:{message}', style='{', datefmt=datefmt)
|
||||||
|
formatter.default_msec_format = '%s.%03d'
|
||||||
|
handler.setFormatter(formatter)
|
||||||
handler.setLevel(level)
|
handler.setLevel(level)
|
||||||
root.addHandler(handler)
|
root.addHandler(handler)
|
||||||
return handler
|
return handler
|
||||||
|
|
|
||||||
|
|
@ -651,15 +651,16 @@ class DatabaseWithCaching(Database, metaclass=abc.ABCMeta):
|
||||||
object_table = object_class.table
|
object_table = object_class.table
|
||||||
object_cache = self.caches.get(object_class, None)
|
object_cache = self.caches.get(object_class, None)
|
||||||
|
|
||||||
|
if object_cache is None:
|
||||||
|
log.loud('The %s table is not cached. Returning new instance.', object_class.table)
|
||||||
|
return object_class(self, db_row)
|
||||||
|
|
||||||
if isinstance(db_row, (dict, sqlite3.Row)):
|
if isinstance(db_row, (dict, sqlite3.Row)):
|
||||||
object_id = db_row['id']
|
object_id = db_row['id']
|
||||||
else:
|
else:
|
||||||
object_index = self.COLUMN_INDEX[object_table]
|
object_index = self.COLUMN_INDEX[object_table]
|
||||||
object_id = db_row[object_index['id']]
|
object_id = db_row[object_index['id']]
|
||||||
|
|
||||||
if object_cache is None:
|
|
||||||
return object_class(self, db_row)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
instance = object_cache[object_id]
|
instance = object_cache[object_id]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
@ -807,6 +808,7 @@ class Object(metaclass=abc.ABCMeta):
|
||||||
'''
|
'''
|
||||||
Your subclass should call super().__init__(database).
|
Your subclass should call super().__init__(database).
|
||||||
'''
|
'''
|
||||||
|
super().__init__()
|
||||||
# Used for transaction
|
# Used for transaction
|
||||||
self._worms_database = database
|
self._worms_database = database
|
||||||
self.deleted = False
|
self.deleted = False
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,54 @@ function join_and_trail(list, separator)
|
||||||
return list.join(separator) + separator
|
return list.join(separator) + separator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
common.hms_render_colons =
|
||||||
|
function hms_render_colons(hours, minutes, seconds)
|
||||||
|
{
|
||||||
|
const parts = [];
|
||||||
|
if (hours !== null)
|
||||||
|
{
|
||||||
|
parts.push(hours.toLocaleString(undefined, {minimumIntegerDigits: 2}));
|
||||||
|
}
|
||||||
|
if (minutes !== null)
|
||||||
|
{
|
||||||
|
parts.push(minutes.toLocaleString(undefined, {minimumIntegerDigits: 2}));
|
||||||
|
}
|
||||||
|
parts.push(seconds.toLocaleString(undefined, {minimumIntegerDigits: 2}));
|
||||||
|
return parts.join(":")
|
||||||
|
}
|
||||||
|
|
||||||
|
common.seconds_to_hms =
|
||||||
|
function seconds_to_hms({
|
||||||
|
seconds,
|
||||||
|
renderer=common.hms_render_colons,
|
||||||
|
force_minutes=false,
|
||||||
|
force_hours=false,
|
||||||
|
})
|
||||||
|
{
|
||||||
|
if (seconds > 0 && seconds < 1)
|
||||||
|
{
|
||||||
|
seconds = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
seconds = Math.round(seconds);
|
||||||
|
}
|
||||||
|
let minutes = Math.floor(seconds / 60);
|
||||||
|
seconds = seconds % 60;
|
||||||
|
let hours = Math.floor(minutes / 60);
|
||||||
|
minutes = minutes % 60;
|
||||||
|
|
||||||
|
if (hours == 0 && force_hours == false)
|
||||||
|
{
|
||||||
|
hours = null;
|
||||||
|
}
|
||||||
|
if (minutes == 0 && force_minutes == false)
|
||||||
|
{
|
||||||
|
minutes = null;
|
||||||
|
}
|
||||||
|
return renderer(hours, minutes, seconds);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// HTML & DOM //////////////////////////////////////////////////////////////////////////////////////
|
// HTML & DOM //////////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue