Add cited tweets to user feeds

This commit is contained in:
pluja 2020-09-01 21:03:51 +02:00
parent 12895b2eb0
commit 38746cc0d3
32 changed files with 139 additions and 60111 deletions

BIN
app/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -553,7 +553,7 @@ def getFeed(urls):
for post in userFeed[:-1]: for post in userFeed[:-1]:
date_time_str = post.find('span', attrs={'class':'tweet-date'}).find('a')['title'].replace(",","") date_time_str = post.find('span', attrs={'class':'tweet-date'}).find('a')['title'].replace(",","")
time = datetime.datetime.now() - datetime.datetime.strptime(date_time_str, '%d/%m/%Y %H:%M:%S') time = datetime.datetime.now() - datetime.datetime.strptime(date_time_str, '%d/%m/%Y %H:%M:%S')
if time.days >= 11: if time.days >=8:
continue continue
if post.find('div', attrs={'class':'pinned'}): if post.find('div', attrs={'class':'pinned'}):
@ -596,41 +596,59 @@ def getFeed(urls):
return feedPosts return feedPosts
def getPosts(account): def getPosts(account):
avatarPath = "img/avatars/{}.png".format(str(random.randint(1,12))) feedPosts = []
posts = []
#Gather profile info. #Gather profile info.
rssFeed = feedparser.parse('{instance}{user}/rss'.format(instance=NITTERINSTANCE, user=account)) rssFeed = urllib.request.urlopen('{instance}{user}'.format(instance=NITTERINSTANCE, user=account)).read()
#Gather posts #Gather feedPosts
if rssFeed.entries != []: res = rssFeed.decode('utf-8')
for post in rssFeed.entries: html = BeautifulSoup(res, "html.parser")
newPost = twitterPost() userFeed = html.find_all('div', attrs={'class':'timeline-item'})
newPost.username = rssFeed.feed.title.split("/")[1].replace(" ", "") if userFeed != []:
newPost.twitterName = rssFeed.feed.title.split("/")[0] for post in userFeed[:-1]:
newPost.date = getTimeDiff(post.published_parsed) date_time_str = post.find('span', attrs={'class':'tweet-date'}).find('a')['title'].replace(",","")
newPost.timeStamp = datetime.datetime(*post.published_parsed[:6]) time = datetime.datetime.now() - datetime.datetime.strptime(date_time_str, '%d/%m/%Y %H:%M:%S')
newPost.op = post.author if time.days >=8:
try: continue
newPost.userProfilePic = rssFeed.channel.image.url
except:
newPost.profilePicture = ""
newPost.url = post.link
newPost.content = Markup(post.description)
if "Pinned" in post.title.split(":")[0]: if post.find('div', attrs={'class':'pinned'}):
newPost.isPinned = True if post.find('div', attrs={'class':'pinned'}).find('span', attrs={'icon-pin'}):
continue
if "RT by" in post.title: newPost = twitterPost()
newPost.isRT = True newPost.op = post.find('a', attrs={'class':'username'}).text
newPost.profilePic = "" newPost.twitterName = post.find('a', attrs={'class':'fullname'}).text
else: newPost.timeStamp = datetime.datetime.strptime(date_time_str, '%d/%m/%Y %H:%M:%S')
newPost.isRT = False newPost.date = post.find('span', attrs={'class':'tweet-date'}).find('a').text
try: newPost.content = Markup(post.find('div', attrs={'class':'tweet-content'}))
newPost.profilePic = rssFeed.channel.image.url
except: if post.find('div', attrs={'class':'retweet-header'}):
newPost.profilePic = avatarPath newPost.username = post.find('div', attrs={'class':'retweet-header'}).find('div', attrs={'class':'icon-container'}).text
posts.append(newPost) newPost.isRT = True
return posts else:
newPost.username = newPost.op
newPost.isRT = False
newPost.profilePic = NITTERINSTANCE+post.find('a', attrs={'class':'tweet-avatar'}).find('img')['src'][1:]
newPost.url = NITTERINSTANCE + post.find('a', attrs={'class':'tweet-link'})['href'][1:]
if post.find('div', attrs={'class':'quote'}):
newPost.isReply = True
quote = post.find('div', attrs={'class':'quote'})
if quote.find('div', attrs={'class':'quote-text'}):
newPost.replyingTweetContent = Markup(quote.find('div', attrs={'class':'quote-text'}))
if quote.find('a', attrs={'class':'still-image'}):
newPost.replyAttachedImg = NITTERINSTANCE+quote.find('a', attrs={'class':'still-image'})['href'][1:]
newPost.replyingUser=quote.find('a', attrs={'class':'username'}).text
post.find('div', attrs={'class':'quote'}).decompose()
if post.find('div', attrs={'class':'attachments'}):
if not post.find(class_='quote'):
if post.find('div', attrs={'class':'attachments'}).find('a', attrs={'class':'still-image'}):
newPost.attachedImg = NITTERINSTANCE + post.find('div', attrs={'class':'attachments'}).find('a')['href'][1:]
feedPosts.append(newPost)
return feedPosts
def getYoutubePosts(ids): def getYoutubePosts(ids):
videos = [] videos = []
@ -642,7 +660,7 @@ def getYoutubePosts(ids):
for vid in rssFeed.entries: for vid in rssFeed.entries:
time = datetime.datetime.now() - datetime.datetime(*vid.published_parsed[:6]) time = datetime.datetime.now() - datetime.datetime(*vid.published_parsed[:6])
if time.days >= 15: if time.days >=8:
continue continue
video = ytPost() video = ytPost()

BIN
app/static/favicon_io.zip Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

View File

@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015 Semantic Org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,7 +0,0 @@
# CSS Distribution
This repository is automatically synced with the main [Semantic UI](https://github.com/Semantic-Org/Semantic-UI) repository to provide lightweight CSS only version of Semantic UI.
This package **does not support theming** and includes generated CSS files of the default theme only.
You can view more on Semantic UI at [LearnSemantic.com](http://www.learnsemantic.com) and [Semantic-UI.com](http://www.semantic-ui.com)

View File

@ -1,20 +0,0 @@
{
"name": "semantic-ui-css",
"version": "2.4.1",
"title": "Semantic UI",
"description": "CSS Only distribution of Semantic UI",
"homepage": "http://www.semantic-ui.com",
"author": "Jack Lukic <jack@semantic-ui.com>",
"license": "MIT",
"main": "semantic.js",
"repository": {
"type": "git",
"url": "git://github.com/Semantic-Org/Semantic-UI-CSS.git"
},
"bugs": {
"url": "https://github.com/Semantic-Org/Semantic-UI/issues"
},
"dependencies": {
"jquery": "x.*"
}
}

1
app/static/video-js.min.css vendored Normal file

File diff suppressed because one or more lines are too long

27
app/static/video.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<div style="margin-top: 2em;" class="ui one column centered grid"> <div style="margin-top: 2em;" class="ui one column centered grid">
<img class="ui medium circular image" src="{{ url_for('static',filename='img/404.png') }}"> <img alt="Error 404 Image" class="ui medium circular image" src="{{ url_for('static',filename='img/404.png') }}">
</div> </div>
<div style="margin: 1.5em;" class="ui one column centered grid"> <div style="margin: 1.5em;" class="ui one column centered grid">
<h2 class="ui header">This page is not on the map.</h2> <h2 class="ui header">This page is not on the map.</h2>

View File

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<div style="margin-top: 2em;" class="ui one column centered grid"> <div style="margin-top: 2em;" class="ui one column centered grid">
<img class="ui medium circular image" src="{{ url_for('static',filename='img/405.png') }}"> <img alt="Error 405 Image" class="ui medium circular image" src="{{ url_for('static',filename='img/405.png') }}">
</div> </div>
<div style="margin: 1.5em;" class="ui one column centered grid"> <div style="margin: 1.5em;" class="ui one column centered grid">
<h2 class="ui header">You are not allowed to do this!</h2> <h2 class="ui header">You are not allowed to do this!</h2>

View File

@ -2,7 +2,7 @@
{% block content %} {% block content %}
<div style="margin-top: 2em;" class="ui one column centered grid"> <div style="margin-top: 2em;" class="ui one column centered grid">
<img class="ui medium circular image" src="{{ url_for('static',filename='img/500.png') }}"> <img alt="Error 500 Image" class="ui medium circular image" src="{{ url_for('static',filename='img/500.png') }}">
</div> </div>
<div style="margin: 1.5em;" class="ui one column centered grid"> <div style="margin: 1.5em;" class="ui one column centered grid">
<h2 class="ui header">Something went wrong... But it's not your fault!</h2> <h2 class="ui header">Something went wrong... But it's not your fault!</h2>

View File

@ -1,6 +1,6 @@
<div class="ui center aligned text container"> <div class="ui center aligned text container">
<div class="ui row"> <div class="ui row">
<img class="ui image" src="{{ url_for('static',filename='img/closed.png') }}"> <img alt="Closed registrations image" class="ui image" src="{{ url_for('static',filename='img/closed.png') }}">
</div> </div>
<div class="ui row"> <div class="ui row">

View File

@ -1,6 +1,6 @@
<div class="ui center aligned text container"> <div class="ui center aligned text container">
<div class="ui row"> <div class="ui row">
<img class="ui image" src="{{ url_for('static',filename='img/empty.png') }}"> <img alt="Empty feed image" class="ui image" src="{{ url_for('static',filename='img/empty.png') }}">
</div> </div>
<div class="ui row"> <div class="ui row">

View File

@ -3,7 +3,7 @@
<div class="content"> <div class="content">
<div class="extra content"> <div class="extra content">
<div class="left floated author"> <div class="left floated author">
<img class="ui avatar image" src="{{ url_for('static',filename='img/avatars/')}}{{range(1, 12) | random}}.png"> <img alt="Avatar random" class="ui avatar image" src="{{ url_for('static',filename='img/avatars/')}}{{range(1, 12) | random}}.png">
</div> </div>
<a href="{{post.url}}"><span class="right floated star"> <a href="{{post.url}}"><span class="right floated star">

View File

@ -2,7 +2,7 @@
<div class="content"> <div class="content">
<div class="extra content"> <div class="extra content">
<div class="left floated author"> <div class="left floated author">
<img class="ui avatar image" src="{{ post.profilePic }}"> <img alt="Avatar" class="ui avatar image" src="{{ post.profilePic }}">
</div> </div>
<a href="{{post.url}}"><span class="right floated star"> <a href="{{post.url}}"><span class="right floated star">
@ -24,7 +24,7 @@
</div> </div>
<div class="extra content"> <div class="extra content">
{% if post.attachedImg != "" %} {% if post.attachedImg != "" %}
<img class="ui centered medium image" src="{{post.attachedImg}}"> <img alt="Image attachment" class="ui centered medium image" src="{{post.attachedImg}}">
{% endif %} {% endif %}
{% if post.isReply %} {% if post.isReply %}
<div class="ui card"> <div class="ui card">
@ -34,7 +34,7 @@
<div class="description break-word"> <div class="description break-word">
{{post.replyingTweetContent}} {{post.replyingTweetContent}}
{% if post.replyAttachedImg != "" %} {% if post.replyAttachedImg != "" %}
<img class="ui centered medium image" src="{{post.replyAttachedImg}}"> <img alt="Image attachment" class="ui centered medium image" src="{{post.replyAttachedImg}}">
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
<div class="card"> <div class="card">
<div class="image"> <div class="image">
<img src="{{video.videoThumb}}"> <img alt="Thumbnail" src="{{video.videoThumb}}">
</div> </div>
<div class="content"> <div class="content">
<a class="video-title break-word" href="{{url_for('watch', v=video.id, _method='GET')}}">{{video.videoTitle}}</a> <a class="video-title break-word" href="{{url_for('watch', v=video.id, _method='GET')}}">{{video.videoTitle}}</a>

View File

@ -8,14 +8,17 @@
{% else %} {% else %}
<title>Yotter</title> <title>Yotter</title>
{% endif %} {% endif %}
<meta name="viewport" content="width=device-width, user-scalable=no"> <meta name="viewport" content="width=device-width">
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='semantic/semantic.min.css') }}"> <link rel="preload" as= "style" type= "text/css" href= "{{ url_for('static',filename='semantic/semantic.min.css') }}">
<link rel="stylesheet" type= "text/css" href="{{ url_for('static',filename='styles.css') }}"> <link rel="stylesheet" type= "text/css" href="{{ url_for('static',filename='styles.css') }}">
<link rel="icon" href="{{ url_for('static',filename='favicons/favicon.ico') }}">
<link rel="stylesheet"href= "{{ url_for('static',filename='semantic/semantic.min.css') }}">
</head> </head>
<body> <body>
<div class="ui icon menu overflow-auto"> <div class="ui icon menu overflow-auto">
<a href="{{ url_for('index') }}"><div class="item"> <a href="{{ url_for('index') }}"><div class="item">
<img src="{{ url_for('static',filename='img/logo_simple.png') }}"> <img alt="Yotter simple logo" src="{{ url_for('static',filename='img/logo_simple.png') }}">
</div></a> </div></a>
{% if current_user.is_anonymous %} {% if current_user.is_anonymous %}
<a href="{{ url_for('login') }}" class="item">Login</a> <a href="{{ url_for('login') }}" class="item">Login</a>

View File

@ -4,7 +4,7 @@
<div class="blue ui centered card"> <div class="blue ui centered card">
<div class="content"> <div class="content">
<div class="center aligned author"> <div class="center aligned author">
<img class="ui avatar image" src="{{channel.avatar}}"> <img alt="Avatar" class="ui avatar image" src="{{channel.avatar}}">
</div> </div>
<div class="center aligned header"><a href="">{{channel.name}}</a></div> <div class="center aligned header"><a href="">{{channel.name}}</a></div>
<div class="center aligned description"> <div class="center aligned description">

View File

@ -1,6 +1,42 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<style>
.ui.button {
cursor: pointer;
display: inline-block;
min-height: 1em;
outline: none;
border: none;
vertical-align: baseline;
background: #E0E1E2 none;
color: rgba(0, 0, 0, 0.6);
font-family: 'Lato', 'Helvsetica Neue', Arial, Helvetica, sans-serif;
margin: 0em 0.25em 0em 0em;
padding: 0.78571429em 1.5em 0.78571429em;
text-transform: none;
text-shadow: none;
font-weight: bold;
line-height: 1em;
font-style: normal;
text-align: center;
text-decoration: none;
border-radius: 0.28571429rem;
-webkit-box-shadow: 0px 0px 0px 1px transparent inset, 0px 0em 0px 0px rgba(34, 36, 38, 0.15) inset;
box-shadow: 0px 0px 0px 1px transparent inset, 0px 0em 0px 0px rgba(34, 36, 38, 0.15) inset;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transition: opacity 0.1s ease, background-color 0.1s ease, color 0.1s ease, background 0.1s ease, -webkit-box-shadow 0.1s ease;
transition: opacity 0.1s ease, background-color 0.1s ease, color 0.1s ease, background 0.1s ease, -webkit-box-shadow 0.1s ease;
transition: opacity 0.1s ease, background-color 0.1s ease, color 0.1s ease, box-shadow 0.1s ease, background 0.1s ease;
transition: opacity 0.1s ease, background-color 0.1s ease, color 0.1s ease, box-shadow 0.1s ease, background 0.1s ease, -webkit-box-shadow 0.1s ease;
will-change: '';
-webkit-tap-highlight-color: transparent;
}
</style>
<div style="margin: 2em" class="ui one column centered grid"> <div style="margin: 2em" class="ui one column centered grid">
<div class="row"> <div class="row">
<div class="column"> <div class="column">

View File

@ -18,7 +18,7 @@
<div class="ui relaxed divided list"> <div class="ui relaxed divided list">
{% for res in results %} {% for res in results %}
<div class="item"> <div class="item">
<img class="ui avatar image" src="{{ res.avatar }}"> <img alt="Avatar" class="ui avatar image" src="{{ res.avatar }}">
<div class="content"> <div class="content">
{% if res.fullName|length > 20%} {% if res.fullName|length > 20%}
<a class="header" href="/u/{{res.username}}">{{res.fullName[0:23]}}...</a> <a class="header" href="/u/{{res.username}}">{{res.fullName[0:23]}}...</a>

View File

@ -4,7 +4,7 @@
<div class="blue ui centered card"> <div class="blue ui centered card">
<div class="content"> <div class="content">
<div class="center aligned author"> <div class="center aligned author">
<img class="ui avatar image" src="{{user.profilePic}}"> <img alt="Profile picture" class="ui avatar image" src="{{user.profilePic}}">
</div> </div>
<div class="center aligned header"><a href="https://nitter.net/{{ user.profileUsername.replace('@','') }}"> <div class="center aligned header"><a href="https://nitter.net/{{ user.profileUsername.replace('@','') }}">
{%if user.profileFullName%} {%if user.profileFullName%}

View File

@ -1,5 +1,5 @@
<head> <head>
<link rel="stylesheet" type= "text/css" href="{{ url_for('static',filename='videojs.css') }}"> <link rel="stylesheet" type= "text/css" href="{{ url_for('static',filename='video-js.min.css') }}">
</head> </head>
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
@ -46,5 +46,5 @@
</div> </div>
</div> </div>
</div> </div>
<script src="{{ url_for('static',filename='videojs.js') }}"></script> <script src="{{ url_for('static',filename='video.min.js') }}"></script>
{% endblock %} {% endblock %}

View File

@ -37,7 +37,7 @@
</p> </p>
{% endif %} {% endif %}
</div> </div>
<img class="ui avatar image" src="{{ res.thumbnail }}"> <img alt="Avatar" class="ui avatar image" src="{{ res.thumbnail }}">
<div class="content"> <div class="content">
<a class = "header" href="{{ url_for('channel', id=res.channelId)}}">{{res.username}}</a> <a class = "header" href="{{ url_for('channel', id=res.channelId)}}">{{res.username}}</a>
<div class="description"><div class="ui label"> <div class="description"><div class="ui label">