RESPONSIBILTIY'S COOL

This commit is contained in:
codl 2017-08-01 20:57:15 +02:00
parent fffb38bc9a
commit 0f80fc74a0
No known key found for this signature in database
GPG Key ID: 6CD7C8891ED1233A
8 changed files with 142 additions and 20 deletions

View File

@ -1 +1,3 @@
from .auth import require_auth from .auth import require_auth
from .interval import decompose_interval
from .interval import SCALES as interval_scales

50
lib/interval.py Normal file
View File

@ -0,0 +1,50 @@
from datetime import timedelta
SCALES = [
('seconds', timedelta(seconds=1)),
('minutes', timedelta(minutes=1)),
('hours', timedelta(hours=1)),
('days', timedelta(days=1)),
('months', timedelta(days=30)),
('years', timedelta(days=365)),
]
def decompose_interval(attrname):
scales = [scale[1] for scale in SCALES]
scales.reverse()
def decorator(cls):
scl_name = '{}_scale'.format(attrname)
sig_name = '{}_significand'.format(attrname)
@property
def scale(self):
for m in scales:
if getattr(self, attrname) % m == timedelta(0):
return m
return timedelta(seconds=1)
@scale.setter
def scale(self, value):
print(value)
if(type(value) != timedelta):
value = timedelta(seconds=float(value))
print(value)
setattr(self, attrname, getattr(self, sig_name) * value)
@property
def significand(self):
return int(getattr(self, attrname) / getattr(self, scl_name))
@significand.setter
def significand(self, value):
setattr(self, attrname, int(value) * getattr(self, scl_name))
setattr(cls, scl_name, scale)
setattr(cls, sig_name, significand)
return cls
return decorator

View File

@ -0,0 +1,32 @@
"""empty message
Revision ID: 9fab742962ef
Revises: 711770097f06
Create Date: 2017-08-01 00:33:59.183437
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '9fab742962ef'
down_revision = '711770097f06'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('accounts', sa.Column('policy_delete_every', sa.Interval(), server_default='0', nullable=True))
op.add_column('accounts', sa.Column('policy_keep_latest', sa.Integer(), server_default='0', nullable=True))
op.add_column('accounts', sa.Column('policy_keep_younger', sa.Interval(), server_default='0', nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('accounts', 'policy_keep_younger')
op.drop_column('accounts', 'policy_keep_latest')
op.drop_column('accounts', 'policy_delete_every')
# ### end Alembic commands ###

View File

@ -4,6 +4,7 @@ from app import db
from twitter import Twitter, OAuth from twitter import Twitter, OAuth
import secrets import secrets
from lib import decompose_interval
class TimestampMixin(object): class TimestampMixin(object):
created_at = db.Column(db.DateTime, server_default=db.func.now()) created_at = db.Column(db.DateTime, server_default=db.func.now())
@ -33,15 +34,17 @@ class RemoteIDMixin(object):
class Account(db.Model, TimestampMixin, RemoteIDMixin): @decompose_interval('policy_delete_every')
@decompose_interval('policy_keep_younger')
class Account(TimestampMixin, RemoteIDMixin):
__tablename__ = 'accounts' __tablename__ = 'accounts'
id = db.Column(db.String, primary_key=True) id = db.Column(db.String, primary_key=True)
policy_enabled = db.Column(db.Boolean, server_default='FALSE', nullable=False) policy_enabled = db.Column(db.Boolean, server_default='FALSE', nullable=False)
# policy_keep_younger = db.Column(db.Interval) policy_keep_latest = db.Column(db.Integer, server_default='0')
# policy_keep_latest = db.Column(db.Integer)
# policy_delete_every = db.Column(db.Interval)
policy_ignore_favourites = db.Column(db.Boolean, server_default='TRUE') policy_ignore_favourites = db.Column(db.Boolean, server_default='TRUE')
policy_delete_every = db.Column(db.Interval, server_default='0', default=0)
policy_keep_younger = db.Column(db.Interval, server_default='0', default=0)
remote_display_name = db.Column(db.String) remote_display_name = db.Column(db.String)
remote_screen_name = db.Column(db.String) remote_screen_name = db.Column(db.String)
@ -61,6 +64,11 @@ class Account(db.Model, TimestampMixin, RemoteIDMixin):
def post_count(self): def post_count(self):
return Post.query.filter(Post.author_id == self.id).count() return Post.query.filter(Post.author_id == self.id).count()
class Account(Account, db.Model):
pass
class OAuthToken(db.Model, TimestampMixin): class OAuthToken(db.Model, TimestampMixin):
__tablename__ = 'oauth_tokens' __tablename__ = 'oauth_tokens'

View File

@ -2,6 +2,7 @@ from app import app
from flask import render_template, url_for, redirect, request, g, Response from flask import render_template, url_for, redirect, request, g, Response
from datetime import datetime from datetime import datetime
import lib.twitter import lib.twitter
import lib
from lib import require_auth from lib import require_auth
from model import Account, Session, Post, TwitterArchive from model import Account, Session, Post, TwitterArchive
from app import db from app import db
@ -46,7 +47,7 @@ def twitter_login_step2():
db.session.add(session) db.session.add(session)
db.session.commit() db.session.commit()
tasks.fetch_acc.s(token.account_id).delay() tasks.fetch_acc.s(token.account_id).apply_async(routing_key='high')
resp = Response(status=302, headers={"location": url_for('index')}) resp = Response(status=302, headers={"location": url_for('index')})
resp.set_cookie('forget_sid', session.id, resp.set_cookie('forget_sid', session.id,
@ -63,7 +64,7 @@ def upload_tweet_archive():
db.session.add(ta) db.session.add(ta)
db.session.commit() db.session.commit()
tasks.import_twitter_archive.s(ta.id).apply_async() tasks.import_twitter_archive.s(ta.id).apply_async(routing_key='high')
return render_template('upload_tweet_archive.html') return render_template('upload_tweet_archive.html')
@ -71,13 +72,20 @@ def upload_tweet_archive():
@require_auth @require_auth
def settings(): def settings():
if request.method == 'POST': if request.method == 'POST':
for attr in ('policy_enabled', 'policy_ignore_favourites'): for attr in ('policy_enabled',
'policy_ignore_favourites',
'policy_keep_latest',
'policy_delete_every_significand',
'policy_delete_every_scale',
'policy_keep_younger_significand',
'policy_keep_younger_scale',
):
if attr in request.form: if attr in request.form:
setattr(g.viewer.account, attr, request.form[attr]) setattr(g.viewer.account, attr, request.form[attr])
db.session.commit() db.session.commit()
return render_template('settings.html') return render_template('settings.html', scales=lib.interval_scales)

View File

@ -10,8 +10,17 @@ from datetime import timedelta, datetime
from zipfile import ZipFile from zipfile import ZipFile
from io import BytesIO, TextIOWrapper from io import BytesIO, TextIOWrapper
import json import json
from kombu import Queue
app = Celery('tasks', broker=flaskapp.config['CELERY_BROKER'], task_serializer='pickle') app = Celery('tasks', broker=flaskapp.config['CELERY_BROKER'], task_serializer='pickle')
app.conf.task_queues = (
Queue('default', routing_key='celery'),
Queue('high_prio', routing_key='high'),
Queue('higher_prio', routing_key='higher'),
)
app.conf.task_default_queue = 'default'
app.conf.task_default_exchange = 'celery'
app.conf.task_default_exchange_type = 'direct'
@app.task(autoretry_for=(TwitterError, URLError)) @app.task(autoretry_for=(TwitterError, URLError))
def fetch_acc(id, cursor=None): def fetch_acc(id, cursor=None):

View File

@ -0,0 +1,15 @@
{% macro interval_input(obj, attrname, scales) -%}
<input type=number name={{attrname}}_significand
value={{obj[attrname + '_significand']}}
style='max-width:8ch' min=0 step=1>
<select name={{attrname}}_scale>
{%- for scale in scales %}
<option value="{{scale[1].total_seconds()}}"
{{- ' selected' if scale[1] == obj[attrname + '_scale'] -}}
>{{scale[0]}}</option>
{% endfor -%}
</select>
{%- endmacro %}

View File

@ -9,21 +9,19 @@
<label><input type=radio name=policy_enabled value=true {{ "checked" if g.viewer.account.policy_enabled }}> Enabled</label> <label><input type=radio name=policy_enabled value=true {{ "checked" if g.viewer.account.policy_enabled }}> Enabled</label>
<label><input type=radio name=policy_enabled value=false {{ "checked" if not g.viewer.account.policy_enabled }}> Disabled</label> <label><input type=radio name=policy_enabled value=false {{ "checked" if not g.viewer.account.policy_enabled }}> Disabled</label>
</p> </p>
{# {%- from 'lib/interval.html' import interval_input %}
<p>Delete one post every
{{interval_input(g.viewer.account, 'policy_delete_every', scales)}}
</p>
<p>Keep posts less than <p>Keep posts less than
<input type=number name=policy_keep_younger min=0 step=1 max=30> {{interval_input(g.viewer.account, 'policy_keep_younger', scales)}}
<select name=policy_keep_younger_multiplier>
<option name=1>seconds</option>
<option name=60>minutes</option>
<option name=3600>hours</option>
<option name=86400>days</option>
<option name=2635200>months</option>
<option name=31536000>years</option>
</select>
old old
</p> </p>
#} <p>Keep my
<p>Keep posts that you have favourited: <input type=number name=policy_keep_latest min=0 step=1 style='max-width:8ch' value={{g.viewer.account.policy_keep_latest}}>
latest posts
</p>
<p>Keep posts that I have favourited
<label><input type=radio name=policy_ignore_favourites value=true {{ "checked" if g.viewer.account.policy_ignore_favourites }}> Yes</label> <label><input type=radio name=policy_ignore_favourites value=true {{ "checked" if g.viewer.account.policy_ignore_favourites }}> Yes</label>
<label><input type=radio name=policy_ignore_favourites value=false {{ "checked" if not g.viewer.account.policy_ignore_favourites }}> No</label> <label><input type=radio name=policy_ignore_favourites value=false {{ "checked" if not g.viewer.account.policy_ignore_favourites }}> No</label>
</p> </p>