mirror of
https://github.com/godotengine/godot-showreel-voting.git
synced 2025-12-31 17:49:06 +03:00
* initial backend setup
* copied db setup
* added login
* added autoincrement to ids
* update db again
* added script to populate with test data
* added functionality to fetch videos
* added vote functionality
* added logic to update video info
* added history
* updated readme
* Update thank you page
* fixed small bugs
* small improvements
* added admin view, UI fix
* fix vote buttons style
* added pagination
* added command to load sample data from csv
* Autoplay videos
* Adding before you vote page
* added yt video id extractor
* improve visibility for the history page votes
* added logic for before you vote disclaimer
* Remind people to set videos to unlisted and allowed for embed
* Update home.html
* Update home.html
* Add progress bar to total
* Small adjustments
* fix home {% if user %}
* Update macros.html
* limit vote views to users with specific roles
* added endpoint to delete votes
* added confirmation to the delete vote action
* Update non-fund members CTA
* allow voting to specific fund members
* added result csv endpoint
* updated auth
* revert adding 'vote_allowed' column, merged it into is_staff
* added `is_fund_member` attribute to table and updated code
* refactored code
* update style for voting page
* updated readme
* Add static files
* remove options from dropdown for users that can't vote
* added keyboard shortcuts to vote buttons
* added azerty support for shortcuts
* update skip to S key
* remove placeholder
---------
Co-authored-by: Emi <2206700+coppolaemilio@users.noreply.github.com>
158 lines
5.8 KiB
Python
158 lines
5.8 KiB
Python
import csv
|
|
from datetime import timedelta
|
|
import hashlib
|
|
from http.client import HTTPException
|
|
import os
|
|
import click
|
|
from flask import Flask, current_app, g, render_template, session
|
|
|
|
from gdshowreelvote import auth
|
|
from gdshowreelvote.blueprints.votes import bp as votes_bp
|
|
from gdshowreelvote.database import DB, Showreel, ShowreelStatus, User, Video, Vote, migrate
|
|
|
|
def create_app(config=None):
|
|
# ------------------------------------------------
|
|
# App Config
|
|
# ------------------------------------------------
|
|
app = Flask(__name__, instance_relative_config=True)
|
|
|
|
# Load the default config
|
|
app.config.from_pyfile('config.py', silent=True)
|
|
|
|
if config:
|
|
app.config.update(config)
|
|
|
|
app.register_blueprint(votes_bp, url_prefix='/')
|
|
|
|
DB.init_app(app)
|
|
migrate.init_app(app, DB)
|
|
auth.init_app(app)
|
|
|
|
# ------------------------------------------------
|
|
# OIDC User Handling
|
|
# ------------------------------------------------
|
|
# Set session timeout to 1 day
|
|
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=1)
|
|
|
|
@app.before_request
|
|
def setup_globals():
|
|
session.permanent = True
|
|
oidc_info = session.get('user', None)
|
|
|
|
if oidc_info:
|
|
g.user = DB.session.get(User, oidc_info['sub'])
|
|
# Calculate Gravatar hash
|
|
g.user.gravatar_hash = hashlib.md5(g.user.email.encode('utf-8')).hexdigest()
|
|
else:
|
|
g.user = None
|
|
|
|
# ------------------------------------------------
|
|
# Error Handling
|
|
# ------------------------------------------------
|
|
@app.errorhandler(HTTPException)
|
|
def page_not_found(error):
|
|
user = g.user if hasattr(g, 'user') else None
|
|
content = render_template('error.html', error=error)
|
|
return render_template('default.html', content=content, user=user)
|
|
|
|
|
|
# ------------------------------------------------
|
|
# Commands
|
|
# ------------------------------------------------
|
|
|
|
@app.cli.command('create-sample-data')
|
|
def create_sample_data():
|
|
if current_app.config['ENV'] != 'dev':
|
|
print('Sample data can only be created in development environment.')
|
|
return
|
|
print('Creating sample data...')
|
|
# Reset state
|
|
DB.session.query(Showreel).delete()
|
|
DB.session.query(User).filter(User.email == 'author@example.com').delete()
|
|
DB.session.query(Vote).delete()
|
|
DB.session.query(Video).delete()
|
|
DB.session.commit()
|
|
# Create showreel
|
|
showreel = Showreel(status=ShowreelStatus.VOTE, title='2025 Godot Desktop/Console Games')
|
|
DB.session.add(showreel)
|
|
DB.session.commit()
|
|
# Create author of videos
|
|
author = User(id='sample-author-id', email='author@example.com', username='Sample Author')
|
|
DB.session.add(author)
|
|
DB.session.commit()
|
|
|
|
# Create sample video entries
|
|
video_data = [{
|
|
'game': 'Brotato',
|
|
'author_name': 'Blobfish Games',
|
|
'follow_me_link': 'https://twitter.com/BlobfishGames',
|
|
'category': '2025 Godot Desktop/Console Games',
|
|
'video_link': 'https://www.youtube.com/watch?v=nfceZHR7Yq0',
|
|
'video_download_link': 'https://www.youtube.com/watch?v=nfceZHR7Yq0',
|
|
'store_link': 'https://store.steampowered.com/app/1592190/Brotato/',
|
|
},
|
|
{'game': 'Vampire Survivors',
|
|
'author_name': 'Blobfish Games',
|
|
'follow_me_link': 'https://twitter.com/BlobfishGames',
|
|
'category': '2025 Godot Desktop/Console Games',
|
|
'video_link': 'https://www.youtube.com/watch?v=6HXNxWbRgsg',
|
|
'video_download_link': 'https://www.youtube.com/watch?v=6HXNxWbRgsg',
|
|
'store_link': 'https://store.steampowered.com/app/1592190/Brotato/',
|
|
},
|
|
]
|
|
for video in video_data:
|
|
video = Video(game=video['game'],
|
|
author_name=video['author_name'],
|
|
follow_me_link=video['follow_me_link'],
|
|
video_link=video['video_link'],
|
|
video_download_link=video['video_download_link'],
|
|
store_link=video['store_link'],
|
|
author=author,
|
|
showreel=showreel)
|
|
DB.session.add(video)
|
|
DB.session.commit()
|
|
|
|
print(f'Created sample video entry: {video.game} (ID: {video.id})')
|
|
|
|
return showreel, author
|
|
|
|
|
|
@app.cli.command('load-data-from-csv')
|
|
@click.argument('file')
|
|
def load_data_from_csv(file):
|
|
showreel = DB.session.query(Showreel).first()
|
|
author = DB.session.query(User).filter(User.id == 'sample-author-id').first()
|
|
if not showreel or not author:
|
|
print('No showreel or user to attach videos to. Please execute "uv run flask --app main create-sample-data" and then try again.')
|
|
return
|
|
|
|
file_path = 'instance/sample.csv'
|
|
if file and os.path.isfile(file):
|
|
file_path = file
|
|
with open(file_path) as csvfile:
|
|
spamreader = csv.DictReader(csvfile, delimiter=',')
|
|
|
|
for row in spamreader:
|
|
video = Video(game=row['Game'],
|
|
author_name=row['Author'],
|
|
follow_me_link=row['Follow-me link'],
|
|
video_link=row['Video link'],
|
|
video_download_link=row['Download link'],
|
|
store_link=row['Store Link'],
|
|
contact_email=row['Contact email'],
|
|
author=author,
|
|
showreel=showreel)
|
|
DB.session.add(video)
|
|
|
|
DB.session.commit()
|
|
print(f'added {spamreader.line_num} videos')
|
|
|
|
return app
|
|
|
|
|
|
app = create_app()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
app.run(debug=True)
|