Compare commits
No commits in common. 'development' and 'main' have entirely different histories.
developmen
...
main
@ -1,158 +0,0 @@ |
|||||||
#!/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', |
|
||||||
) |
|
||||||
) |
|
@ -1,59 +0,0 @@ |
|||||||
#!/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() |
|
@ -1,37 +0,0 @@ |
|||||||
#!/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', |
|
||||||
) |
|
@ -1,126 +0,0 @@ |
|||||||
{% extends "settings_page.html" %} |
|
||||||
|
|
||||||
{% block header_script_files %} |
|
||||||
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> |
|
||||||
{% endblock %} |
|
||||||
|
|
||||||
{% block settings_pane %} |
|
||||||
|
|
||||||
<div id="app"> |
|
||||||
<settings ref="settings" v-bind:settings="settings"></settings> |
|
||||||
<modals ref="modal" v-bind:settings="settings"></modals> |
|
||||||
</div> |
|
||||||
|
|
||||||
{% endblock %} |
|
||||||
|
|
||||||
{% block script %} |
|
||||||
|
|
||||||
Vue.component('settings', { |
|
||||||
props: ['settings'], |
|
||||||
template: ` |
|
||||||
<div class="row r-10 m-2"> |
|
||||||
<div class="col col-12"> |
|
||||||
<div class="row"> |
|
||||||
<div class="col-sm-12 col-md-6 text-center text-md-start"> |
|
||||||
<h2>Thumbnailer</h2> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<hr /> |
|
||||||
<div class="row"> |
|
||||||
<ul class="nav nav-tabs" id="myTab" role="tablist"> |
|
||||||
<li class="nav-item" role="presentation"> |
|
||||||
<button class="nav-link active" id="settings-tab" data-bs-toggle="tab" data-bs-target="#settings" type="button" role="tab" aria-controls="settings" aria-selected="true">Settings</button> |
|
||||||
</li> |
|
||||||
</ul> |
|
||||||
<div class="tab-content py-2" id="myTabContent"> |
|
||||||
<div class="tab-pane fade show active" id="settings" role="tabpanel" aria-labelledby="settings-tab"> |
|
||||||
<div class="row"> |
|
||||||
<table class="table table-striped"> |
|
||||||
<tbody> |
|
||||||
<tr> |
|
||||||
<th scope="row">{{ settings_form.api_key.label.text }}</th><td>[[ settings.PUSHBULLET.api_key ]]</td> |
|
||||||
</tr> |
|
||||||
<tr> |
|
||||||
<th scope="row">{{ settings_form.channel.label.text }}</th><td>[[ settings.PUSHBULLET.channel ]]</td> |
|
||||||
</tr> |
|
||||||
</tbody> |
|
||||||
</table> |
|
||||||
</div> |
|
||||||
<div class="row w-100"> |
|
||||||
<div class="col-12 text-end my-2"> |
|
||||||
<button type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#settingsModal">Modify Settings</button> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
`, |
|
||||||
methods: {}, |
|
||||||
delimiters: ["[[","]]"] |
|
||||||
}) |
|
||||||
|
|
||||||
Vue.component('modals',{ |
|
||||||
props: ['settings'], |
|
||||||
template: ` |
|
||||||
<div> |
|
||||||
<div class="modal" id="settingsModal" role="dialog" aria-labelledby="settingsModal" aria-hidden="true"> |
|
||||||
<div class="modal-dialog modal-dialog-centered" role="document"> |
|
||||||
<div class="modal-content"> |
|
||||||
<div class="modal-header"> |
|
||||||
<h5 class="modal-title" id="notesModalTitle"> |
|
||||||
Modify App Settings |
|
||||||
</h5> |
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
|
||||||
</div> |
|
||||||
|
|
||||||
<form method="POST"> |
|
||||||
<div class="modal-body"> |
|
||||||
|
|
||||||
{{ settings_form.csrf_token }} |
|
||||||
|
|
||||||
<div class="mb-3"> |
|
||||||
{{ settings_form.api_key.label }} |
|
||||||
{{ settings_form.api_key(class_='form-control', placeholder=settings_form.api_key.label.text) }} |
|
||||||
</div> |
|
||||||
<div class="mb-3"> |
|
||||||
{{ settings_form.channel.label }} |
|
||||||
{{ settings_form.channel(class_='form-control', placeholder=settings_form.channel.label.text) }} |
|
||||||
</div> |
|
||||||
|
|
||||||
</div> |
|
||||||
<div class="modal-footer"> |
|
||||||
{{ settings_form.settings_button(class_='btn btn-success') }} |
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button> |
|
||||||
</div> |
|
||||||
</form> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
`, |
|
||||||
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 %} |
|
@ -1,6 +0,0 @@ |
|||||||
<li class="nav-item"> |
|
||||||
<a class="nav-link{% if request.path == url_for('pushbullet.pushbullet_settings_page') %} active{% endif %}" href="{{ url_for('pushbullet.pushbullet_settings_page') }}"> |
|
||||||
<i class="fas fa-bell"></i> |
|
||||||
Pushbullet |
|
||||||
</a> |
|
||||||
</li> |
|
Loading…
Reference in new issue