From a5187c751a562af8389ad77b7d90f422a67dd6cd Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 24 Mar 2021 01:31:51 -0500 Subject: [PATCH] Initial development commit --- __init__.py | 158 ++++++++++++++++++++ config.py | 59 ++++++++ forms.py | 37 +++++ templates/pushbullet_settings.html | 126 ++++++++++++++++ templates/pushbullet_tep_settings_menu.html | 6 + 5 files changed, 386 insertions(+) create mode 100644 __init__.py create mode 100644 config.py create mode 100644 forms.py create mode 100644 templates/pushbullet_settings.html create mode 100644 templates/pushbullet_tep_settings_menu.html diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..2b8bcd0 --- /dev/null +++ b/__init__.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""------------------------------------------------------------------------------------------- +-- IMPORTS +-------------------------------------------------------------------------------------------""" + +""" --- PYTHON IMPORTS --- """ +import os +from os.path import dirname, abspath + +""" --- STASHR CORE IMPORTS --- """ +from stashr import log, utils +from stashr import database as stashr_database +from stashr.stashr import stashr_notification, stashr_notification +from stashr.api import create_json_return + +""" --- STASHR PLUGIN IMPORTS --- """ +from . import forms +from .config import pushconfig + +""" --- STASHR PLUGIN DEPENDENCY IMPORTS --- """ +try: + from pushbullet import Pushbullet +except: + utils.install_package('pushbullet.py') + from pushbullet import Pushbullet + +""" --- FLASK EXTENSION IMPORTS --- """ +from flask_login import login_required, current_user + +""" --- STASHR DEPENDENCY IMPORTS --- """ +from flask import Blueprint, render_template, request, redirect, flash, url_for + +""" --- CREATE LOGGER --- """ +logger = log.stashr_logger(__name__) + +"""------------------------------------------------------------------------------------------- +-- PLUGIN +-------------------------------------------------------------------------------------------""" + +__plugin_name__ = "Stashr Pushbullet" +__version__ = "0.1.0" +__author__ = "Stashr" +__description__ = "Send notifications via Pushbullet" + +"""------------------------------ +- PUSHBULLET OBJECT +------------------------------""" + +pb = None +pb_active = False + +"""------------------------------ +- PLUGIN ROUTES +------------------------------""" + +""" --- DEFINE BLUEPRINT --- """ +bp = Blueprint('pushbullet', __name__, root_path=dirname(abspath(__file__)), template_folder='templates', static_folder='static') + +""" --- PAGES --- """ + +@bp.route('/settings', methods=['GET', 'POST']) +@login_required +def pushbullet_settings_page(): + + if current_user.role != 'admin': + flash('Permission Denied', 'error') + return redirect(url_for('index_page')) + + settings_form = forms.settings_form() + + if request.method == 'POST': + if settings_form.validate(): + pushconfig['PUSHBULLET']['api_key'] = settings_form.api_key.data + pushconfig['PUSHBULLET']['channel'] = settings_form.channel.data + pushconfig.write() + define_pushbullet() + flash('Pushbullet Settings Updated', 'success') + else: + for error in settings_form.errors.items(): + flash(f'{error[0]}: {error[1]}', 'error') + + return render_template( + 'pushbullet_settings.html', + title='Pushbullet Settings', + settings_form=settings_form + ) + + +""" --- API --- """ + +@bp.route('/api/settings', methods=['GET']) +def api_get_settings(): + + user = current_user + + if not user.is_authenticated: + api_key = request.args.get('api_key') + if api_key == "": + return create_json_return('100') + user = stashr_database.session \ + .query(stashr_database.Users) \ + .filter(stashr_database.Users.api_key == api_key) \ + .first() + + if user is None: + return create_json_return('100') + + if user.role.lower() != 'admin': + return create_json_return('401') + + settings = pushconfig + + return create_json_return('200', results=settings) + +"""------------------------------ +- PLUGIN FUNCTIONS +------------------------------""" + +# --- Subscribe to stashr_notifications signal --- # +@stashr_notification.connect +def send_notification(*args, **kwargs): + + global pb + global pb_active + + if not pb_active: + define_pushbullet() + + if 'title' in kwargs and 'message' in kwargs: + pb_channel = pb.get_channel(pushconfig['PUSHBULLET']['channel']) + pb_channel.push_note(kwargs['title'], kwargs['message']) + + +def define_pushbullet(): + global pb + global pb_active + try: + pb = Pushbullet(pushconfig['PUSHBULLET']['api_key']) + pb_active = True + except Exception as e: + logger.error(e) + +"""------------------------------ +- REGISTER PLUGIN +------------------------------""" + +def register(): + return dict( + bep=dict( + blueprint=bp, + prefix='/pushbullet' + ), + tep = dict( + settings_menu='pushbullet_tep_settings_menu.html', + ) + ) \ No newline at end of file diff --git a/config.py b/config.py new file mode 100644 index 0000000..3ef0904 --- /dev/null +++ b/config.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""------------------------------------------------------------------------------------------- +-- IMPORTS +-------------------------------------------------------------------------------------------""" + +""" --- PYTHON IMPORTS --- """ +import os, io, shutil +from os.path import dirname, abspath + +from configobj import ConfigObj +from validate import Validator + +"""------------------------------------------------------------------------------------------- +-- PUSHBULLET CONFIG +-------------------------------------------------------------------------------------------""" + +class PushConfig(ConfigObj): + + configspec = u""" +[PUSHBULLET] +api_key = string(default='') +channel = string(default='') + """ + + def __init__(self): + super(PushConfig, self).__init__() + + configspecfile = os.path.join( + dirname(abspath(__file__)), + 'configspec.ini' + ) + + if not os.path.exists(configspecfile): + with open(configspecfile, 'w') as fd: + shutil.copyfileobj(io.StringIO(PushConfig.configspec), fd) + + self.filename = os.path.join( + dirname(abspath(__file__)), + 'config.ini' + ) + self.configspec = configspecfile + self.encoding = "UTF8" + + tmp = ConfigObj(self.filename, configspec=self.configspec, encoding=self.encoding) + validator = Validator() + tmp.validate(validator, copy=True) + + self.merge(tmp) + + if not os.path.exists(self.filename): + self.write() + +"""------------------------------------------------------------------------------------------- +-- CONFIGURATION DEFINITION +-------------------------------------------------------------------------------------------""" + +pushconfig = PushConfig() \ No newline at end of file diff --git a/forms.py b/forms.py new file mode 100644 index 0000000..480c71b --- /dev/null +++ b/forms.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""------------------------------------------------------------------------------------------- +-- IMPORTS +-------------------------------------------------------------------------------------------""" + +""" --- HUEY IMPORT --- """ +""" --- PYTHON IMPORTS --- """ +""" --- STASHR DEPENDENCY IMPORTS --- """ +""" --- STASHR CORE IMPORTS --- """ +from stashr import log, database + +""" --- FLASK EXTENSION IMPORTS --- """ +from flask_wtf import FlaskForm + +from wtforms import StringField, SubmitField +from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError, NumberRange + +""" --- CREATE LOGGER --- """ +logger = log.stashr_logger(__name__) + +"""------------------------------------------------------------------------------------------- +-- FORMS +-------------------------------------------------------------------------------------------""" + +class settings_form(FlaskForm): + + api_key = StringField( + 'Pushbullet API Key', + ) + channel = StringField( + 'Pushbullet Channel', + ) + settings_button = SubmitField( + 'Save', + ) diff --git a/templates/pushbullet_settings.html b/templates/pushbullet_settings.html new file mode 100644 index 0000000..9f67c93 --- /dev/null +++ b/templates/pushbullet_settings.html @@ -0,0 +1,126 @@ +{% extends "settings_page.html" %} + +{% block header_script_files %} + +{% endblock %} + +{% block settings_pane %} + +
+ + +
+ +{% endblock %} + +{% block script %} + +Vue.component('settings', { + props: ['settings'], + template: ` +
+
+
+
+

Thumbnailer

+
+
+
+
+ +
+
+
+ + + + + + + + + +
{{ settings_form.api_key.label.text }}[[ settings.PUSHBULLET.api_key ]]
{{ settings_form.channel.label.text }}[[ settings.PUSHBULLET.channel ]]
+
+
+
+ +
+
+
+
+
+
+
+ `, + methods: {}, + delimiters: ["[[","]]"] +}) + +Vue.component('modals',{ + props: ['settings'], + template: ` +
+ +
+ `, + methods: {}, + delimiters: ["[[","]]"] +}) + +var app = new Vue({ + el: '#app', + data: { + settings: [] + }, + created() { + this.getSettings() + }, + methods: { + getSettings() { + axios.get('{{ url_for('pushbullet.api_get_settings') }}') + .then(res => { + this.settings = res.data.results; + }) + } + }, + delimiters: ["[[","]]"] +}) + +{% endblock %} \ No newline at end of file diff --git a/templates/pushbullet_tep_settings_menu.html b/templates/pushbullet_tep_settings_menu.html new file mode 100644 index 0000000..ccae8b7 --- /dev/null +++ b/templates/pushbullet_tep_settings_menu.html @@ -0,0 +1,6 @@ + \ No newline at end of file