Saved posts + YT search + YT follow manager
This commit is contained in:
parent
9f4cf189c7
commit
14392660ff
@ -1 +1 @@
|
||||
{"twitter": [{"username": "aantonop"}, {"username": "Trezor"}, {"username": "aitor13023985"}, {"username": "guaridadelzorro"}, {"username": "elonmusk"}, {"username": "bitcoin"}, {"username": "monero"}, {"username": "xmroutreach"}, {"username": "Locha_io"}, {"username": "randybrito"}, {"username": "btcven"}, {"username": "Snowden"}, {"username": "_prestwich"}, {"username": "TradeOnFire"}], "youtube": [{"channelId": "UCjr2bPAyPV7t35MvcgT3W8Q"}, {"channelId": "UCJWCJCWOxBYSi5DhCieLOLQ"}, {"channelId": "UCW3iqZr2cQFYKdO9Kpa97Yw"}, {"channelId": "UCLXo7UDZvByw2ixzpQCufnA"}, {"channelId": "UCR9sFzaG9Ia_kXJhfxtFMBA"}, {"channelId": "UCbdSYaPD-lr1kW27UJuk8Pw"}, {"channelId": "UCa3DVlGH2_QhvwuWlPa6MDQ"}, {"channelId": "UComoqWnjQlH7JpvqfyGnWNA"}, {"channelId": "UCA58hhLv4pdgDjBW5oNSklA"}]}
|
||||
{"twitter": [{"username": "aantonop"}, {"username": "Trezor"}, {"username": "aitor13023985"}, {"username": "guaridadelzorro"}, {"username": "elonmusk"}, {"username": "bitcoin"}, {"username": "monero"}, {"username": "xmroutreach"}, {"username": "Locha_io"}, {"username": "randybrito"}, {"username": "btcven"}, {"username": "Snowden"}, {"username": "_prestwich"}, {"username": "TradeOnFire"}], "youtube": [{"channelId": "UCjr2bPAyPV7t35MvcgT3W8Q"}, {"channelId": "UCJWCJCWOxBYSi5DhCieLOLQ"}, {"channelId": "UCW3iqZr2cQFYKdO9Kpa97Yw"}, {"channelId": "UCLXo7UDZvByw2ixzpQCufnA"}, {"channelId": "UCR9sFzaG9Ia_kXJhfxtFMBA"}, {"channelId": "UCbdSYaPD-lr1kW27UJuk8Pw"}, {"channelId": "UCa3DVlGH2_QhvwuWlPa6MDQ"}, {"channelId": "UComoqWnjQlH7JpvqfyGnWNA"}, {"channelId": "UCA58hhLv4pdgDjBW5oNSklA"}, {"channelId": "UCkHR9m-tscD3ojD7_viIfTA"}, {"channelId": "UCYO_jab_esuFRV4b17AJtAw"}, {"channelId": "UC9-y-6csu5WGm29I7JiwpnA"}, {"channelId": "UC2PA-AKmVpU6NKCGtZq_rKQ"}, {"channelId": "UC2Qc22WUjL_GbBDIPvmHWmQ"}, {"channelId": "UC3Hx81QYLoEQkm3vyl4N4eQ"}, {"channelId": "UCiwy9Lx6h1Oi-UYwYDbgBZA"}, {"channelId": "UCHW_zn-nX5nvMjEA6mtNZ1A"}]}
|
@ -15,8 +15,8 @@ class SearchForm(FlaskForm):
|
||||
submit = SubmitField('Search')
|
||||
|
||||
class ChannelForm(FlaskForm):
|
||||
channelId = StringField('Channel ID')
|
||||
submit = SubmitField('Follow')
|
||||
channelId = StringField('')
|
||||
submit = SubmitField('Search')
|
||||
|
||||
|
||||
class RegistrationForm(FlaskForm):
|
||||
|
@ -29,6 +29,7 @@ class User(UserMixin, db.Model):
|
||||
def check_password(self, password):
|
||||
return check_password_hash(self.password_hash, password)
|
||||
|
||||
# TWITTER
|
||||
def follow(self, user):
|
||||
if not self.is_following(user):
|
||||
self.followed.append(user)
|
||||
@ -47,9 +48,21 @@ class User(UserMixin, db.Model):
|
||||
def saved_posts(self):
|
||||
return Post.query.filter_by(user_id=self.id)
|
||||
|
||||
# YOUTUBE
|
||||
def youtube_following_list(self):
|
||||
return self.youtubeFollowed.all()
|
||||
|
||||
def is_following_yt(self, cid):
|
||||
temp_cid = invidiousFollow.query.filter_by(channelId = cid).first()
|
||||
if temp_cid is None:
|
||||
return False
|
||||
else:
|
||||
following = self.youtube_following_list()
|
||||
for f in following:
|
||||
if f.channelId == cid:
|
||||
return True
|
||||
return False
|
||||
|
||||
followed = db.relationship(
|
||||
'User', secondary=followers,
|
||||
primaryjoin=(followers.c.follower_id == id),
|
||||
@ -88,6 +101,7 @@ class invidiousPost():
|
||||
videoThumb = '#'
|
||||
description = "LOREM IPSUM"
|
||||
date = 'None'
|
||||
views = 'NaN'
|
||||
|
||||
|
||||
class invidiousFollow(db.Model):
|
||||
|
@ -146,6 +146,29 @@ def invidious():
|
||||
videos.sort(key=lambda x: x.date, reverse=True)
|
||||
return render_template('invidious.html', videos=videos, form=form)
|
||||
|
||||
@app.route('/ytsearch', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def ytsearch():
|
||||
form = ChannelForm()
|
||||
button_form = EmptyForm()
|
||||
if form.validate_on_submit():
|
||||
channelId = form.channelId.data
|
||||
r = requests.get('https://invidio.us/api/v1/search?type=channel&q={}'.format(channelId))
|
||||
if r.status_code == 200:
|
||||
results = json.loads(r.content)
|
||||
channels = []
|
||||
for res in results:
|
||||
channels.append({
|
||||
'username':res['author'],
|
||||
'channelId':res['authorId'],
|
||||
'thumbnail':res['authorThumbnails'][0]['url'],
|
||||
'subCount':letterify(res['subCount'])
|
||||
})
|
||||
|
||||
return render_template('ytsearch.html', form=form, btform=button_form, results=channels)
|
||||
else:
|
||||
return render_template('ytsearch.html', form=form)
|
||||
|
||||
@app.route('/savePost/<url>', methods=['POST'])
|
||||
@login_required
|
||||
def savePost(url):
|
||||
@ -181,6 +204,43 @@ def deleteSaved(id):
|
||||
db.session.commit()
|
||||
return redirect(url_for('saved'))
|
||||
|
||||
@app.route('/ytfollow/<channelId>', methods=['POST'])
|
||||
@login_required
|
||||
def ytfollow(channelId):
|
||||
form = EmptyForm()
|
||||
if form.validate_on_submit():
|
||||
channel = invidiousFollow.query.filter_by(channelId=channelId).first()
|
||||
if requests.get('https://invidio.us/feed/channel/{}'.format(channelId)).status_code == 200:
|
||||
if channel is None:
|
||||
follow = invidiousFollow()
|
||||
follow.channelId = channelId
|
||||
follow.followers.append(current_user)
|
||||
try:
|
||||
db.session.add(follow)
|
||||
db.session.commit()
|
||||
except:
|
||||
flash("Something went wrong. Try again!")
|
||||
return redirect(url_for('invidious'))
|
||||
flash('You are following {}!'.format(channelId))
|
||||
else:
|
||||
flash("Something went wrong... try again")
|
||||
return redirect(url_for('ytsearch'))
|
||||
else:
|
||||
return redirect(url_for('ytsearch'))
|
||||
|
||||
@app.route('/ytunfollow/<channelId>', methods=['POST'])
|
||||
@login_required
|
||||
def ytunfollow(channelId):
|
||||
form = EmptyForm()
|
||||
channel = invidiousFollow.query.filter_by(channelId=channelId).first()
|
||||
try:
|
||||
db.session.delete(channel)
|
||||
db.session.commit()
|
||||
flash("User unfollowed!")
|
||||
except:
|
||||
flash("There was an error unfollowing the user. Try again.")
|
||||
return redirect(url_for('ytsearch'))
|
||||
|
||||
@app.route('/follow/<username>', methods=['POST'])
|
||||
@login_required
|
||||
def follow(username):
|
||||
@ -412,7 +472,27 @@ def getInvidiousPosts(ids):
|
||||
video.videoUrl = vid.link
|
||||
video.videoTitle = vid.title
|
||||
video.videoThumb = vid.media_thumbnail[0]['url']
|
||||
video.views = vid.media_statistics['views']
|
||||
video.description = vid.summary.split('<p style="word-break:break-word;white-space:pre-wrap">')[1]
|
||||
video.description = re.sub(r'^https?:\/\/.*[\r\n]*', '', video.description[0:120]+"...", flags=re.MULTILINE)
|
||||
videos.append(video)
|
||||
return videos
|
||||
|
||||
def letterify(number):
|
||||
order = len(str(number))
|
||||
if order == 4:
|
||||
subCount = "{k}.{c}k".format(k=str(number)[0:1], c=str(number)[1:2])
|
||||
elif order == 5:
|
||||
subCount = "{k}.{c}k".format(k=str(number)[0:2], c=str(number)[2:3])
|
||||
elif order == 6:
|
||||
subCount = "{k}.{c}k".format(k=str(number)[0:3], c=str(number)[3:4])
|
||||
elif order == 7:
|
||||
subCount = "~{M}M".format(M=str(number)[0:1])
|
||||
elif order == 8:
|
||||
subCount = "~{M}M".format(M=str(number)[0:2])
|
||||
elif order >= 8:
|
||||
subCount = "{M}M".format(M=str(number)[0:3])
|
||||
else:
|
||||
subCount = str(number)
|
||||
|
||||
return subCount
|
@ -20,7 +20,7 @@
|
||||
</div>
|
||||
<div class="extra content">
|
||||
<p>
|
||||
<form class="ui form" action="{{ url_for('savePost', url=post.urlToPost.replace('/', '~')) }}" method="post">
|
||||
<form class="ui form" action="{{ url_for('savePost', url=post.url.replace('/', '~')) }}" method="post">
|
||||
<button type="submit" class="ui icon button">
|
||||
<i class="bookmark outline icon"></i>
|
||||
</button>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<p>{{post.content}}</p>
|
||||
</div>
|
||||
<div class="extra content">
|
||||
<form class="ui form" action="{{ url_for('savePost', url=post.urlToPost.replace('/', '~')) }}" method="post">
|
||||
<form class="ui form" action="{{ url_for('savePost', url=post.url.replace('/', '~')) }}" method="post">
|
||||
<button type="submit" class="ui icon button">
|
||||
<i class="bookmark outline icon"></i>
|
||||
</button>
|
||||
|
@ -12,13 +12,17 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="extra content">
|
||||
<span class="right floated">
|
||||
<i class="eye icon"></i>
|
||||
{{video.views}}
|
||||
</span>
|
||||
<span class="right floated">
|
||||
<i class="clock icon"></i>
|
||||
{{video.timeStamp}}
|
||||
{{video.timeStamp}}
|
||||
</span>
|
||||
<span>
|
||||
<a href="{{video.videoUrl}}">
|
||||
<i class="eye icon"></i>
|
||||
<i class="share square outline icon"></i>
|
||||
Open
|
||||
</a>
|
||||
</span>
|
||||
|
@ -38,6 +38,7 @@
|
||||
<a href="{{ url_for('following') }}" class="twitter item">Following</a>
|
||||
<a href="{{ url_for('saved') }}" class="twitter item">Saved</a>
|
||||
<a href="{{ url_for('invidious') }}" class="youtube item">Youtube</a>
|
||||
<a href="{{ url_for('ytsearch') }}" class="youtube item">Search</a>
|
||||
<a href="{{ url_for('logout') }}" class="item">Logout</a>
|
||||
<a href="{{ url_for('settings') }}" class="item"><i class="cog icon"></i></a>
|
||||
{% endif %}
|
||||
|
53
app/templates/ytsearch.html
Normal file
53
app/templates/ytsearch.html
Normal file
@ -0,0 +1,53 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="ui one column centered grid">
|
||||
<form class="ui form" action="" method="post" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
<p>
|
||||
{{ form.channelId.label }}<br>
|
||||
{{ form.channelId(size=32) }}<br>
|
||||
{% for error in form.channelId.errors %}
|
||||
<span style="color: red;">[{{ error }}]</span>
|
||||
{% endfor %}
|
||||
</p>
|
||||
<p>{{ form.submit() }}</p>
|
||||
</form>
|
||||
|
||||
{% if results %}
|
||||
<div class="ui one column centered grid">
|
||||
<div class="ui middle aligned divided list">
|
||||
{% for res in results %}
|
||||
<div class="item">
|
||||
<div class="right floated content">
|
||||
{% if not current_user.is_following_yt(res.channelId) %}
|
||||
<p>
|
||||
<form action="{{ url_for('ytfollow', channelId=res.channelId) }}" method="post">
|
||||
{{ btform.hidden_tag() }}
|
||||
{{ btform.submit(value='Follow') }}
|
||||
</form>
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
<form action="{{ url_for('ytunfollow', channelId=res.channelId) }}" method="post">
|
||||
{{ btform.hidden_tag() }}
|
||||
{{ btform.submit(value='Unfollow') }}
|
||||
</form>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<img class="ui avatar image" src="{{ res.thumbnail }}">
|
||||
<div class="content">
|
||||
{{res.username}}
|
||||
<div class="ui label">
|
||||
<i class="user icon"></i> {{res.subCount}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
Reference in New Issue
Block a user