linuxgaming

This is my own Linux gaming aggregate web app I built for personal use.
git clone git://git.beardyjay.co.uk/linuxgaming
Log | Files | Refs | README

commit fc2c288974464dfdec1e3f349a9b5b1fabf99b67
parent b49b0953cbbc0c9364b3ba53a090e2fface86cbf
Author: Jay Scott <jay@beardyjay.co.uk>
Date:   Thu, 19 Jul 2018 20:21:38 +0100

another huge refactor

Diffstat:
MCHANGELOG | 36+++++++++++++++++++++---------------
MTODO.md | 14++++++--------
Mlinuxgaming/__init__.py | 8++++----
Mlinuxgaming/details.py | 11++++++++---
Mlinuxgaming/search.py | 23+++++++++++++++++------
Dlinuxgaming/templates/macros/cards.html | 26--------------------------
Mlinuxgaming/templates/macros/items.html | 82+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mlinuxgaming/templates/pages/details.html | 17+----------------
Dlinuxgaming/templates/pages/games.html | 35-----------------------------------
Mlinuxgaming/templates/pages/home.html | 20+++-----------------
Mlinuxgaming/templates/pages/search.html | 18++----------------
Mlinuxgaming/update.py | 36++++++++++++++++++++++++++++++------
Mlinuxgaming/util.py | 18++++++++++++++++++
13 files changed, 159 insertions(+), 185 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG @@ -1,24 +1,31 @@ +Thur 19 Jul +-- + + - refactored + Wed 18 Jul --- - - Added new source "Xpenguin" - - RSS description check added. - - Refactored search page. - - Changed gog to type game. - + - added new source "Xpenguin" + - rss description check added + - refactored + - changed gog to type game + - created new helper modules + - add humble bundle test data + Tue 17 Jul --- - - Major update to the UI. - - Added menu - - Front page now shows past 24 hours - - Updated error pages - - Added type object to MongoDB - - Added new type "podcast" - - Added new search path - - Added new source, "Mostly Linux Podcast" - - Added GoG source and test page- \ No newline at end of file + - major update to the UI + - added menu + - front page now shows past 24 hours + - updated error pages + - added type object to MongoDB + - added new type "podcast" + - added new search path + - added new source, "Mostly Linux Podcast" + - added gog source and test page diff --git a/TODO.md b/TODO.md @@ -1,9 +1,8 @@ # TODO - - - Add menu with source info / about etc - - Move updates to AWS Lambda function - - Add API - - Add Itch.io games - - Add Steam games - - Add better searching- \ No newline at end of file + - add menu with source info / about etc + - move updates to AWS Lambda function + - add API + - add Itch.io games + - add Steam games + - add better searching diff --git a/linuxgaming/__init__.py b/linuxgaming/__init__.py @@ -33,15 +33,15 @@ def create_app(): app.mongo = mongo # register blueprint modules - app.register_blueprint(update.bp) - app.register_blueprint(details.bp) - app.register_blueprint(search.bp) + app.register_blueprint(update.BP) + app.register_blueprint(details.BP) + app.register_blueprint(search.BP) @app.route("/") def home(): result = database.find_all({ "date": { - '$gte': datetime.now() - timedelta(hours=24) + '$gte': datetime.now() - timedelta(hours=48) } }) return render_template('pages/home.html', entries=result) diff --git a/linuxgaming/details.py b/linuxgaming/details.py @@ -1,12 +1,17 @@ +""" +shows more details about the current sources. + +:return: Blueprint +""" from flask import (Blueprint, flash, redirect, render_template, url_for, current_app) from . import database from . import util -bp = Blueprint('details', __name__, url_prefix='/details') +BP = Blueprint('details', __name__, url_prefix='/details') -@bp.route("/<path:path>", methods=["GET"]) +@BP.route("/<path:path>", methods=["GET"]) def details(path): """Source details page""" feed_config = util.load_yaml() @@ -21,4 +26,4 @@ def details(path): source_items = database.find_all({"name": path}) return render_template( - 'pages/details.html', data=source_data, items=source_items) + 'pages/details.html', data=source_data, entries=source_items) diff --git a/linuxgaming/search.py b/linuxgaming/search.py @@ -1,21 +1,32 @@ +""" +module to search database based on the path. + +""" from flask import (Blueprint, flash, redirect, url_for, render_template, current_app) from . import database -bp = Blueprint('search', __name__, url_prefix='/search') +BP = Blueprint('search', __name__, url_prefix='/search') -@bp.route("/<path:path>", methods=["GET"]) +@BP.route("/<path:path>", methods=["GET"]) def search(path): + """ + search database based on the given path + :param path: path is used as the db find + :return: Flask render_template + """ + # pages that we allow pages = ['game', 'twitch', 'youtube', 'article', 'podcast'] + # if they are not in the path, then redirect. if any(x in path for x in pages): result = database.find_all({"type": path}) return render_template( 'pages/search.html', entries=result, count=result.count()) - else: - flash('1337 Hacks in progress...') - current_app.logger.info('Manual search probe %s', path) - return redirect(url_for('home')) + flash('1337 Hacks in progress...') + current_app.logger.info('Manual search probe %s', path) + + return redirect(url_for('home')) diff --git a/linuxgaming/templates/macros/cards.html b/linuxgaming/templates/macros/cards.html @@ -1,25 +0,0 @@ -{% macro show_card(item) %} -<div class="card"> - <div class="blurring dimmable image"> - <div class="ui dimmer"> - <div class="content"> - <div class="center"> - <a href="{{ item.url }}" class="ui inverted button">More Details</a> - </div> - </div> - </div> - <img class="ui small image" alt="Site Logo" src="{{ item.image }}"> - </div> - - <div class="content"> - <a class="header">{{ item.title }}</a> - <div class="right floated meta"> - {{ item.category}} - </div> - <div class="meta"> - <span class="date">Released {{ item.date|strftime}}</span> - </div> - </div> - </div> - -{% endmacro %}- \ No newline at end of file diff --git a/linuxgaming/templates/macros/items.html b/linuxgaming/templates/macros/items.html @@ -1,36 +1,53 @@ -{% macro show_item(item) %} - <tr> +{% macro show_item(entries) %} +<table class="ui striped very compact small olive table"> + <thead> + <tr> + <th>Type</th> + <th data-tooltip="Click the source to filter just them!" data-position="top center">Source</th> + <th>Title</th> + <th>Released</th> + <th>Link</th> + </tr> + </thead> + <tbody> + {% for item in entries %} + <tr> + <td> + {% if "twitch" in item.type %} + <i text='twitch' class="twitch inverted purple bordered icon"></i> + {% elif "youtube" in item.type %} + <i class="youtube red bordered inverted icon"></i> + {% elif "game" in item.type %} + <i class="game blue bordered inverted icon"></i> + {% elif "article" in item.type %} + <i class="rss orange bordered inverted icon"></i> + {% else %} + <i class="soundcloud blue bordered inverted icon"></i> + {% endif %} + </td> + <td> + {% if not "gog" in item.name %} + <a href="/details/{{ item.name }}"> + <img alt="{{ item.name }} icon" src="{{ url_for('static', filename='images/icons/')}}{{ item.icon }} "> + </a> + {% else %} + <img alt="{{ item.name }} icon" src="{{ url_for('static', filename='images/icons/')}}{{ item.icon }} "> + {% endif %} + + </td> <td> - {% if "twitch" in item.type %} - <i text='twitch' class="twitch inverted purple bordered icon"></i> - {% elif "youtube" in item.type %} - <i class="youtube red bordered inverted icon"></i> - {% elif "game" in item.type %} - <i class="game blue bordered inverted icon"></i> - {% elif "article" in item.type %} - <i class="rss orange bordered inverted icon"></i> - {% else %} - <i class="soundcloud blue bordered inverted icon"></i> - {% endif %} + {{ item.title }} </td> + <td>{{ item.date|strftime}}</td> <td> - {% if not "gog" in item.name %} - <a href="/details/{{ item.name }}"> - <img alt="{{ item.name }} icon" src="{{ url_for('static', filename='images/icons/')}}{{ item.icon }} "> - </a> - {% else %} - <img alt="{{ item.name }} icon" src="{{ url_for('static', filename='images/icons/')}}{{ item.icon }} "> - {% endif %} - + <a href="{{ item.url }}" target="_blank"> + <i class="external alternate olive bordered icon"></i> + </a> </td> - <td> - {{ item.title }} - </td> - <td>{{ item.date|strftime}}</td> - <td> - <a href="{{ item.url }}" target="_blank"> - <i class="external alternate olive bordered icon"></i> - </a> - </td> - </tr> -{% endmacro %}- \ No newline at end of file + </tr> + {% endfor %} + </tbody> +</table> + + +{% endmacro %} diff --git a/linuxgaming/templates/pages/details.html b/linuxgaming/templates/pages/details.html @@ -36,22 +36,7 @@ </div> -<table class="ui striped very compact small olive table"> - <thead> - <tr> - <th>Type</th> - <th>Source</th> - <th>Title</th> - <th>Released</th> - <th>Link</th> - </tr> - </thead> - <tbody> - {% for e in items %} - {{ show_item(e) }} - {% endfor %} - </tbody> -</table> +{{ show_item(entries) }} {% endblock %} diff --git a/linuxgaming/templates/pages/games.html b/linuxgaming/templates/pages/games.html @@ -1,35 +0,0 @@ -{% extends "base.html" %} -{% from "macros/cards.html" import show_card with context %} - -{% block content %} - -{% with messages = get_flashed_messages() %} - {% if messages %} - {% for message in messages %} - <div class="ui massive red icon message"> - <i class="spinner loading icon"></i> - <div class="content"> - <div class="header"> - {{ message }} - </div> - </div> - </div> - {% endfor %} - {% endif %} -{% endwith %} - -<div class="ui horizontal divider"> - {{ count }} {{ source }} Results -</div> - -<div class="ui three cards"> - - {% for e in entries %} - {{ show_card(e) }} - {% endfor %} - -</div> - -{% endblock %} - - diff --git a/linuxgaming/templates/pages/home.html b/linuxgaming/templates/pages/home.html @@ -19,25 +19,11 @@ {% endwith %} <div class="ui horizontal divider"> - Last 24 hours + Last 48 hours </div> -<table class="ui striped very compact small olive table"> - <thead> - <tr> - <th>Type</th> - <th data-tooltip="Click the source to filter just them!" data-position="top center">Source</th> - <th>Title</th> - <th>Released</th> - <th>Link</th> - </tr> - </thead> - <tbody> - {% for e in entries %} - {{ show_item(e) }} - {% endfor %} - </tbody> -</table> +{{ show_item(entries) }} + {% endblock %} diff --git a/linuxgaming/templates/pages/search.html b/linuxgaming/templates/pages/search.html @@ -7,22 +7,8 @@ {{ count }} Results </div> -<table class="ui striped very compact small olive table"> - <thead> - <tr> - <th>Type</th> - <th data-tooltip="Click the source to filter just them!" data-position="top center">Source</th> - <th>Title</th> - <th>Released</th> - <th>Link</th> - </tr> - </thead> - <tbody> - {% for e in entries %} - {{ show_item(e) }} - {% endfor %} - </tbody> -</table> +{{ show_item(entries) }} + {% endblock %} diff --git a/linuxgaming/update.py b/linuxgaming/update.py @@ -1,3 +1,7 @@ +""" +module for updating various sources. + +""" from googleapiclient.discovery import build from twitch import TwitchClient from flask import Blueprint, render_template, current_app @@ -5,11 +9,16 @@ import dateutil.parser from . import database from . import util -bp = Blueprint('update', __name__, url_prefix='/update') +BP = Blueprint('update', __name__, url_prefix='/update') -@bp.route('/rss', methods=["GET"]) +@BP.route('/rss', methods=["GET"]) def rss_update(): + """ + update sources with rss feeds + + :return: Flask render_template + """ # load sources config feed_config = util.load_yaml() @@ -59,8 +68,13 @@ def rss_update(): return render_template("message.html", msg="RSS feeds updated!") -@bp.route('/twitch', methods=["GET"]) +@BP.route('/twitch', methods=["GET"]) def twitch_update(): + """ + update sources with twitch API + + :return: Flask render_template + """ feed_config = util.load_yaml() @@ -102,9 +116,13 @@ def twitch_update(): return render_template("message.html", msg="Twitch API updated!") -@bp.route('/youtube', methods=["GET"]) +@BP.route('/youtube', methods=["GET"]) def youtube_update(): + """ + update sources with youtube API + :return: Flask render_template + """ feed_config = util.load_yaml() for section in feed_config: @@ -150,9 +168,13 @@ def youtube_update(): return render_template("message.html", msg="Youtube API updated!") -@bp.route('/gog', methods=["GET"]) +@BP.route('/gog', methods=["GET"]) def gog_update(): + """ + update GoG games via API + :return: Flask render_template + """ from datetime import datetime count = 1 @@ -161,7 +183,9 @@ def gog_update(): game_data = util.get_gog_info(query) for search_result in game_data['products']: - + # GoG API is an arse are returns loads of entries that we + # dont want so all of the following if statements are to + # filter them out if not search_result['worksOn']['Linux']: continue diff --git a/linuxgaming/util.py b/linuxgaming/util.py @@ -1,3 +1,8 @@ +""" +helper module with various functions + +""" + import json import yaml import feedparser @@ -23,20 +28,33 @@ def load_yaml(): def feed_parse(url): + """ + return mongodb cursor results from a find query + + :param url: the feed url to parse + :returns: list + """ # parse the feed and get the results res = feedparser.parse(url) + # check is parse returned with results if res.entries: return res.entries + # no entries then error out, something went wrong current_app.logger.error('FEED parse error %s', url) return None def get_gog_info(query): + """ + query gog api + :param query: query passed to the gog API + :return: json of the query + """ gog_api_url = "https://embed.gog.com/games/ajax/filtered?" response = requests.get(gog_api_url + query)