Merge branch 'dev-indep' of https://github.com/ytorg/yotter into dev-indep

This commit is contained in:
pluja 2020-10-05 13:24:07 +02:00
commit d1ec8e20b6
5 changed files with 88 additions and 51 deletions

View File

@ -1,5 +1,7 @@
.git .git
.github
.gitignore .gitignore
cache
Dockerfile Dockerfile
docker-compose.yml docker-compose.yml
LICENSE LICENSE

7
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,7 @@
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

45
.github/workflows/docker-build.yml vendored Normal file
View File

@ -0,0 +1,45 @@
name: Docker Multi-Architecture Build
on:
push:
paths-ignore:
- "**.md"
branches:
- dev-indep
jobs:
build-docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
with:
version: latest
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: cache docker cache
uses: actions/cache@v2.1.1
with:
path: ${{ github.workspace }}/cache
key: ${{ runner.os }}-docker-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-docker-${{ hashFiles('**/requirements.txt') }}
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ytorg/yotter:latest
cache-from: type=local,src=cache
cache-to: type=local,dest=cache

View File

@ -47,7 +47,6 @@ YOUTUBERSS = "https://www.youtube.com/feeds/videos.xml?channel_id="
########################## ##########################
#### Global variables #### #### Global variables ####
########################## ##########################
ALLOWED_EXTENSIONS = {'json', 'db'}
######################### #########################
#### Twitter Logic ###### #### Twitter Logic ######
@ -296,28 +295,34 @@ def ytsearch():
def ytfollow(channelId): def ytfollow(channelId):
form = EmptyForm() form = EmptyForm()
if form.validate_on_submit(): if form.validate_on_submit():
r = followYoutubeChannel(channelId) r = followYoutubeChannel(channelId)
return redirect(request.referrer) return redirect(request.referrer)
def followYoutubeChannel(channelId): def followYoutubeChannel(channelId):
channelData = YoutubeSearch.channelInfo(channelId, False)
try: try:
if not current_user.is_following_yt(channelId): channelData = YoutubeSearch.channelInfo(channelId, False)
follow = youtubeFollow() try:
follow.channelId = channelId if not current_user.is_following_yt(channelId):
follow.channelName = channelData[0]['name'] follow = youtubeFollow()
follow.followers.append(current_user) follow.channelId = channelId
db.session.add(follow) follow.channelName = channelData[0]['name']
db.session.commit() follow.followers.append(current_user)
flash("{} followed!".format(channelData[0]['name'])) db.session.add(follow)
return True db.session.commit()
else: flash("{} followed!".format(channelData[0]['name']))
return True
else:
return False
except Exception as e:
print(e)
flash("Youtube: Couldn't follow {}. Already followed?".format(channelData[0]['name']))
return False return False
except Exception as e: except KeyError as ke:
print(e) print("KeyError: {}:'{}' could not be found".format(ke, channelId))
flash("Youtube: Couldn't follow {}. Already followed?".format(channelData[0]['name'])) flash("Youtube: ChannelId '{}' is not valid".format(channelId))
return False return False
@app.route('/ytunfollow/<channelId>', methods=['POST']) @app.route('/ytunfollow/<channelId>', methods=['POST'])
@login_required @login_required
def ytunfollow(channelId): def ytunfollow(channelId):
@ -571,16 +576,12 @@ def importdata():
if file.filename == '': if file.filename == '':
flash('No selected file') flash('No selected file')
return redirect(request.referrer) return redirect(request.referrer)
if file and allowed_file(file.filename) or 'subscription_manager' in file.filename: else:
option = request.form['import_format'] option = request.form['import_format']
if option == 'yotter': if option == 'yotter':
importYotterSubscriptions(file) importYotterSubscriptions(file)
elif option == 'newpipe':
importNewPipeSubscriptions(file)
elif option == 'youtube': elif option == 'youtube':
importYoutubeSubscriptions(file) importYoutubeSubscriptions(file)
elif option == 'freetube':
importFreeTubeSubscriptions(file)
return redirect(request.referrer) return redirect(request.referrer)
return redirect(request.referrer) return redirect(request.referrer)
@ -594,37 +595,25 @@ def deleteme():
logout_user() logout_user()
return redirect(url_for('index')) return redirect(url_for('index'))
def importYoutubeSubscriptions(file):
filename = secure_filename(file.filename)
try:
data = re.findall('(UC[a-zA-Z0-9_-]{22})|(?<=user/)[a-zA-Z0-9_-]+', file.read().decode('utf-8'))
for acc in data:
r = followYoutubeChannel(acc)
except Exception as e:
print(e)
flash("File is not valid.")
def importYotterSubscriptions(file): def importYotterSubscriptions(file):
filename = secure_filename(file.filename) filename = secure_filename(file.filename)
data = json.load(file) data = json.load(file)
for acc in data['twitter']: for acc in data['twitter']:
r = followTwitterAccount(acc['username']) r = followTwitterAccount(acc['username'])
for acc in data['youtube']: for acc in data['youtube']:
r = followYoutubeChannel(acc['channelId']) r = followYoutubeChannel(acc['channelId'])
def importNewPipeSubscriptions(file):
filename = secure_filename(file.filename)
data = json.load(file)
for acc in data['subscriptions']:
r = followYoutubeChannel(re.search('(UC[a-zA-Z0-9_-]{22})|(?<=user\/)[a-zA-Z0-9_-]+', acc['url']).group())
def importYoutubeSubscriptions(file):
filename = secure_filename(file.filename)
itemlist = minidom.parse(file).getElementsByTagName('outline')
for item in itemlist[1:]:
r = followYoutubeChannel(re.search('UC[a-zA-Z0-9_-]{22}', item.attributes['xmlUrl'].value).group())
def importFreeTubeSubscriptions(file):
filename = secure_filename(file.filename)
data = re.findall('UC[a-zA-Z0-9_-]{22}', file.read().decode('utf-8'))
for acc in data:
r = followYoutubeChannel(acc)
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/register', methods=['GET', 'POST']) @app.route('/register', methods=['GET', 'POST'])
def register(): def register():
form = RegistrationForm() form = RegistrationForm()

View File

@ -31,7 +31,7 @@
<div class="ui blue segment"> <div class="ui blue segment">
<i class="large upload middle aligned icon"></i> <i class="large upload middle aligned icon"></i>
<div class="content"> <div class="content">
<div class="description"><h5 class="ui header">Import suscription data</h5></div> <div class="description"><h5 class="ui header">Import subscription data</h5></div>
<form action = "{{ url_for('importdata') }}" method = "POST" enctype = "multipart/form-data"> <form action = "{{ url_for('importdata') }}" method = "POST" enctype = "multipart/form-data">
<input type = "file" name = "file"/> <input type = "file" name = "file"/>
<input type = "submit"/> <input type = "submit"/>
@ -39,15 +39,9 @@
<label class="radio-inline"> <label class="radio-inline">
<input type="radio" name="import_format" id="yotter" value="yotter" checked> Yotter <input type="radio" name="import_format" id="yotter" value="yotter" checked> Yotter
</label> </label>
<label class="radio-inline"> <label class="radio-inline" data-tooltip="Includes FreeTube, Invidious and NewPipe.">
<input type="radio" name="import_format" id="newpipe" value="newpipe"> NewPipe
</label>
<label class="radio-inline">
<input type="radio" name="import_format" id="youtube" value="youtube"> Youtube <input type="radio" name="import_format" id="youtube" value="youtube"> Youtube
</label> </label>
<label class="radio-inline">
<input type="radio" name="import_format" id="freetube" value="freetube"> FreeTube
</label>
</form> </form>
</div> </div>
</div> </div>