refactor model #3
5 changed files with 66 additions and 93 deletions
|
@ -2,7 +2,7 @@
|
||||||
import click
|
import click
|
||||||
|
|
||||||
from BDSM import app, db
|
from BDSM import app, db
|
||||||
from BDSM.models import Settings, Toot, Other
|
from BDSM.models import Settings, Toot
|
||||||
from BDSM.toot import app_login, toot_process
|
from BDSM.toot import app_login, toot_process
|
||||||
from mastodon import MastodonNotFoundError
|
from mastodon import MastodonNotFoundError
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ def initdb(drop):
|
||||||
@app.cli.command()
|
@app.cli.command()
|
||||||
def analysis():
|
def analysis():
|
||||||
"""Analysis current Year"""
|
"""Analysis current Year"""
|
||||||
from BDSM.models import Toot, Other
|
from BDSM.models import Toot
|
||||||
from sqlalchemy.sql import extract
|
from sqlalchemy.sql import extract
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
from sqlalchemy import desc
|
from sqlalchemy import desc
|
||||||
|
@ -42,8 +42,8 @@ def analysis():
|
||||||
)
|
)
|
||||||
|
|
||||||
print("2022 年互动最多帐号排名" +
|
print("2022 年互动最多帐号排名" +
|
||||||
str(db.session.query(Other.acct.label('count'),func.count('count')
|
str(db.session.query(Toot.acct.label('count'),func.count('count')
|
||||||
).filter(extract('year', Other.created_at) == 2022
|
).filter(extract('year', Toot.created_at) == 2022
|
||||||
).group_by('count'
|
).group_by('count'
|
||||||
).order_by(desc(func.count('count'))
|
).order_by(desc(func.count('count'))
|
||||||
).all()[:3])
|
).all()[:3])
|
||||||
|
@ -193,17 +193,15 @@ def renderfile():
|
||||||
def graball():
|
def graball():
|
||||||
"""Grab all toots context"""
|
"""Grab all toots context"""
|
||||||
settings = Settings.query.first()
|
settings = Settings.query.first()
|
||||||
account = settings.account[1:]
|
domain = settings.domain
|
||||||
username, domain = account.split("@")
|
|
||||||
url = "https://" + domain
|
url = "https://" + domain
|
||||||
mastodon, user = app_login(url)
|
mastodon, _ = app_login(url)
|
||||||
acct = mastodon.me().acct
|
acct = mastodon.me().acct
|
||||||
|
|
||||||
toots = Toot.query.filter(Toot.in_reply_to_id.isnot(None)).all()
|
toots = Toot.query.filter(Toot.in_reply_to_id.isnot(None)).all()
|
||||||
toots_id = []
|
toots_id = []
|
||||||
for i in toots:
|
for i in toots:
|
||||||
if (Toot.query.get(i.in_reply_to_id) != None
|
if (Toot.query.get(i.in_reply_to_id) != None):
|
||||||
or Other.query.get(i.in_reply_to_id) != None):
|
|
||||||
continue
|
continue
|
||||||
#context api excluding itself
|
#context api excluding itself
|
||||||
toots_id.append(i.id)
|
toots_id.append(i.id)
|
||||||
|
|
|
@ -26,29 +26,6 @@ class Toot(db.Model):
|
||||||
favourites_count = db.Column(db.Integer)
|
favourites_count = db.Column(db.Integer)
|
||||||
language = db.Column(db.Text)
|
language = db.Column(db.Text)
|
||||||
|
|
||||||
class Other(db.Model):
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
|
||||||
acct = db.Column(db.Text)
|
|
||||||
url = db.Column(db.Text)
|
|
||||||
created_at = db.Column(db.DateTime)
|
|
||||||
edited_at = db.Column(db.DateTime)
|
|
||||||
in_reply_to_id = db.Column(db.Integer)
|
|
||||||
in_reply_to_account_id = db.Column(db.Integer)
|
|
||||||
content = db.Column(db.Text)
|
|
||||||
media_list = db.Column(db.Text)
|
|
||||||
emoji_list = db.Column(db.Text)
|
|
||||||
spoiler_text = db.Column(db.Text)
|
|
||||||
poll_id = db.Column(db.Integer)
|
|
||||||
visibility = db.Column(db.Text)
|
|
||||||
reblogged = db.Column(db.Boolean)
|
|
||||||
favourited = db.Column(db.Boolean)
|
|
||||||
bookmarked = db.Column(db.Boolean)
|
|
||||||
sensitive = db.Column(db.Boolean)
|
|
||||||
replies_count = db.Column(db.Integer)
|
|
||||||
reblogs_count = db.Column(db.Integer)
|
|
||||||
favourites_count = db.Column(db.Integer)
|
|
||||||
language = db.Column(db.Text)
|
|
||||||
|
|
||||||
class Tag(db.Model):
|
class Tag(db.Model):
|
||||||
__table_args__ = {'sqlite_autoincrement': True}
|
__table_args__ = {'sqlite_autoincrement': True}
|
||||||
tag_id = db.Column(db.Integer, primary_key=True)
|
tag_id = db.Column(db.Integer, primary_key=True)
|
||||||
|
@ -79,6 +56,7 @@ class Poll(db.Model):
|
||||||
options = db.Column(db.Text)
|
options = db.Column(db.Text)
|
||||||
|
|
||||||
class Settings(db.Model):
|
class Settings(db.Model):
|
||||||
account = db.Column(db.Text, primary_key=True)
|
domain = db.Column(db.Text, primary_key=True)
|
||||||
|
account = db.Column(db.Text)
|
||||||
timezone = db.Column(db.Text)
|
timezone = db.Column(db.Text)
|
||||||
setup = db.Column(db.Boolean)
|
setup = db.Column(db.Boolean)
|
||||||
|
|
|
@ -4,13 +4,12 @@
|
||||||
<h3>设置</h3>
|
<h3>设置</h3>
|
||||||
<form method="post" class="form-horizontal" role="form">
|
<form method="post" class="form-horizontal" role="form">
|
||||||
{% if settings != None %}
|
{% if settings != None %}
|
||||||
<div class="form-group">
|
<br>
|
||||||
<label class="col-sm-2 control-label">用户名</label>
|
<h4>站点地址:</h4>
|
||||||
<div class="col-sm-10">
|
<p> {{ settings.domain }} </p>
|
||||||
<input type="text" class="form-control" name="account" autocomplete="off" required
|
<br>
|
||||||
value="{{ settings.account }}">
|
<h4>用户名:</h4>
|
||||||
</div>
|
<p> {{ settings.account }} </p>
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-2 control-label">时区</label>
|
<label class="col-sm-2 control-label">时区</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
|
@ -24,9 +23,9 @@
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-2 control-label">用户名</label>
|
<label class="col-sm-2 control-label">站点地址</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" name="account" autocomplete="off" required value="@用户名@实例">
|
<input type="text" class="form-control" name="domain" autocomplete="off" required value="例如:mastodon.social">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
18
BDSM/toot.py
18
BDSM/toot.py
|
@ -3,7 +3,7 @@
|
||||||
from mastodon import Mastodon
|
from mastodon import Mastodon
|
||||||
from tenacity import *
|
from tenacity import *
|
||||||
from BDSM import db
|
from BDSM import db
|
||||||
from BDSM.models import Other, Toot, Tag, Media, Emoji, Poll
|
from BDSM.models import Toot, Tag, Media, Emoji, Poll, Settings
|
||||||
import sys
|
import sys
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
|
|
||||||
|
@ -40,8 +40,9 @@ def app_login(url):
|
||||||
return mastodon, user
|
return mastodon, user
|
||||||
|
|
||||||
def get_context(url, toot_id):
|
def get_context(url, toot_id):
|
||||||
mastodon, user = app_login(url)
|
mastodon, _ = app_login(url)
|
||||||
acct = mastodon.me().acct
|
settings = Settings.query.first()
|
||||||
|
acct = settings.account
|
||||||
context = mastodon.status_context(toot_id)
|
context = mastodon.status_context(toot_id)
|
||||||
statuses = []
|
statuses = []
|
||||||
statuses= context['ancestors'] + context['descendants']
|
statuses= context['ancestors'] + context['descendants']
|
||||||
|
@ -52,7 +53,6 @@ def get_context(url, toot_id):
|
||||||
def toot_process(statuses, my_acct, duplicates_counter=0):
|
def toot_process(statuses, my_acct, duplicates_counter=0):
|
||||||
for status in statuses:
|
for status in statuses:
|
||||||
is_reblog = False
|
is_reblog = False
|
||||||
is_myself = False
|
|
||||||
if status['reblog'] != None:
|
if status['reblog'] != None:
|
||||||
if my_acct == status['reblog']['account']['acct']:
|
if my_acct == status['reblog']['account']['acct']:
|
||||||
reblog_myself = True
|
reblog_myself = True
|
||||||
|
@ -78,11 +78,6 @@ def toot_process(statuses, my_acct, duplicates_counter=0):
|
||||||
id = status['id']
|
id = status['id']
|
||||||
|
|
||||||
acct = status['account']['acct']
|
acct = status['account']['acct']
|
||||||
if my_acct == acct:
|
|
||||||
is_myself = True
|
|
||||||
else:
|
|
||||||
is_myself = False
|
|
||||||
|
|
||||||
url = status['url']
|
url = status['url']
|
||||||
created_at = status['created_at']
|
created_at = status['created_at']
|
||||||
|
|
||||||
|
@ -181,9 +176,6 @@ def toot_process(statuses, my_acct, duplicates_counter=0):
|
||||||
favourites_count = status['favourites_count']
|
favourites_count = status['favourites_count']
|
||||||
language = status['language']
|
language = status['language']
|
||||||
|
|
||||||
if is_reblog or not is_myself:
|
|
||||||
table = Other()
|
|
||||||
else:
|
|
||||||
table = Toot()
|
table = Toot()
|
||||||
|
|
||||||
table.id=id
|
table.id=id
|
||||||
|
@ -208,7 +200,7 @@ def toot_process(statuses, my_acct, duplicates_counter=0):
|
||||||
table.favourites_count=favourites_count
|
table.favourites_count=favourites_count
|
||||||
table.language=language
|
table.language=language
|
||||||
|
|
||||||
if Toot.query.get(id) != None or Other.query.get(id) != None:
|
if Toot.query.get(id) != None:
|
||||||
duplicates_counter += 1
|
duplicates_counter += 1
|
||||||
|
|
||||||
db.session.merge(table)
|
db.session.merge(table)
|
||||||
|
|
|
@ -5,9 +5,10 @@ import json
|
||||||
|
|
||||||
from flask import render_template, request, url_for, redirect, flash, abort
|
from flask import render_template, request, url_for, redirect, flash, abort
|
||||||
from flask_sqlalchemy import Pagination
|
from flask_sqlalchemy import Pagination
|
||||||
|
from sqlalchemy import or_
|
||||||
from BDSM import app, db
|
from BDSM import app, db
|
||||||
from BDSM.models import Media, Poll, Settings, Toot, Emoji, Other
|
from BDSM.models import Media, Poll, Settings, Toot, Emoji
|
||||||
from BDSM.toot import app_register, archive_toot, get_context
|
from BDSM.toot import app_login, app_register, archive_toot, get_context
|
||||||
from mastodon import Mastodon
|
from mastodon import Mastodon
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
from datetime import timezone
|
from datetime import timezone
|
||||||
|
@ -24,7 +25,7 @@ def index():
|
||||||
return redirect(url_for('settings'))
|
return redirect(url_for('settings'))
|
||||||
else:
|
else:
|
||||||
page = request.args.get('page', 1, type=int)
|
page = request.args.get('page', 1, type=int)
|
||||||
toots_ = Toot.query.order_by(Toot.created_at.desc()).paginate(page=page, per_page=50)
|
toots_ = Toot.query.order_by(Toot.created_at.desc()).filter(or_(Toot.acct==settings.account, Toot.reblog_id!=None)).paginate(page=page, per_page=50)
|
||||||
toots = process_toot(toots_)
|
toots = process_toot(toots_)
|
||||||
path=SimpleNamespace()
|
path=SimpleNamespace()
|
||||||
path.path = "index"
|
path.path = "index"
|
||||||
|
@ -32,6 +33,21 @@ def index():
|
||||||
|
|
||||||
return render_template('view.html', toots=toots, pagination=toots_, path=path)
|
return render_template('view.html', toots=toots, pagination=toots_, path=path)
|
||||||
|
|
||||||
|
@app.route('/favourited', methods=['GET', 'POST'])
|
||||||
|
def favourited():
|
||||||
|
settings = Settings.query.first()
|
||||||
|
if settings == None:
|
||||||
|
return redirect(url_for('settings'))
|
||||||
|
else:
|
||||||
|
page = request.args.get('page', 1, type=int)
|
||||||
|
toots_ = Toot.query.order_by(Toot.created_at.desc()).paginate(page=page, per_page=50)
|
||||||
|
toots = process_toot(toots_)
|
||||||
|
path=SimpleNamespace()
|
||||||
|
path.path = "favourited"
|
||||||
|
path.args = {}
|
||||||
|
|
||||||
|
return render_template('view.html', toots=toots, pagination=toots_, path=path)
|
||||||
|
|
||||||
@app.route('/search', methods=['GET', 'POST'])
|
@app.route('/search', methods=['GET', 'POST'])
|
||||||
def search():
|
def search():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
@ -55,8 +71,6 @@ def search():
|
||||||
def context(toot_id):
|
def context(toot_id):
|
||||||
def get_reply(reply_id):
|
def get_reply(reply_id):
|
||||||
toots = Toot.query.order_by(Toot.created_at.desc()).filter_by(in_reply_to_id=reply_id).all()
|
toots = Toot.query.order_by(Toot.created_at.desc()).filter_by(in_reply_to_id=reply_id).all()
|
||||||
other_toots = Other.query.order_by(Other.created_at.desc()).filter_by(in_reply_to_id=reply_id).all()
|
|
||||||
toots = process_toot(toots) + process_toot(other_toots)
|
|
||||||
|
|
||||||
for i in toots:
|
for i in toots:
|
||||||
if i.in_reply_to_id != None:
|
if i.in_reply_to_id != None:
|
||||||
|
@ -67,8 +81,6 @@ def context(toot_id):
|
||||||
toots = []
|
toots = []
|
||||||
|
|
||||||
toot_ = Toot.query.get(toot_id)
|
toot_ = Toot.query.get(toot_id)
|
||||||
if toot_ == None:
|
|
||||||
toot_ = Other.query.get(toot_id)
|
|
||||||
if toot_ == None:
|
if toot_ == None:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
|
@ -80,8 +92,6 @@ def context(toot_id):
|
||||||
while(in_reply_to_id != None):
|
while(in_reply_to_id != None):
|
||||||
toot = []
|
toot = []
|
||||||
toot_ = Toot.query.get(toots[0].in_reply_to_id)
|
toot_ = Toot.query.get(toots[0].in_reply_to_id)
|
||||||
if toot_ == None:
|
|
||||||
toot_ = Other.query.get(toots[0].in_reply_to_id)
|
|
||||||
if toot_ == None:
|
if toot_ == None:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -95,8 +105,7 @@ def context(toot_id):
|
||||||
@app.route('/grab/<int:toot_id>', methods=['GET', 'POST'])
|
@app.route('/grab/<int:toot_id>', methods=['GET', 'POST'])
|
||||||
def grab(toot_id):
|
def grab(toot_id):
|
||||||
settings = Settings.query.first()
|
settings = Settings.query.first()
|
||||||
account = settings.account[1:]
|
domain = settings.domain
|
||||||
username, domain = account.split("@")
|
|
||||||
url = "https://" + domain
|
url = "https://" + domain
|
||||||
|
|
||||||
get_context(url, toot_id)
|
get_context(url, toot_id)
|
||||||
|
@ -106,20 +115,18 @@ def grab(toot_id):
|
||||||
@app.route('/settings', methods=['GET', 'POST'])
|
@app.route('/settings', methods=['GET', 'POST'])
|
||||||
def settings():
|
def settings():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
account = request.form['account']
|
|
||||||
timezone = request.form['timezone']
|
timezone = request.form['timezone']
|
||||||
|
settings = Settings.query.first()
|
||||||
|
if settings == None:
|
||||||
|
domain = request.form['domain']
|
||||||
|
|
||||||
if not account or len(account) > 30:
|
if not domain or len(domain) > 50:
|
||||||
flash('无效输入')
|
flash('无效输入')
|
||||||
return redirect(url_for('settings'))
|
return redirect(url_for('settings'))
|
||||||
|
|
||||||
settings = Settings.query.first()
|
settings = Settings(domain=domain, timezone=timezone)
|
||||||
|
|
||||||
if settings == None:
|
|
||||||
settings = Settings(account=account, timezone=timezone)
|
|
||||||
db.session.add(settings)
|
db.session.add(settings)
|
||||||
else:
|
else:
|
||||||
settings.account = account
|
|
||||||
settings.timezone = timezone
|
settings.timezone = timezone
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -137,13 +144,17 @@ def settings():
|
||||||
def register():
|
def register():
|
||||||
settings = Settings.query.first()
|
settings = Settings.query.first()
|
||||||
if settings == None:
|
if settings == None:
|
||||||
flash('请先输入用户名!')
|
flash('请先输入站点地址!')
|
||||||
return redirect(url_for('settings'))
|
return redirect(url_for('settings'))
|
||||||
else:
|
else:
|
||||||
account = settings.account[1:]
|
domain = settings.domain
|
||||||
username, domain = account.split("@")
|
|
||||||
url = "https://" + domain
|
url = "https://" + domain
|
||||||
|
|
||||||
|
mastodon, _ = app_login(url)
|
||||||
|
account = mastodon.me().acct
|
||||||
|
settings.account = account
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
token = request.form['token'].rstrip()
|
token = request.form['token'].rstrip()
|
||||||
mastodon = Mastodon(client_id='pyBDSM_clientcred.secret', api_base_url=url)
|
mastodon = Mastodon(client_id='pyBDSM_clientcred.secret', api_base_url=url)
|
||||||
|
@ -168,8 +179,7 @@ def archive():
|
||||||
settings = Settings.query.first()
|
settings = Settings.query.first()
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
archive_match = request.form.getlist("archive_match")
|
archive_match = request.form.getlist("archive_match")
|
||||||
account = settings.account[1:]
|
domain = settings.domain
|
||||||
username, domain = account.split("@")
|
|
||||||
url = "https://" + domain
|
url = "https://" + domain
|
||||||
archive_toot(url, archive_match)
|
archive_toot(url, archive_match)
|
||||||
|
|
||||||
|
@ -196,19 +206,15 @@ def process_toot(toots_):
|
||||||
toot.created_at = toot.created_at.replace(tzinfo=timezone.utc)
|
toot.created_at = toot.created_at.replace(tzinfo=timezone.utc)
|
||||||
toot.created_at = toot.created_at.astimezone(user_timezone).strftime(fmt)
|
toot.created_at = toot.created_at.astimezone(user_timezone).strftime(fmt)
|
||||||
|
|
||||||
if hasattr(toot, 'reblog_id'):
|
if toot.acct == settings.account:
|
||||||
toot.is_myself = True
|
toot.is_myself = True
|
||||||
|
else:
|
||||||
|
toot.is_myself = False
|
||||||
|
|
||||||
if toot.reblog_id != None:
|
if toot.reblog_id != None:
|
||||||
if toot.reblog_myself:
|
|
||||||
toot = Toot.query.get(toot.reblog_id)
|
toot = Toot.query.get(toot.reblog_id)
|
||||||
toot = SimpleNamespace(**toot.__dict__)
|
toot = SimpleNamespace(**toot.__dict__)
|
||||||
toot.is_reblog = True
|
toot.is_reblog = True
|
||||||
else:
|
|
||||||
toot = Other.query.get(toot.reblog_id)
|
|
||||||
toot = SimpleNamespace(**toot.__dict__)
|
|
||||||
toot.is_reblog = True
|
|
||||||
else:
|
|
||||||
toot.is_myself = False
|
|
||||||
|
|
||||||
if toot.media_list != "":
|
if toot.media_list != "":
|
||||||
toot.medias = []
|
toot.medias = []
|
||||||
|
|
Loading…
Reference in a new issue