This commit is contained in:
codl 2017-08-29 21:27:38 +02:00
parent 8f40dbe490
commit 20d765e0d1
No known key found for this signature in database
GPG Key ID: 6CD7C8891ED1233A
9 changed files with 42 additions and 45 deletions

4
app.py
View File

@ -4,9 +4,9 @@ from sqlalchemy import MetaData, event
from sqlalchemy.engine import Engine from sqlalchemy.engine import Engine
from flask_migrate import Migrate from flask_migrate import Migrate
import version import version
from lib import cachebust from lib.cachebust import cachebust
from flask_limiter import Limiter from flask_limiter import Limiter
from lib import get_viewer from lib.session import get_viewer
import os import os
import mimetypes import mimetypes

35
dodo.py
View File

@ -7,44 +7,46 @@ def reltouch(source_filename, dest_filename):
utime(dest_filename, ns=(stat_res.st_atime_ns, stat_res.st_mtime_ns)) utime(dest_filename, ns=(stat_res.st_atime_ns, stat_res.st_mtime_ns))
def resize_image(basename, width, format): def resize_image(basename, width, image_format):
from PIL import Image from PIL import Image
with Image.open('assets/{}.png'.format(basename)) as im: with Image.open('assets/{}.png'.format(basename)) as im:
if 'A' in im.getbands() and format != 'jpeg': if 'A' in im.getbands() and image_format != 'jpeg':
im = im.convert('RGBA') im = im.convert('RGBA')
else: else:
im = im.convert('RGB') im = im.convert('RGB')
height = im.height * width // im.width height = im.height * width // im.width
new = im.resize((width, height), resample=Image.LANCZOS) new = im.resize((width, height), resample=Image.LANCZOS)
if format == 'jpeg': if image_format == 'jpeg':
kwargs = dict( kwargs = dict(
optimize=True, optimize=True,
progressive=True, progressive=True,
quality=80, quality=80,
) )
elif format == 'webp': elif image_format == 'webp':
kwargs = dict( kwargs = dict(
quality=79, quality=79,
) )
elif format == 'png': elif image_format == 'png':
kwargs = dict( kwargs = dict(
optimize=True, optimize=True,
) )
new.save('static/{}-{}.{}'.format(basename, width, format), **kwargs) new.save('static/{}-{}.{}'.format(basename, width, image_format),
**kwargs)
reltouch('assets/{}.png'.format(basename), reltouch('assets/{}.png'.format(basename),
'static/{}-{}.{}'.format(basename, width, format)) 'static/{}-{}.{}'.format(basename, width, image_format))
def task_logotype(): def task_logotype():
"""resize and convert logotype""" """resize and convert logotype"""
widths = (200, 400, 600, 800) widths = (200, 400, 600, 800)
formats = ('jpeg', 'webp') image_formats = ('jpeg', 'webp')
for width in widths: for width in widths:
for format in formats: for image_format in image_formats:
yield dict( yield dict(
name='{}.{}'.format(width, format), name='{}.{}'.format(width, image_format),
actions=[(resize_image, ('logotype', width, format))], actions=[(resize_image,
targets=[f'static/logotype-{width}.{format}'], ('logotype', width, image_format))],
targets=[f'static/logotype-{width}.{image_format}'],
file_dep=['assets/logotype.png'], file_dep=['assets/logotype.png'],
clean=True, clean=True,
) )
@ -55,13 +57,14 @@ def task_service_icon():
widths = (20, 40, 80) widths = (20, 40, 80)
formats = ('webp', 'png') formats = ('webp', 'png')
for width in widths: for width in widths:
for format in formats: for image_format in formats:
for basename in ('twitter', 'mastodon'): for basename in ('twitter', 'mastodon'):
yield dict( yield dict(
name='{}-{}.{}'.format(basename, width, format), name='{}-{}.{}'.format(basename, width, image_format),
actions=[(resize_image, (basename, width, format))], actions=[(resize_image, (basename, width, image_format))],
targets=[ targets=[
'static/{}-{}.{}'.format(basename, width, format)], 'static/{}-{}.{}'.format(basename, width,
image_format)],
file_dep=['assets/{}.png'.format(basename)], file_dep=['assets/{}.png'.format(basename)],
clean=True, clean=True,
) )

View File

@ -1,10 +0,0 @@
from .interval import decompose_interval
from .interval import SCALES as interval_scales
from .cachebust import cachebust
from .session import set_session_cookie, get_viewer_session, get_viewer
from . import auth
from . import brotli
from . import cachebust
from . import interval
from . import session
from . import settings

View File

@ -8,7 +8,9 @@ import mimetypes
class BrotliCache(object): class BrotliCache(object):
def __init__(self, redis_kwargs={}, max_wait=0.020, expire=60*60*6): def __init__(self, redis_kwargs=None, max_wait=0.020, expire=60*60*6):
if not redis_kwargs:
redis_kwargs = {}
self.redis = redis.StrictRedis(**redis_kwargs) self.redis = redis.StrictRedis(**redis_kwargs)
self.max_wait = max_wait self.max_wait = max_wait
self.expire = expire self.expire = expire

View File

@ -3,6 +3,8 @@ import os
def cachebust(app): def cachebust(app):
# pylint: disable=unused-variable
@app.route('/static-cb/<int:timestamp>/<path:filename>') @app.route('/static-cb/<int:timestamp>/<path:filename>')
def static_cachebust(timestamp, filename): def static_cachebust(timestamp, filename):
path = os.path.join(app.static_folder, filename) path = os.path.join(app.static_folder, filename)

View File

@ -24,7 +24,7 @@ def decompose_interval(attrname):
@scale.setter @scale.setter
def scale(self, value): def scale(self, value):
if(type(value) != timedelta): if not isinstance(value, timedelta):
value = timedelta(seconds=float(value)) value = timedelta(seconds=float(value))
setattr(self, attrname, max(1, getattr(self, sig_name)) * value) setattr(self, attrname, max(1, getattr(self, sig_name)) * value)
@ -34,7 +34,7 @@ def decompose_interval(attrname):
@significand.setter @significand.setter
def significand(self, value): def significand(self, value):
if type(value) == str and value.strip() == '': if isinstance(value, str) and value.strip() == '':
value = 0 value = 0
try: try:

View File

@ -2,7 +2,7 @@ from datetime import timedelta, datetime
from app import db from app import db
import secrets import secrets
from lib import decompose_interval from lib.interval import decompose_interval
class TimestampMixin(object): class TimestampMixin(object):
@ -33,8 +33,8 @@ class RemoteIDMixin(object):
return self.id.split(":")[1] return self.id.split(":")[1]
@twitter_id.setter @twitter_id.setter
def twitter_id(self, id): def twitter_id(self, id_):
self.id = "twitter:{}".format(id) self.id = "twitter:{}".format(id_)
@property @property
def mastodon_instance(self): def mastodon_instance(self):
@ -61,8 +61,8 @@ class RemoteIDMixin(object):
return self.id.split(":", 1)[1].split('@')[0] return self.id.split(":", 1)[1].split('@')[0]
@mastodon_id.setter @mastodon_id.setter
def mastodon_id(self, id): def mastodon_id(self, id_):
self.id = "mastodon:{}@{}".format(id, self.mastodon_instance) self.id = "mastodon:{}@{}".format(id_, self.mastodon_instance)
@decompose_interval('policy_delete_every') @decompose_interval('policy_delete_every')
@ -121,9 +121,10 @@ class Account(TimestampMixin, RemoteIDMixin):
self.next_delete = datetime.now() + value self.next_delete = datetime.now() + value
return value return value
# pylint: disable=R0201
@db.validates('policy_keep_latest') @db.validates('policy_keep_latest')
def validate_empty_string_is_zero(self, key, value): def validate_empty_string_is_zero(self, key, value):
if type(value) == str and value.strip() == '': if isinstance(value, str) and value.strip() == '':
return 0 return 0
return value return value

View File

@ -3,10 +3,8 @@ from flask import render_template, url_for, redirect, request, g, Response,\
from datetime import datetime, timedelta from datetime import datetime, timedelta
import lib.twitter import lib.twitter
import lib.mastodon import lib.mastodon
import lib
from lib.auth import require_auth, require_auth_api, csrf from lib.auth import require_auth, require_auth_api, csrf
from lib import set_session_cookie from lib.session import set_session_cookie, get_viewer_session, get_viewer
from lib import get_viewer_session, get_viewer
from model import Session, TwitterArchive, MastodonApp, MastodonInstance from model import Session, TwitterArchive, MastodonApp, MastodonInstance
from app import app, db, sentry, limiter from app import app, db, sentry, limiter
import tasks import tasks
@ -15,6 +13,7 @@ from twitter import TwitterError
from urllib.error import URLError from urllib.error import URLError
import version import version
import lib.version import lib.version
import lib.brotli
@app.before_request @app.before_request

View File

@ -52,8 +52,8 @@ def noop(*args, **kwargs):
@app.task(autoretry_for=(TwitterError, URLError, MastodonRatelimitError)) @app.task(autoretry_for=(TwitterError, URLError, MastodonRatelimitError))
def fetch_acc(id, cursor=None): def fetch_acc(id_, cursor=None):
acc = Account.query.get(id) acc = Account.query.get(id_)
print(f'fetching {acc}') print(f'fetching {acc}')
try: try:
action = noop action = noop
@ -63,7 +63,7 @@ def fetch_acc(id, cursor=None):
action = lib.mastodon.fetch_acc action = lib.mastodon.fetch_acc
cursor = action(acc, cursor) cursor = action(acc, cursor)
if cursor: if cursor:
fetch_acc.si(id, cursor).apply_async() fetch_acc.si(id_, cursor).apply_async()
finally: finally:
db.session.rollback() db.session.rollback()
acc.touch_fetch() acc.touch_fetch()
@ -188,8 +188,8 @@ def delete_from_account(account_id):
action = lib.twitter.delete action = lib.twitter.delete
posts = refresh_posts(posts) posts = refresh_posts(posts)
if posts: if posts:
eligible = list( # nosec eligible = list(( # nosec
(post for post in posts if post for post in posts if
(not account.policy_keep_favourites or not post.favourite) (not account.policy_keep_favourites or not post.favourite)
and (not account.policy_keep_media or not post.has_media) and (not account.policy_keep_media or not post.has_media)
)) ))