From ac6f7203d88e0906371df27aaa183875517690ec Mon Sep 17 00:00:00 2001
From: codl
Date: Tue, 8 Aug 2017 15:38:54 +0200
Subject: [PATCH] add ability to keep posts with media (close #1)
---
lib/twitter.py | 2 ++
.../versions/04da9abf37e2_add_post_media.py | 27 +++++++++++++++++++
model.py | 17 +++++++++---
routes.py | 1 +
tasks.py | 5 +++-
templates/index.html | 1 +
templates/logged_in.html | 6 +++++
7 files changed, 54 insertions(+), 5 deletions(-)
create mode 100644 migrations/versions/04da9abf37e2_add_post_media.py
diff --git a/lib/twitter.py b/lib/twitter.py
index 8f7e895..4be75b6 100644
--- a/lib/twitter.py
+++ b/lib/twitter.py
@@ -91,6 +91,8 @@ def post_from_api_tweet_object(tweet, post=None):
post.author_id = 'twitter:{}'.format(tweet['user']['id_str'])
if 'favorited' in tweet:
post.favourite = tweet['favorited']
+ if 'entities' in tweet:
+ post.has_media = bool('media' in tweet['entities'] and tweet['entities']['media'])
return post
def fetch_acc(account, cursor, consumer_key=None, consumer_secret=None):
diff --git a/migrations/versions/04da9abf37e2_add_post_media.py b/migrations/versions/04da9abf37e2_add_post_media.py
new file mode 100644
index 0000000..607966f
--- /dev/null
+++ b/migrations/versions/04da9abf37e2_add_post_media.py
@@ -0,0 +1,27 @@
+"""add post media
+
+Revision ID: 04da9abf37e2
+Revises: 2e3a2882e5a4
+Create Date: 2017-08-08 15:15:50.911420
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = '04da9abf37e2'
+down_revision = '2e3a2882e5a4'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ op.add_column('accounts', sa.Column('policy_keep_media', sa.Boolean(), server_default='FALSE', nullable=False))
+ op.add_column('posts', sa.Column('has_media', sa.Boolean(), server_default='FALSE', nullable=False))
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ op.drop_column('posts', 'has_media')
+ op.drop_column('accounts', 'policy_keep_media')
diff --git a/model.py b/model.py
index 448b2eb..88b417c 100644
--- a/model.py
+++ b/model.py
@@ -43,6 +43,7 @@ class Account(TimestampMixin, RemoteIDMixin):
policy_enabled = db.Column(db.Boolean, server_default='FALSE', nullable=False)
policy_keep_latest = db.Column(db.Integer, server_default='100', nullable=False)
policy_keep_favourites = db.Column(db.Boolean, server_default='TRUE', nullable=False)
+ policy_keep_media = db.Column(db.Boolean, server_default='FALSE', nullable=False)
policy_delete_every = db.Column(db.Interval, server_default='30 minutes', nullable=False)
policy_keep_younger = db.Column(db.Interval, server_default='365 days', nullable=False)
@@ -95,6 +96,8 @@ class Account(TimestampMixin, RemoteIDMixin):
filter(~Post.id.in_(latest_n_posts))
if(self.policy_keep_favourites):
query = query.filter_by(favourite = False)
+ if(self.policy_keep_media):
+ query = query.filter_by(has_media = False)
return query.count()
@@ -118,6 +121,8 @@ class OAuthToken(db.Model, TimestampMixin):
# note: account_id is nullable here because we don't know what account a token is for
# until we call /account/verify_credentials with it
+
+
class Session(db.Model, TimestampMixin):
__tablename__ = 'sessions'
@@ -126,6 +131,7 @@ class Session(db.Model, TimestampMixin):
account_id = db.Column(db.String, db.ForeignKey('accounts.id', ondelete='CASCADE', onupdate='CASCADE'), nullable=False)
account = db.relationship(Account, lazy='joined', backref='sessions')
+
class Post(db.Model, TimestampMixin, RemoteIDMixin):
__tablename__ = 'posts'
@@ -137,12 +143,15 @@ class Post(db.Model, TimestampMixin, RemoteIDMixin):
backref=db.backref('posts', order_by=lambda: db.desc(Post.created_at)))
favourite = db.Column(db.Boolean, server_default='FALSE', nullable=False)
+ has_media = db.Column(db.Boolean, server_default='FALSE', nullable=False)
+
+ def snippet(self):
+ if len(self.body) > 20:
+ return self.body[:19] + "✂"
+ return self.body
def __repr__(self):
- snippet = self.body
- if len(snippet) > 20:
- snippet = snippet[:19] + "✂"
- return ''.format(self.id, snippet, self.author_id)
+ return ''.format(self.id, self.snippet(), self.author_id)
class TwitterArchive(db.Model, TimestampMixin):
__tablename__ = 'twitter_archives'
diff --git a/routes.py b/routes.py
index b4b8d2f..a66ea30 100644
--- a/routes.py
+++ b/routes.py
@@ -91,6 +91,7 @@ def settings():
'policy_delete_every_scale',
'policy_keep_younger_significand',
'policy_keep_younger_scale',
+ 'policy_keep_media',
):
try:
if attr in request.form:
diff --git a/tasks.py b/tasks.py
index 4e8772d..9b4a29a 100644
--- a/tasks.py
+++ b/tasks.py
@@ -140,7 +140,10 @@ def delete_from_account(account_id):
posts = refresh_posts(posts)
if account.service == 'twitter':
- eligible = list((post for post in posts if not account.policy_keep_favourites or not post.favourite))
+ eligible = list((post for post in posts if
+ (not account.policy_keep_favourites or not post.favourite)
+ and (not account.policy_keep_media or not post.has_media)
+ ))
if eligible:
if account.policy_delete_every == timedelta(0):
print("deleting all {} eligible posts for {}".format(len(eligible), account))
diff --git a/templates/index.html b/templates/index.html
index bd7d7a5..cefe33f 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -13,6 +13,7 @@
Pick between deleting every old post or randomly deleting one old post periodically
Pick between deleting posts older than a date, posts past a post count, or both
Optionally mark posts that you want to preserve forever, by giving them a like
+ Optionally keep posts with media forever
Upload a tweet archive if your twitter account has more tweets than the twitter api will return
Free and Open Source software
diff --git a/templates/logged_in.html b/templates/logged_in.html
index 3ae3879..c248e8c 100644
--- a/templates/logged_in.html
+++ b/templates/logged_in.html
@@ -56,6 +56,12 @@
No
+Posts that have media attached will stay fresh forever
+
+ Yes
+ No
+
+
Any post that is not kept fresh by any of these rules is considered expired. One random expired post will be deleted every
{{interval_input(g.viewer.account, 'policy_delete_every', scales)}}