From 3eae6f61e36235e570fa8ee4b0a99b9372aba41e Mon Sep 17 00:00:00 2001 From: pluja Date: Wed, 5 Aug 2020 09:20:23 +0200 Subject: [PATCH] Initial commit --- README.md | 19 ++++++---------- app/routes.py | 33 +++++++++++++++++----------- app/static/styles.css | 20 +++++++++++++++++ app/templates/base.html | 16 +------------- app/templates/video.html | 47 +++++++++++++++++++++------------------- 5 files changed, 73 insertions(+), 62 deletions(-) create mode 100644 app/static/styles.css diff --git a/README.md b/README.md index 1cdf6e9..d3a6702 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,9 @@ # Parasitter +

Twitter and Youtube via RSS with privacy

-

THIS IS A MIRROR FOR THE MAIN REPO


-> Important note: A [new branch](https://github.com/pluja/Parasitter/tree/dev-indep) is being developed as I'm breaking the dependance with Invidious. You can now test it. - -Parasitter allows you to follow your favorite Twitter and YouTube accounts with full privacy. Parasitter uses [Nitter's](https://nitter.net/) and [Invidious](invidio.us) rss feeds in order to gather the latest content from your favourite accounts and builds a *beautiful* feed. We will never connect you to Twitter or YouTube in any way, so your privacy is safe when using Parasitter. Parasitter is written in Python and Flask and uses Semantic-UI as its CSS framework. - -Parasitter doesn't try to compete with Nitter nor Invidious. It serves as a complement, as it beneficiates from them. Parasitter is not a Twitter viewer as Nitter is or a YouTube frontend as Invidious. Instead Parasitter gathers all your accounts in one place so you can stay tuned with their latest content. +Parasitter allows you to follow your favorite Twitter and YouTube accounts with full privacy using rss feeds in order to gather the latest content from your favourite accounts and builds a *beautiful* feed so you can read them. Parasitter is written in Python and Flask and uses Semantic-UI as its CSS framework. Parasitter is possible thanks to several open-source projects that are listed on the [Powered by](#powered-by) section. Make sure to check out those awesome projects! @@ -28,7 +24,6 @@ Parasitter is possible thanks to several open-source projects that are listed on * Uses RSS feeds (could be expanded to more social networks) * Follow Twitter accounts. * Follow Youtube accounts. -* Watch Youtube videos. * Save your favourite Tweets. * Save your favourite Youtube videos [Coming soon!] * Tor-friendly. @@ -43,18 +38,18 @@ Only the hash of your password is stored on the database. Also no personal infor I always recommend self-hosting, as you will be the only person with access to the data. ## Privacy -Parasitter cares about your privacy, and for this it will never make any connection to Twitter or Youtube. We make use of rss feeds to fetch all the tweets and videos from your followed accounts. If you want to use a specific Nitter or Invidious instance you can replace it at the top of the file `app/routes.py`. +Parasitter cares about your privacy, and for this it will never make any connection to Twitter or Youtube. We make use pf rss feeds to fetch all the tweets from your followed accounts. If you want to use a specific Nitter or Invidious instance you can replace it on the file `app/routes.py`. -It is always recommended to set up a self-hosted instance. It is quite easy and conveninent and will give you full control over your data. The only data that is stored on the Database is: * Hash of the password * Username -* Email (Will be deprecated soon!) +* Email (we won't send you any mails so you can make up the mail) - This is for future versions. * List of followed users * List of saved posts # Self hosting ### Local +> IMPORTANT: Connections to googlevideo will be made to stream the videos (as Invidious did). It is recommended to use a VPS server to preserve your privacy. You don't need a server to run Parasitter. You can run it on your computer locally and own your (little) data. The installation process is done on a GNU/Linux environment, but should be pretty similar on other platforms. 1. Install `python3`, `pip3`, `python3-venv` (optional) and `git`. @@ -139,8 +134,8 @@ Another option is to host a Parasitter server so you can access it from anywhere #### TO BE CONTINUED! ### Powered by: -* [Nitter](https://nitter.net) -* [Invidious](https://invidio.us) +* [RSSBridge](https://github.com/RSS-Bridge/rss-bridge) +* [youtube-dl](https://github.com/ytdl-org/youtube-dl) * [Flask](https://flask.palletsprojects.com/) * [SQLAlchemy](https://docs.sqlalchemy.org/en/13/) * [Semantic-UI](https://semantic-ui.com) diff --git a/app/routes.py b/app/routes.py index 45158c7..f1453bd 100644 --- a/app/routes.py +++ b/app/routes.py @@ -6,6 +6,7 @@ from requests_futures.sessions import FuturesSession from concurrent.futures import as_completed from werkzeug.urls import url_parse from bs4 import BeautifulSoup +from youtube_dl import YoutubeDL from app import app, db import random, string import time, datetime @@ -17,7 +18,8 @@ import re # Instances - Format must be instance.tld (No '/' and no 'https://') nitterInstance = "https://nitter.net/" nitterInstanceII = "https://nitter.mastodont.cat/" -invidiousInstance = "invidious.snopyta.org" +invidiousInstance = "invidio.us" +proxy = "" #eg. socks5://IP:PORT ######################### #### Twitter Logic ###### @@ -301,20 +303,24 @@ def ytunfollow(channelId): @app.route('/video/', methods=['POST', 'GET']) @login_required def video(id): - data = requests.get('https://{instance}/api/v1/videos/{id}'.format(instance=invidiousInstance, id=id)) - data = json.loads(data.content) + if proxy: + ydl_opts = { + 'proxy':proxy + } + else: + ydl_opts = {} + ydl = YoutubeDL(ydl_opts) + data = ydl.extract_info("{id}".format(id=id), download=False) video = { 'title':data['title'], - 'description':Markup(data['descriptionHtml']), - 'viewCount':data['viewCount'], - 'likeCount':data['likeCount'], - 'dislikeCount':data['dislikeCount'], - 'authorThumb':data['authorThumbnails'][4]['url'], - 'author':data['author'], - 'authorUrl':data['authorUrl'], - 'instance':invidiousInstance, - 'id':id + 'description':Markup(data['description']), + 'viewCount':data['view_count'], + 'author':data['uploader'], + 'authorUrl':data['uploader_url'], + 'id':id, + 'url': data['formats'][-1]['url'], + 'averageRating': str((float(data['average_rating'])/5)*100) } return render_template("video.html", video=video) @@ -500,6 +506,8 @@ def getPosts(account): def getInvidiousPosts(ids): videos = [] + ydl = YoutubeDL() + link = ydl.extract_info("https://www.youtube.com/watch?v=XCSfoiD8wUA", download=False)['formats'][-1]['url'] with FuturesSession() as session: futures = [session.get('https://{instance}/feed/channel/{id}'.format(instance=invidiousInstance, id=id.channelId)) for id in ids] for future in as_completed(futures): @@ -511,7 +519,6 @@ def getInvidiousPosts(ids): video.timeStamp = getTimeDiff(vid.published_parsed) video.channelName = vid.author_detail.name video.channelUrl = vid.author_detail.href - video.videoUrl = vid.link video.id = vid.link.split("?v=")[1] video.videoTitle = vid.title video.videoThumb = vid.media_thumbnail[0]['url'] diff --git a/app/static/styles.css b/app/static/styles.css new file mode 100644 index 0000000..0816937 --- /dev/null +++ b/app/static/styles.css @@ -0,0 +1,20 @@ +.para-light-grey{ + background-color: rgb(250, 82, 82); +} + +.para-green{ + background-color: lightgreen; +} + +.twitter{ + color: rgb(0, 166, 196) !important; +} + +.youtube{ + color: rgb(224, 32, 32) !important; +} + +.video-title{ + font-weight: bold; + font-size: 1.15em; +} \ No newline at end of file diff --git a/app/templates/base.html b/app/templates/base.html index 437ee66..9ee6146 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -9,21 +9,7 @@ Parasitter {% endif %} - - +