Save newsletters to html file

This commit is contained in:
JonnyWong16 2018-03-18 21:02:39 -07:00
parent b6bd305694
commit b9b82b23f7
11 changed files with 111 additions and 41 deletions

2
.gitignore vendored
View file

@ -15,7 +15,9 @@
release.lock
version.lock
logs/*
backups/*
cache/*
newsletters/*
*.mmdb
# HTTPS Cert/Key #

View file

@ -49,6 +49,10 @@ DOCUMENTATION :: END
<td>Cache Directory:</td>
<td>${plexpy.CONFIG.CACHE_DIR}</td>
</tr>
<tr>
<td>Newsletter Directory:</td>
<td>${plexpy.CONFIG.NEWSLETTER_DIR}</td>
</tr>
<tr>
<td>GeoLite2 Database:</td>
% if plexpy.CONFIG.GEOIP_DB:

View file

@ -1043,6 +1043,17 @@
<h3>Directories</h3>
</div>
<div class="form-group">
<label for="log_dir">Log Directory</label>
<div class="row">
<div class="col-md-6">
<input type="text" class="form-control directory-settings" id="log_dir" name="log_dir" value="${config['log_dir']}">
<div class="btn-group">
<button class="btn btn-form" type="button" id="clear_logs">Clear Logs</button>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="backup_dir">Backup Directory</label>
<div class="row">
@ -1068,13 +1079,10 @@
</div>
</div>
<div class="form-group">
<label for="log_dir">Log Directory</label>
<label for="newsletter_dir">Newsletter Directory</label>
<div class="row">
<div class="col-md-6">
<input type="text" class="form-control directory-settings" id="log_dir" name="log_dir" value="${config['log_dir']}">
<div class="btn-group">
<button class="btn btn-form" type="button" id="clear_logs">Clear Logs</button>
</div>
<input type="text" class="form-control directory-settings" id="newsletter_dir" name="newsletter_dir" value="${config['newsletter_dir']}">
</div>
</div>
</div>

View file

@ -7,7 +7,7 @@
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tautulli ${title} Newsletter</title>
<title>Tautulli Newsletter - ${title}</title>
<style>
/* -------------------------------------
GLOBAL RESETS
@ -567,7 +567,7 @@
<div class="content" style="box-sizing: border-box;display: block;margin: 0 auto;max-width: 1042px;padding: 10px;">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader" style="color: transparent;display: none;height: 0;max-height: 0;max-width: 0;opacity: 0;overflow: hidden;mso-hide: all;visibility: hidden;width: 0;">Tautulli ${title} Newsletter (${parameters['start_date']} - ${parameters['end_date']})</span>
<span class="preheader">Tautulli Newsletter - ${title}</span>
<table border="0" cellpadding="0" cellspacing="0" class="main" style="border-collapse: separate;mso-table-lspace: 0pt;mso-table-rspace: 0pt;width: 100%;background: #282A2D;border-radius: 3px;color: #ffffff;">

View file

@ -7,7 +7,7 @@
<head>
<meta name="viewport" content="width=device-width"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Tautulli ${title} Newsletter</title>
<title>Tautulli Newsletter - ${title}</title>
<style>
/* -------------------------------------
GLOBAL RESETS
@ -567,7 +567,7 @@
<div class="content">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader">Tautulli ${title} Newsletter (${parameters['start_date']} - ${parameters['end_date']})</span>
<span class="preheader">Tautulli Newsletter - ${title}</span>
<table border="0" cellpadding="0" cellspacing="0" class="main">

View file

@ -167,6 +167,14 @@ def initialize(config_file):
except OSError as e:
logger.error(u"Could not create cache dir '%s': %s" % (CONFIG.CACHE_DIR, e))
if not CONFIG.NEWSLETTER_DIR:
CONFIG.NEWSLETTER_DIR = os.path.join(DATA_DIR, 'newsletters')
if not os.path.exists(CONFIG.NEWSLETTER_DIR):
try:
os.makedirs(CONFIG.NEWSLETTER_DIR)
except OSError as e:
logger.error(u"Could not create newsletter dir '%s': %s" % (CONFIG.NEWSLETTER_DIR, e))
# Initialize the database
logger.info(u"Checking if the database upgrades are required...")
try:

View file

@ -308,6 +308,7 @@ _CONFIG_DEFINITIONS = {
'MONITOR_REMOTE_ACCESS': (int, 'Monitoring', 0),
'MONITORING_INTERVAL': (int, 'Monitoring', 60),
'MONITORING_USE_WEBSOCKET': (int, 'Monitoring', 0),
'NEWSLETTER_DIR': (str, 'General', ''),
'NMA_APIKEY': (str, 'NMA', ''),
'NMA_ENABLED': (int, 'NMA', 0),
'NMA_PRIORITY': (int, 'NMA', 0),
@ -656,7 +657,7 @@ def make_backup(cleanup=False, scheduler=False):
logger.debug(u"Tautulli Config :: Successfully backed up %s to %s" % (plexpy.CONFIG_FILE, backup_file))
return True
else:
logger.warn(u"Tautulli Config :: Failed to backup %s to %s" % (plexpy.CONFIG_FILE, backup_file))
logger.error(u"Tautulli Config :: Failed to backup %s to %s" % (plexpy.CONFIG_FILE, backup_file))
return False

View file

@ -94,7 +94,7 @@ def make_backup(cleanup=False, scheduler=False):
logger.debug(u"Tautulli Database :: Successfully backed up %s to %s" % (db_filename(), backup_file))
return True
else:
logger.warn(u"Tautulli Database :: Failed to backup %s to %s" % (db_filename(), backup_file))
logger.error(u"Tautulli Database :: Failed to backup %s to %s" % (db_filename(), backup_file))
return False

View file

@ -13,6 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import os
import time
from apscheduler.schedulers.background import BackgroundScheduler
@ -78,7 +79,8 @@ def notify(newsletter_id=None, notify_action=None, **kwargs):
notify_action=notify_action,
subject=newsletter_agent.subject,
start_date=newsletter_agent.start_date.format('YYYY-MM-DD'),
end_date=newsletter_agent.end_date.format('YYYY-MM-DD'))
end_date=newsletter_agent.end_date.format('YYYY-MM-DD'),
newsletter_uuid=newsletter_agent.uuid)
# Send the notification
success = newsletter_agent.send()
@ -88,13 +90,13 @@ def notify(newsletter_id=None, notify_action=None, **kwargs):
return True
def set_notify_state(newsletter, notify_action, subject, start_date, end_date):
def set_notify_state(newsletter, notify_action, subject, start_date, end_date, newsletter_uuid):
if newsletter and notify_action:
db = database.MonitorDatabase()
keys = {'timestamp': int(time.time()),
'uuid': generate_newsletter_uuid()}
'uuid': newsletter_uuid}
values = {'newsletter_id': newsletter['id'],
'agent_id': newsletter['agent_id'],
@ -118,22 +120,32 @@ def set_notify_success(newsletter_log_id):
db.upsert(table_name='newsletter_log', key_dict=keys, value_dict=values)
def generate_newsletter_uuid():
uuid = ''
uuid_exists = 0
db = database.MonitorDatabase()
while not uuid or uuid_exists:
uuid = plexpy.generate_uuid()[:8]
result = db.select_single(
'SELECT EXISTS(SELECT uuid FROM newsletter_log WHERE uuid = ?) as uuid_exists', [uuid])
uuid_exists = result['uuid_exists']
return uuid
def get_newsletter(newsletter_uuid):
db = database.MonitorDatabase()
result = db.select_single('SELECT newsletter_id, start_date, end_date FROM newsletter_log '
'WHERE uuid = ?', [newsletter_uuid])
return result
if result:
newsletter_id = result['newsletter_id']
start_date = result['start_date']
end_date = result['end_date']
newsletter_file = 'newsletter_%s-%s_%s.html' % (start_date.replace('-', ''),
end_date.replace('-', ''),
newsletter_uuid)
newsletter_folder = plexpy.CONFIG.NEWSLETTER_DIR
newsletter_file_fp = os.path.join(newsletter_folder, newsletter_file)
if newsletter_file in os.listdir(newsletter_folder):
try:
with open(newsletter_file_fp, 'r') as n_file:
newsletter = n_file.read()
return newsletter
except OSError as e:
logger.error(u"Tautulli NewsletterHandler :: Failed to retrieve newsletter '%s': %s" % (newsletter_uuid, e))
return "Failed to retrieve newsletter"
else:
logger.warn(u"Tautulli NewsletterHandler :: Newsletter '%s' file is missing." % newsletter_uuid)
return "Newsletter no longer exists"
else:
return "Newsletter does not exist"

View file

@ -259,6 +259,20 @@ def serve_template(templatename, **kwargs):
return exceptions.html_error_template().render()
def generate_newsletter_uuid():
uuid = ''
uuid_exists = 0
db = database.MonitorDatabase()
while not uuid or uuid_exists:
uuid = plexpy.generate_uuid()[:8]
result = db.select_single(
'SELECT EXISTS(SELECT uuid FROM newsletter_log WHERE uuid = ?) as uuid_exists', [uuid])
uuid_exists = result['uuid_exists']
return uuid
class Newsletter(object):
NAME = ''
_DEFAULT_CONFIG = {'last_days': 7}
@ -307,6 +321,8 @@ class Newsletter(object):
self.subject = self.format_subject(self.email_config['subject'])
self.uuid = generate_newsletter_uuid()
self.is_preview = False
self.data = {}
@ -355,7 +371,7 @@ class Newsletter(object):
return serve_template(
templatename=template,
title=self.NAME,
title=self.subject,
parameters=self.parameters,
data=self.data,
preview=self.is_preview
@ -364,6 +380,30 @@ class Newsletter(object):
def send(self):
newsletter = self.generate_newsletter()
self._save(newsletter)
return self._send(newsletter)
def _save(self, newsletter):
newsletter_file = 'newsletter_%s-%s_%s.html' % (self.start_date.format('YYYYMMDD'),
self.end_date.format('YYYYMMDD'),
self.uuid)
newsletter_folder = plexpy.CONFIG.NEWSLETTER_DIR
newsletter_file_fp = os.path.join(newsletter_folder, newsletter_file)
# In case the user has deleted it manually
if not os.path.exists(newsletter_folder):
os.makedirs(newsletter_folder)
try:
with open(newsletter_file_fp, 'w') as n_file:
n_file.write(newsletter)
logger.info(u"Tautulli Newsletters :: %s newsletter saved to %s" % (self.NAME, newsletter_file))
except OSError as e:
logger.error(u"Tautulli Newsletters :: Failed to save %s newsletter to %s: %s"
% (self.NAME, newsletter_file, e))
def _send(self, newsletter):
if not self._has_data():
logger.warn(u"Tautulli Newsletters :: %s newsletter has no data. Newsletter not sent." % self.NAME)
return False

View file

@ -2658,7 +2658,8 @@ class WebInterface(object):
"music_watched_percent": plexpy.CONFIG.MUSIC_WATCHED_PERCENT,
"themoviedb_lookup": checked(plexpy.CONFIG.THEMOVIEDB_LOOKUP),
"tvmaze_lookup": checked(plexpy.CONFIG.TVMAZE_LOOKUP),
"show_advanced_settings": plexpy.CONFIG.SHOW_ADVANCED_SETTINGS
"show_advanced_settings": plexpy.CONFIG.SHOW_ADVANCED_SETTINGS,
"newsletter_dir": plexpy.CONFIG.NEWSLETTER_DIR
}
return serve_template(templatename="settings.html", title="Settings", config=config, kwargs=kwargs)
@ -5474,7 +5475,7 @@ class WebInterface(object):
@cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi("notify_newsletter")
def send_newsletter(self, newsletter_id=None, subject='Tautulli Newsletter', notify_action='', **kwargs):
def send_newsletter(self, newsletter_id=None, subject='', notify_action='', **kwargs):
""" Send a newsletter using Tautulli.
```
@ -5527,15 +5528,9 @@ class WebInterface(object):
preview=False, master=False, raw=False, **kwargs):
if newsletter_uuid:
newsletter = newsletter_handler.get_newsletter(newsletter_uuid=newsletter_uuid)
return newsletter
if newsletter:
newsletter_id = newsletter['newsletter_id']
start_date = newsletter['start_date']
end_date = newsletter['end_date']
else:
return "This newsletter does not exist"
if newsletter_id:
if newsletter_id and newsletter_id != 'None':
newsletter = newsletters.get_newsletter_config(newsletter_id=newsletter_id)
if newsletter:
@ -5553,7 +5548,7 @@ class WebInterface(object):
return newsletter_agent.generate_newsletter(preview=preview, master=master)
logger.error(u"Failed to retrieve newsletter: Invalid newsletter_id #%s" % newsletter_id)
logger.error(u"Failed to retrieve newsletter: Invalid newsletter_id %s" % newsletter_id)
return "Failed to retrieve newsletter"
logger.error(u"Failed to retrieve newsletter: Missing newsletter_id parameter.")