another huge refactor - linuxgaming - Linux gaming aggregate tool, built to test out NodeJS.
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit d63baf1c3958f7983396c41caa4d1e15a2f4b21d
 (DIR) parent c12dc577e91ea897c3e0f7a1567fa0f98f853f40
 (HTM) Author: Jay Scott <me@jay.scot>
       Date:   Thu, 19 Jul 2018 20:21:38 +0100
       
       another huge refactor
       
       Diffstat:
         M CHANGELOG                           |      36 ++++++++++++++++++-------------
         M TODO.md                             |      14 ++++++--------
         M linuxgaming/__init__.py             |       8 ++++----
         M linuxgaming/details.py              |      11 ++++++++---
         M linuxgaming/search.py               |      23 +++++++++++++++++------
         D linuxgaming/templates/macros/cards… |      26 --------------------------
         M linuxgaming/templates/macros/items… |      82 ++++++++++++++++++-------------
         M linuxgaming/templates/pages/detail… |      17 +----------------
         D linuxgaming/templates/pages/games.… |      35 -------------------------------
         M linuxgaming/templates/pages/home.h… |      20 +++-----------------
         M linuxgaming/templates/pages/search… |      18 ++----------------
         M linuxgaming/update.py               |      36 ++++++++++++++++++++++++++------
         M linuxgaming/util.py                 |      18 ++++++++++++++++++
       
       13 files changed, 159 insertions(+), 185 deletions(-)
       ---
 (DIR) 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
 (DIR) 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
 (DIR) 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)
 (DIR) 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)
 (DIR) 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'))
 (DIR) 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
 (DIR) 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 %}
 (DIR) 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 %}
        
 (DIR) 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 %}
       -
       -
 (DIR) 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 %}
        
        
 (DIR) 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 %}
        
        
 (DIR) 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
        
 (DIR) 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)