Rename PlexPy to Tautulli

This commit is contained in:
JonnyWong16 2017-12-10 23:07:32 -08:00
parent 55bdde808b
commit 19f029cff0
50 changed files with 867 additions and 870 deletions

View file

@ -6,20 +6,20 @@
# -*- coding: utf-8 -*-
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import os
import sys
@ -43,11 +43,11 @@ signal.signal(signal.SIGTERM, plexpy.sig_handler)
def main():
"""
PlexPy application entry point. Parses arguments, setups encoding and
Tautulli application entry point. Parses arguments, setups encoding and
initializes the application.
"""
# Fixed paths to PlexPy
# Fixed paths to Tautulli
if hasattr(sys, 'frozen'):
plexpy.FULL_PATH = os.path.abspath(sys.executable)
else:
@ -81,9 +81,9 @@ def main():
parser.add_argument(
'-d', '--daemon', action='store_true', help='Run as a daemon')
parser.add_argument(
'-p', '--port', type=int, help='Force PlexPy to run on a specified port')
'-p', '--port', type=int, help='Force Tautulli to run on a specified port')
parser.add_argument(
'--dev', action='store_true', help='Start PlexPy in the development environment')
'--dev', action='store_true', help='Start Tautulli in the development environment')
parser.add_argument(
'--datadir', help='Specify a directory where to store your data files')
parser.add_argument(
@ -93,7 +93,7 @@ def main():
parser.add_argument(
'--pidfile', help='Create a pid file (only relevant when running as a daemon)')
parser.add_argument(
'--nofork', action='store_true', help='Start PlexPy as a service, do not fork when restarting')
'--nofork', action='store_true', help='Start Tautulli as a service, do not fork when restarting')
args = parser.parse_args()
@ -108,7 +108,7 @@ def main():
if args.dev:
plexpy.DEV = True
logger.debug(u"PlexPy is running in the dev environment.")
logger.debug(u"Tautulli is running in the dev environment.")
if args.daemon:
if sys.platform == 'win32':
@ -120,7 +120,7 @@ def main():
if args.nofork:
plexpy.NOFORK = True
logger.info("PlexPy is running as a service, it will not fork when restarted.")
logger.info("Tautulli is running as a service, it will not fork when restarted.")
if args.pidfile:
plexpy.PIDFILE = str(args.pidfile)

View file

@ -1,8 +1,8 @@
# PlexPy
# Tautulli
[![Discord](https://img.shields.io/badge/Discord-PlexPy-738bd7.svg?style=flat-square)](https://discord.gg/36ggawe)
[![Gitter](https://img.shields.io/badge/Gitter-PlexPy-ed1965.svg?style=flat-square)](https://gitter.im/plexpy/general)
[![Plex Forums](https://img.shields.io/badge/Plex%20Forums-PlexPy-E5A00D.svg?style=flat-square)](https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program)
[![Discord](https://img.shields.io/badge/Discord-Tautulli-7289DA.svg?style=flat-square)](https://discord.gg/36ggawe)
[![Reddit](https://img.shields.io/badge/Reddit-Tautulli-FF5700.svg?style=flat-square)](https://discord.gg/36ggawe)
[![Plex Forums](https://img.shields.io/badge/Plex%20Forums-Tautulli-E5A00D.svg?style=flat-square)](https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program)
A python based web application for monitoring, analytics and notifications for [Plex Media Server](https://plex.tv).
@ -29,11 +29,11 @@ This project is based on code from [Headphones](https://github.com/rembo10/headp
* [Full preview gallery on Imgur](https://imgur.com/a/RwQPM)
![PlexPy Homepage](https://i.imgur.com/0D0uFJg.jpg)
![Tautulli Homepage](https://i.imgur.com/0D0uFJg.jpg)
## Installation and Support
* [Installation Guides](https://github.com/JonnyWong16/plexpy/wiki/Installation) shows you how to install PlexPy.
* [Installation Guides](https://github.com/JonnyWong16/plexpy/wiki/Installation) shows you how to install Tautulli.
* [FAQs](https://github.com/JonnyWong16/plexpy/wiki/Frequently-Asked-Questions-(FAQ)) in the wiki can help you with common problems.
**Support** the project by implementing new features, solving support tickets and provide bug fixes.

View file

@ -50,7 +50,7 @@
% if _session['user_group'] == 'admin':
% if plexpy.CONFIG.CHECK_GITHUB and not plexpy.CURRENT_VERSION:
<div id="updatebar" style="display: none;">
You're running an unknown version of PlexPy.<br />
You're running an unknown version of Tautulli.<br />
<a href="update">Update</a> or <a href="#" id="updateDismiss">Close</a>
</div>
% elif plexpy.CONFIG.CHECK_GITHUB and plexpy.CURRENT_VERSION != plexpy.LATEST_VERSION and plexpy.COMMITS_BEHIND > 0 and plexpy.INSTALL_TYPE != 'win':
@ -210,13 +210,13 @@ ${next.modalIncludes()}
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
<h4 class="modal-title">PlexPy Donation</h4>
<h4 class="modal-title">Tautulli Donation</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12" style="text-align: center;">
<h4>
<strong>Thank you for supporting PlexPy!</strong>
<strong>Thank you for supporting Tautulli!</strong>
</h4>
<p>
Please select a donation method.
@ -236,7 +236,7 @@ ${next.modalIncludes()}
<p>
Click the button below to continue to PayPal.
</p>
<a href="${anon_url('https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=6XPPKTDSX9QFL&lc=US&item_name=PlexPy&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted')}" target="_blank">
<a href="${anon_url('https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=6XPPKTDSX9QFL&lc=US&item_name=Tautulli&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted')}" target="_blank">
<img src="images/gold-rect-paypal-34px.png" alt="PayPal">
</a>
</div>
@ -244,7 +244,7 @@ ${next.modalIncludes()}
<p>
Click the button below to continue to Flattr.
</p>
<a href="${anon_url('https://flattr.com/submit/auto?user_id=JonnyWong16&url=https://github.com/JonnyWong16/plexpy&title=PlexPy&language=en_GB&tags=github&category=software')}" target="_blank">
<a href="${anon_url('https://flattr.com/submit/auto?user_id=JonnyWong16&url=https://github.com/JonnyWong16/plexpy&title=Tautulli&language=en_GB&tags=github&category=software')}" target="_blank">
<img src="images/flattr-badge-large.png" alt="Flattr">
</a>
</div>
@ -306,7 +306,7 @@ ${next.modalIncludes()}
}
$("#nav-shutdown").click(function() {
$("#confirm-message").text("Are you sure you want to shutdown PlexPy?");
$("#confirm-message").text("Are you sure you want to shutdown Tautulli?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
window.location.href = "shutdown";
@ -314,7 +314,7 @@ ${next.modalIncludes()}
});
$("#nav-restart").click(function() {
$("#confirm-message").text("Are you sure you want to restart PlexPy?");
$("#confirm-message").text("Are you sure you want to restart Tautulli?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
window.location.href = "restart";

View file

@ -77,17 +77,16 @@ DOCUMENTATION :: END
<a id="source-link" class="no-highlight" href="${anon_url('https://github.com/%s/plexpy' % plexpy.CONFIG.GIT_USER)}" target="_blank">GitHub Source</a> |
<a class="no-highlight guidelines-modal-link" href="${anon_url('https://github.com/%s/plexpy/issues' % plexpy.CONFIG.GIT_USER)}" data-id="issue">GitHub Issues</a> |
<a class="no-highlight guidelines-modal-link" href="${anon_url('http://feathub.com/%s/plexpy' % plexpy.CONFIG.GIT_USER)}" data-id="feature request">FeatHub Feature Requests</a> |
<a class="no-highlight" href="${anon_url('https://github.com/%s/plexpy/wiki' % plexpy.CONFIG.GIT_USER)}" target="_blank">PlexPy Wiki</a> |
<a id="faq-source-link" class="no-highlight" href="${anon_url('https://github.com/%s/plexpy/wiki/Frequently-Asked-Questions-(FAQ)' % plexpy.CONFIG.GIT_USER)}" target="_blank">PlexPy FAQ</a>
<a class="no-highlight" href="${anon_url('https://github.com/%s/plexpy/wiki' % plexpy.CONFIG.GIT_USER)}" target="_blank">Tautulli Wiki</a> |
<a id="faq-source-link" class="no-highlight" href="${anon_url('https://github.com/%s/plexpy/wiki/Frequently-Asked-Questions-(FAQ)' % plexpy.CONFIG.GIT_USER)}" target="_blank">Tautulli FAQ</a>
</td>
</tr>
<tr>
<td>Support:</td>
<td>
<a class="no-highlight support-modal-link" href="${anon_url('https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program')}" target="_blank">Plex Forums</a> |
<a class="no-highlight support-modal-link" href="${anon_url('https://gitter.im/plexpy/general')}" target="_blank">PlexPy Gitter Chat</a> |
<a id="best-support-link" class="no-highlight support-modal-link" href="${anon_url('https://discord.gg/011TFFWSuNFI02EKr')}" target="_blank">/r/Plex Discord Server</a> |
<a class="no-highlight support-modal-link" href="${anon_url('https://discord.gg/36ggawe')}" target="_blank">PlexPy Discord Server</a>
<a class="no-highlight support-modal-link" href="${anon_url('https://discord.gg/36ggawe')}" target="_blank">Tautulli Discord Server</a> |
<a class="no-highlight support-modal-link" href="${anon_url('https://www.reddit.com/r/Tautulli')}" target="_blank">Tautulli Subreddit</a> |
<a class="no-highlight support-modal-link" href="${anon_url('https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program')}" target="_blank">Plex Forums</a>
</td>
</tr>
</tbody>
@ -99,7 +98,7 @@ DOCUMENTATION :: END
var msg = 'Are you sure you want to install the GeoLite2 database?<br /><br />' +
'The database is used to lookup IP address geolocation info.<br />' +
'The database will be downloaded from <a href="${anon_url("https://dev.maxmind.com/geoip/geoip2/geolite2/")}" target="_blank">MaxMind</a>, <br />' +
'and requires <strong>100MB</strong> of free space to install in your PlexPy directory.<br />'
'and requires <strong>100MB</strong> of free space to install in your Tautulli directory.<br />'
var url = 'install_geoip_db';
confirmAjaxCall(url, msg, null, 'Installing GeoLite2 database.', getConfigurationTable);
});

View file

@ -45,7 +45,7 @@ DOCUMENTATION :: END
<input type="text" class="form-control" id="custom_thumb_url" name="custom_thumb_url" value="${data['library_thumb']}">
</div>
</div>
<p class="help-block">Change the library's picture in PlexPy. To reset to default, leave this field empty and save.</p>
<p class="help-block">Change the library's picture in Tautulli. To reset to default, leave this field empty and save.</p>
</div>
<div class="checkbox">
<label>

View file

@ -54,7 +54,7 @@ DOCUMENTATION :: END
<input type="text" class="form-control" id="custom_avatar_url" name="custom_avatar_url" value="${data['user_thumb']}">
</div>
</div>
<p class="help-block">Change the users profile picture in PlexPy. To reset to default, leave this field empty and save.</p>
<p class="help-block">Change the users profile picture in Tautulli. To reset to default, leave this field empty and save.</p>
</div>
<div class="checkbox">
<label>
@ -72,7 +72,7 @@ DOCUMENTATION :: END
<label>
<input type="checkbox" id="allow_guest" name="allow_guest" value="1" ${helpers.checked(data['allow_guest'])}> Allow Guest Access
</label>
<p class="help-block">Uncheck this if you do not want to allow this user to login to PlexPy.</p>
<p class="help-block">Uncheck this if you do not want to allow this user to login to Tautulli.</p>
</div>
% if data['user_id']:
<div class="form-group">

View file

@ -128,7 +128,7 @@
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
<h4 class="modal-title">PlexPy Updated</h4>
<h4 class="modal-title">Tautulli Updated</h4>
</div>
<div class="modal-body">
</div>

View file

@ -10,11 +10,11 @@
<div class='container-fluid'>
% if config['update_section_ids'] == 1:
<div id="update_section_ids_message" style="text-align: center; margin-top: 20px;">
<i class="fa fa-exclamation-triangle"></i> PlexPy needs to update the Library IDs in your databse. Click the "<strong>Refresh libraries</strong>" button below to begin the update.
<i class="fa fa-exclamation-triangle"></i> Tautulli needs to update the Library IDs in your databse. Click the "<strong>Refresh libraries</strong>" button below to begin the update.
</div>
% elif config['update_section_ids'] == -1:
<div id="update_section_ids_message" style="text-align: center; margin-top: 20px;">
<i class="fa fa-refresh fa-spin"></i> PlexPy is updating library IDs in the database. This could take a few minutes to hours depending on the size of your database.
<i class="fa fa-refresh fa-spin"></i> Tautulli is updating library IDs in the database. This could take a few minutes to hours depending on the size of your database.
<br />
You may leave this page and come back later.
</div>
@ -199,7 +199,7 @@
$("#refresh-libraries-list").click(function () {
if ("${config['update_section_ids']}" == "1") {
$('#update_section_ids_message').html(
'<i class="fa fa-refresh fa-spin"></i> PlexPy is updating library IDs in the database. This could take a few minutes to hours depending on the size of your database.' +
'<i class="fa fa-refresh fa-spin"></i> Tautulli is updating library IDs in the database. This could take a few minutes to hours depending on the size of your database.' +
'<br />' +
'You may leave this page and come back later.');
$(this).prop('disabled', true);

View file

@ -230,7 +230,7 @@ DOCUMENTATION :: END
% else:
<div id="get_file_sizes_message" style="text-align: center; margin-top: 20px; display: none;">
% endif
<i class="fa fa-refresh fa-spin"></i> PlexPy is calculating the file sizes for the library's media info. This could take a few minutes depending on the size of your library.
<i class="fa fa-refresh fa-spin"></i> Tautulli is calculating the file sizes for the library's media info. This could take a few minutes depending on the size of your library.
<br />
You may leave this page and come back later.
</div>

View file

@ -56,8 +56,8 @@
<div class='table-card-back'>
<div>
<ul id="log_tabs" class="nav nav-pills" role="tablist">
<li role="presentation" class="active"><a id="plexpy-logs-btn" href="#tabs-plexpy_log" aria-controls="tabs-plexpy_log" role="tab" data-toggle="tab">PlexPy Logs</a></li>
<li role="presentation"><a id="plexpy-api-logs-btn" href="#tabs-plexpy_api_log" aria-controls="tabs-plexpy_api_log" role="tab" data-toggle="tab">PlexPy API Logs</a></li>
<li role="presentation" class="active"><a id="plexpy-logs-btn" href="#tabs-plexpy_log" aria-controls="tabs-plexpy_log" role="tab" data-toggle="tab">Tautulli Logs</a></li>
<li role="presentation"><a id="plexpy-api-logs-btn" href="#tabs-plexpy_api_log" aria-controls="tabs-plexpy_api_log" role="tab" data-toggle="tab">Tautulli API Logs</a></li>
<li role="presentation"><a id="plex-logs-btn" href="#tabs-plex_log" aria-controls="tabs-plex_log" role="tab" data-toggle="tab">Plex Media Server Logs</a></li>
<li role="presentation"><a id="plex-scanner-logs-btn" href="#tabs-plex_scanner_log" aria-controls="tabs-plex_scanner_log" role="tab" data-toggle="tab">Plex Media Scanner Logs</a></li>
<li role="presentation"><a id="plexpy-websocket-logs-btn" href="#tabs-plex_websocket_log" aria-controls="tabs-plex_websocket_log" role="tab" data-toggle="tab">Plex Websocket Logs</a></li>
@ -386,7 +386,7 @@
$("#clear-logs").click(function () {
var logfile = $(".tab-pane.active").data('logfile')
$("#confirm-message").text("Are you sure you want to clear the PlexPy logs?");
$("#confirm-message").text("Are you sure you want to clear the Tautulli logs?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
$.ajax({
@ -421,7 +421,7 @@
});
$("#clear-notify-logs").click(function () {
$("#confirm-message").text("Are you sure you want to clear the PlexPy notification logs?");
$("#confirm-message").text("Are you sure you want to clear the Tautulli notification logs?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
$.ajax({
@ -442,7 +442,7 @@
});
$("#clear-login-logs").click(function () {
$("#confirm-message").text("Are you sure you want to clear the PlexPy login logs?");
$("#confirm-message").text("Are you sure you want to clear the Tautulli login logs?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
$.ajax({

View file

@ -76,7 +76,7 @@
}
$('#delete-mobile-device').click(function () {
var msg = 'Are you sure you want to unregister the device <strong>${device["device_name"]}</strong> from PlexPy?';
var msg = 'Are you sure you want to unregister the device <strong>${device["device_name"]}</strong> from Tautulli?';
var url = 'delete_mobile_device';
confirmAjaxCall(url, msg, { mobile_device_id: '${device["id"]}' }, null, deleteCallback);
});

View file

@ -262,7 +262,7 @@
<label for="test_subject">Subject Line</label>
<div class="row">
<div class="col-md-12">
<input class="form-control" type="text" id="test_subject" name="test_subject" value="PlexPy">
<input class="form-control" type="text" id="test_subject" name="test_subject" value="Tautulli">
</div>
</div>
<p class="help-block">Set a custom subject line.</p>

View file

@ -49,7 +49,7 @@
<li role="presentation"><a href="#tabs-notification_agents" aria-controls="tabs-notification_agents" role="tab" data-toggle="tab">Notification Agents</a></li>
<li role="presentation"><a href="#tabs-extra_settings" aria-controls="tabs-extra_settings" role="tab" data-toggle="tab">Extra Settings</a></li>
<li role="presentation"><a href="#tabs-import_backups" aria-controls="tabs-import_backups" role="tab" data-toggle="tab">Import & Backups</a></li>
<li role="presentation"><a href="#tabs-android_app" aria-controls="tabs-android_app" role="tab" data-toggle="tab">PlexPy Android App <sup><small>Beta</small></sup></a></li>
<li role="presentation"><a href="#tabs-android_app" aria-controls="tabs-android_app" role="tab" data-toggle="tab">Tautulli Remote Android App <sup><small>beta</small></sup></a></li>
</ul>
</div>
<div class="col-md-9">
@ -62,14 +62,14 @@
</div>
% endif
<div class="padded-header">
<h3>PlexPy Configuration</h3>
<h3>Tautulli Configuration</h3>
</div>
<div id="plexpy-configuration-table">
<div class='text-muted'><i class="fa fa-refresh fa-spin"></i> Loading configuration table...</div>
<br>
</div>
<div class="padded-header">
<h3>PlexPy Scheduled Tasks</h3>
<h3>Tautulli Scheduled Tasks</h3>
</div>
<div id="plexpy-scheduler-table">
<div class='text-muted'><i class="fa fa-refresh fa-spin"></i> Loading scheduler table...</div>
@ -157,14 +157,14 @@
<label>
<input type="checkbox" id="check_github" name="check_github" value="1" ${config['check_github']}> Enable Updates
</label>
<p class="help-block">Check for PlexPy updates periodically.</p>
<p class="help-block">Check for Tautulli updates periodically.</p>
</div>
<div id="git_update_options">
<div class="checkbox">
<label>
<input type="checkbox" id="plexpy_auto_update" name="plexpy_auto_update" value="1" ${config['plexpy_auto_update']}> Update Automatically
</label>
<p class="help-block">Update PlexPy automatically if an update is available.</p>
<p class="help-block">Update Tautulli automatically if an update is available.</p>
</div>
<div class="form-group">
<label for="git_token">GitHub API Token</label>
@ -362,7 +362,7 @@
<label>
<input type="checkbox" name="launch_browser" id="launch_browser" value="1" ${config['launch_browser']}> Launch Browser on Startup
</label>
<p class="help-block">Launch browser pointed to PlexPy on startup.</p>
<p class="help-block">Launch browser pointed to Tautulli on startup.</p>
</div>
<div class="checkbox">
<label>
@ -375,7 +375,7 @@
<label>
<input type="checkbox" class="http-settings" name="https_create_cert" id="https_create_cert" value="1" ${config['https_create_cert']} /> Create Self-signed Certificate
</label>
<p class="help-block">Check to have PlexPy create a self-signed SSL certificate. Uncheck if you want to use your own certificate.</p>
<p class="help-block">Check to have Tautulli create a self-signed SSL certificate. Uncheck if you want to use your own certificate.</p>
</div>
<div id="https_options_self-signed">
<div class="form-group">
@ -385,7 +385,7 @@
<input type="text" class="form-control http-settings" id="https_domain" name="https_domain" value="${config['https_domain']}">
</div>
</div>
<p class="help-block">The domain names used to access PlexPy, separated by commas (,).</p>
<p class="help-block">The domain names used to access Tautulli, separated by commas (,).</p>
</div>
<div class="form-group">
<label for="https_ip">HTTPS IPs</label>
@ -394,7 +394,7 @@
<input type="text" class="form-control http-settings" id="https_ip" name="https_ip" value="${config['https_ip']}">
</div>
</div>
<p class="help-block">The IP addresses used to access PlexPy, separated by commas (,).</p>
<p class="help-block">The IP addresses used to access Tautulli, separated by commas (,).</p>
</div>
</div>
<div class="form-group">
@ -478,10 +478,10 @@
<div class="checkbox">
<label>
<input type="checkbox" id="allow_guest_access" name="allow_guest_access" value="1" ${config['allow_guest_access']}> Allow Guest Access to PlexPy
<input type="checkbox" id="allow_guest_access" name="allow_guest_access" value="1" ${config['allow_guest_access']}> Allow Guest Access to Tautulli
</label>
<span id="allowGuestCheck" style="color: #eb8600; padding-left: 10px;"></span>
<p class="help-block">Allow shared users to login to PlexPy using their Plex.tv account. Individual user access needs to be enabled from Users > Edit Mode.</p>
<p class="help-block">Allow shared users to login to Tautulli using their Plex.tv account. Individual user access needs to be enabled from Users > Edit Mode.</p>
</div>
<div class="padded-header">
@ -492,7 +492,7 @@
<label>
<input type="checkbox" id="api_enabled" name="api_enabled" value="1" ${config['api_enabled']}> Enable API
</label>
<p class="help-block">Allow remote applications to interface with PlexPy.</p>
<p class="help-block">Allow remote applications to interface with Tautulli.</p>
</div>
<div id="apioptions">
<div class="form-group">
@ -525,7 +525,7 @@
<label>
<input type="checkbox" id="monitor_pms_updates" name="monitor_pms_updates" value="1" ${config['monitor_pms_updates']}> Monitor Plex Updates
</label>
<p class="help-block">Enable to have PlexPy check if updates are available for the Plex Media Server.</p>
<p class="help-block">Enable to have Tautulli check if updates are available for the Plex Media Server.</p>
</div>
<div id="pms_update_options">
<div class="form-group">
@ -550,7 +550,7 @@
<input type="checkbox" id="monitor_remote_access" name="monitor_remote_access" value="1" ${config['monitor_remote_access']}> Monitor Plex Remote Access
</label>
<span id="remoteAccessCheck" style="color: #eb8600; padding-left: 10px;"></span>
<p class="help-block">Enable to have PlexPy check if remote access to the Plex Media Server goes down.</p>
<p class="help-block">Enable to have Tautulli check if remote access to the Plex Media Server goes down.</p>
</div>
<div class="form-group has-feedback" id="pms-ip-group">
@ -583,7 +583,7 @@
<label>
<input type="checkbox" id="pms_is_remote" name="pms_is_remote" value="1" ${config['pms_is_remote']}> Remote Server
</label>
<p class="help-block">Check this if your Plex Server is not on the same local network as PlexPy.</p>
<p class="help-block">Check this if your Plex Server is not on the same local network as Tautulli.</p>
</div>
<div class="checkbox">
<label>
@ -626,7 +626,7 @@
<div id="pms_logs_folder_error" class="alert alert-danger settings-alert" role="alert"></div>
</div>
<p class="help-block">
Optional: Set your Plex logs folder to use PlexPy as a log viewer. Plex logs are not needed for PlexPy to function.
Optional: Set your Plex logs folder to use Tautulli as a log viewer. Plex logs are not needed for Tautulli to function.
A complete folder path is required, shortcuts are not recognized, and the logs must be accessible from the machine where PlexPy is installed.
<a href="${anon_url('https://support.plex.tv/hc/en-us/articles/200250417-Plex-Media-Server-Log-Files')}" target="_blank">Click here</a> for help.
</p>
@ -669,13 +669,13 @@
</div>
<div id="refresh_users_interval_error" class="alert alert-danger settings-alert" role="alert"></div>
</div>
<p class="help-block">The interval (in hours) PlexPy will request an updated friends list from Plex.tv. Minimum 1, maximum 24, default 12.</p>
<p class="help-block">The interval (in hours) Tautulli will request an updated friends list from Plex.tv. Minimum 1, maximum 24, default 12.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="refresh_users_on_startup" name="refresh_users_on_startup" value="1" ${config['refresh_users_on_startup']}> Refresh Users List on Startup
</label>
<p class="help-block">Refresh the users list when PlexPy starts.</p>
<p class="help-block">Refresh the users list when Tautulli starts.</p>
</div>
<div class="padded-header">
@ -690,13 +690,13 @@
</div>
<div id="refresh_libraries_interval_error" class="alert alert-danger settings-alert" role="alert"></div>
</div>
<p class="help-block">The interval (in hours) PlexPy will request an updated libraries list from your Plex Media Server. Minimum 1, maximum 24, default 12.</p>
<p class="help-block">The interval (in hours) Tautulli will request an updated libraries list from your Plex Media Server. Minimum 1, maximum 24, default 12.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="refresh_libraries_on_startup" name="refresh_libraries_on_startup" value="1" ${config['refresh_libraries_on_startup']}> Refresh Libraries List on Startup
</label>
<p class="help-block">Refresh the libraries list when PlexPy starts.</p>
<p class="help-block">Refresh the libraries list when Tautulli starts.</p>
</div>
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
@ -743,7 +743,7 @@
</div>
<div id="buffer_wait_error" class="alert alert-danger settings-alert" role="alert"></div>
</div>
<p class="help-block">The value (in seconds) PlexPy should wait before triggering the next buffer warning. 0 to always trigger.</p>
<p class="help-block">The value (in seconds) Tautulli should wait before triggering the next buffer warning. 0 to always trigger.</p>
</div>
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
@ -776,7 +776,7 @@
</div>
<div id="notify_concurrent_threshold_error" class="alert alert-danger settings-alert" role="alert"></div>
</div>
<p class="help-block">The number of concurrent streams by a single user for PlexPy to trigger a notification. Minimum 2.</p>
<p class="help-block">The number of concurrent streams by a single user for Tautulli to trigger a notification. Minimum 2.</p>
</div>
<div class="padded-header">
@ -817,7 +817,7 @@
</label>
<p class="help-block">
Enable to send another recently added notification when adding a new version of existing media.<br />
Note: If multiple versions are available, PlexPy will assume the higher quality one is newer.
Note: If multiple versions are available, Tautulli will assume the higher quality one is newer.
</p>
</div>-->
@ -894,7 +894,7 @@
<label>
<input type="checkbox" id="get_file_sizes" name="get_file_sizes" value="1" ${config['get_file_sizes']}> Calculate Total File Sizes <span style="color: #eb8600; padding-left: 10px;">[experimental]</span>
</label>
<p class="help-block">Enable if you want PlexPy to calculate the total file size for TV Shows/Seasons and Artists/Albums on the media info tables.</p>
<p class="help-block">Enable if you want Tautulli to calculate the total file size for TV Shows/Seasons and Artists/Albums on the media info tables.</p>
</div>
<div class="checkbox">
<label>
@ -1009,7 +1009,7 @@
</div>
<div id="backup_interval_error" class="alert alert-danger settings-alert" role="alert"></div>
</div>
<p class="help-block">The interval (in hours) PlexPy will backup the database and configuration file. Minimum 1, maximum 24, default 6.</p>
<p class="help-block">The interval (in hours) Tautulli will backup the database and configuration file. Minimum 1, maximum 24, default 6.</p>
</div>
<div class="form-group">
<label for="backup_interval">Backup Days</label>
@ -1070,13 +1070,13 @@
<div role="tabpanel" class="tab-pane" id="tabs-android_app">
<div class="padded-header">
<h3>PlexPy Android App</h3>
<h3>Tautulli Remote Android App</h3>
</div>
<div class="form-group">
<label>Get the App</label>
<p class="help-block">
Get the <a href="${anon_url('https://play.google.com/store/apps/details?id=com.williamcomartin.plexpyremote')}" target="_blank">PlexPy Remote</a> app on Google Play<sup>TM</sup> to access PlexPy from your Android device!<br />
Get the <a href="${anon_url('https://play.google.com/store/apps/details?id=com.williamcomartin.plexpyremote')}" target="_blank">Tautulli Remote</a> app on Google Play<sup>TM</sup> to access Tautulli from your Android device!<br />
<span class="google-play-badge">
<a href="${anon_url('https://play.google.com/store/apps/details?id=com.williamcomartin.plexpyremote')}" target="_blank"><img alt="Get it on Google Play" src="images/en-play-badge.png" /></a>
</span>
@ -1189,7 +1189,7 @@
<div class="modal-body" id="modal-text">
<div>
<p class="help-block">
This will attempt to fetch a new Plex.tv token for you. PlexPy does not store your username and password.
This will attempt to fetch a new Plex.tv token for you. Tautulli does not store your username and password.
Note: This will not work on Internet Explorer 9 or lower.
</p>
<div class="form-group">
@ -1421,7 +1421,7 @@
</div>
<div class="modal-body">
<div style="text-align: center; margin-top: 20px; margin-bottom: 20px;">
You have changed settings that require PlexPy to restart.<br />Click the restart button below to restart now.
You have changed settings that require Tautulli to restart.<br />Click the restart button below to restart now.
</div>
</div>
<div class="modal-footer">
@ -1435,25 +1435,25 @@
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
<h4 class="modal-title">Register PlexPy Android App</h4>
<h4 class="modal-title">Register Tautulli Android App</h4>
</div>
<div class="modal-body">
<label>Instructions</label>
<p class="help-block">
Scan the QR code below with the PlexPy Android app to automatically register it with the server (make sure the PlexPy Address below is correct)
Scan the QR code below with the Tautulli Android app to automatically register it with the server (make sure the Tautulli Address below is correct)
or manually enter the connection info and device token into the app settings.
</p>
<label>QR Code</label>
<pre id="api_qr_code" style="text-align: center"></pre>
<label>PlexPy Address</label>
<label>Tautulli Address</label>
<input type="text" class="form-control" id="api_qr_address">
<p class="help-block" id="api_qr_localhost" style="display: none;">
Note: <span class="inline-pre">127.0.0.1</span> and <span class="inline-pre">localhost</span> will not work.
Please enter an internal or external IP address, or hostname or domain instead.
</p>
<p class="help-block" id="api_qr_private" style="display: none;">
Note: This is a private IP address. PlexPy will not be reachable outside of your home network.
Access PlexPy via an externally address or manually enter the address above to generate the QR code for remote access.
Note: This is a private IP address. Tautulli will not be reachable outside of your home network.
Access Tautulli via an externally address or manually enter the address above to generate the QR code for remote access.
</p>
<p class="help-block" id="api_qr_https" style="display: none;">
Note: This URL is not secure. Requests between the app and the server will not be encrypted.
@ -1491,8 +1491,6 @@
}
if ("${kwargs.get('support')}" == 'true') {
$('.support-modal-link').removeClass('no-highlight').css('color','#e9a049');
$('#best-support-link').prepend('<span data-toggle="tooltip" title="Most Active"><i class="fa fa-star"></i></span>&nbsp;')
$('#best-support-link span').tooltip({ container: 'body' });
}
}
});
@ -1628,7 +1626,7 @@ $(document).ready(function() {
initConfigCheckbox('#monitor_pms_updates');
$('#menu_link_shutdown').click(function() {
$('#confirm-message').text("Are you sure you want to shutdown PlexPy?");
$('#confirm-message').text("Are you sure you want to shutdown Tautulli?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
window.location.href = 'shutdown';
@ -1636,7 +1634,7 @@ $(document).ready(function() {
});
$('#menu_link_restart').click(function() {
$("#confirm-message").text("Are you sure you want to restart PlexPy?");
$("#confirm-message").text("Are you sure you want to restart Tautulli?");
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {
window.location.href = 'restart';
@ -1674,31 +1672,31 @@ $(document).ready(function() {
});
$("#backup_config").click(function () {
var msg = 'Are you sure you want to create a backup of the PlexPy config?';
var msg = 'Are you sure you want to create a backup of the Tautulli config?';
var url = 'backup_config';
confirmAjaxCall(url, msg);
});
$("#backup_database").click(function () {
var msg = 'Are you sure you want to create a backup of the PlexPy database?';
var msg = 'Are you sure you want to create a backup of the Tautulli database?';
var url = 'backup_db';
confirmAjaxCall(url, msg);
});
$("#clear_cache").click(function () {
var msg = 'Are you sure you want to clear the PlexPy cache?';
var msg = 'Are you sure you want to clear the Tautulli cache?';
var url = 'delete_cache';
confirmAjaxCall(url, msg);
});
$("#clear_image_cache").click(function () {
var msg = 'Are you sure you want to clear the PlexPy image cache?';
var msg = 'Are you sure you want to clear the Tautulli image cache?';
var url = 'delete_image_cache';
confirmAjaxCall(url, msg);
});
$("#clear_logs").click(function () {
var msg = 'Are you sure you want to clear the PlexPy logs?';
var msg = 'Are you sure you want to clear the Tautulli logs?';
var url = 'delete_logs';
confirmAjaxCall(url, msg);
});
@ -1719,7 +1717,7 @@ $(document).ready(function() {
showMsg('<i class="fa fa-exclamation-circle"></i> Already on the ' + current_remote + ' ' + current_branch + ' branch.', false, true, 5000, true)
} else {
var msg = 'Are you sure you want to switch to the <strong>' + new_remote + '/' + new_branch + '</strong> branch?' +
'<br />Switching branches may cause PlexPy to become unstable.<br /><br />PlexPy will restart.';
'<br />Switching branches may cause Tautulli to become unstable.<br /><br />Tautulli will restart.';
$('#confirm-message').html(msg);
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-button', function () {

View file

@ -22,10 +22,10 @@
<div class="modal-body" id="modal-text">
<div align="center">
% if message == "Shutting Down":
<h3><i class="fa fa-refresh fa-spin"></i> PlexPy is ${message}.</h3>
<h3><i class="fa fa-refresh fa-spin"></i> Tautulli is ${message}.</h3>
<br />
% else:
<h3><i class="fa fa-refresh fa-spin"></i> PlexPy is ${message}.</h3>
<h3><i class="fa fa-refresh fa-spin"></i> Tautulli is ${message}.</h3>
<br />
<h4>Restart in <span class="countdown"></span></h4>
% endif

View file

@ -73,11 +73,11 @@ DOCUMENTATION :: END
<div class='col-md-12'>
% if not update:
<div style="text-align: center; margin-top: 20px;">
<i class="fa fa-exclamation-triangle"></i> PlexPy cannot find this item's metadata. Either this media item is not available in the Plex Media Server library or it has been moved.
<i class="fa fa-exclamation-triangle"></i> Tautulli cannot find this item's metadata. Either this media item is not available in the Plex Media Server library or it has been moved.
</div>
% endif
<div style="text-align: center; margin-top: 20px;">
<i class="fa fa-info-circle"></i> Please select the correct match below to update the PlexPy database.
<i class="fa fa-info-circle"></i> Please select the correct match below to update the Tautulli database.
</div>
<div class='table-card-header'>
<div class="header-bar">
@ -116,7 +116,7 @@ DOCUMENTATION :: END
<div class="summary-content-wrapper">
<div class='col-md-12'>
<div style="text-align: center; margin-top: 20px;">
<i class="fa fa-exclamation-triangle"></i> PlexPy cannot find this item's metadata. Either this media item is not available in the Plex Media Server library or it has been moved.
<i class="fa fa-exclamation-triangle"></i> Tautulli cannot find this item's metadata. Either this media item is not available in the Plex Media Server library or it has been moved.
</div>
</div>
</div>

View file

@ -66,7 +66,7 @@ DOCUMENTATION :: END
<li><a id="history-tab-btn" href="#userHistory" data-toggle="tab">History</a></li>
<li><a id="sync-tab-btn" href="#userSyncItems" data-toggle="tab">Synced Items</a></li>
<li><a id="ip-tab-btn" href="#userAddresses" data-toggle="tab">IP Addresses</a></li>
<li><a id="login-tab-btn" href="#userLogins" data-toggle="tab">PlexPy Logins</a></li>
<li><a id="login-tab-btn" href="#userLogins" data-toggle="tab">Tautulli Logins</a></li>
</ul>
</div>
</div>
@ -278,7 +278,7 @@ DOCUMENTATION :: END
<div class='table-card-header'>
<div class="header-bar">
<span>
<i class="fa fa-sign-in"></i> PlexPy Login for <strong>
<i class="fa fa-sign-in"></i> Tautulli Login for <strong>
<span class="set-username">${data['friendly_name']}</span>
</strong>
</span>

View file

@ -120,7 +120,7 @@ def swizzled_bundleIdentifier(self, original):
return 'ade.plexpy.osxnotify'
if __name__ == '__main__':
notify('PlexPy', 'Test Subtitle', 'Test Body')
notify('Tautulli', 'Test Subtitle', 'Test Body')
""")
f.close()

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import os
from Queue import Queue
@ -170,7 +170,7 @@ def initialize(config_file):
notifiers.blacklist_logger()
mobile_app.blacklist_logger()
# Check if PlexPy has a uuid
# Check if Tautulli has a uuid
if CONFIG.PMS_UUID == '' or not CONFIG.PMS_UUID:
my_uuid = generate_uuid()
CONFIG.__setattr__('PMS_UUID', my_uuid)
@ -182,7 +182,7 @@ def initialize(config_file):
# Write current version to a file, so we know which version did work.
# This allowes one to restore to that version. The idea is that if we
# arrive here, most parts of PlexPy seem to work.
# arrive here, most parts of Tautulli seem to work.
if CURRENT_VERSION:
version_lock_file = os.path.join(DATA_DIR, "version.lock")
@ -309,9 +309,9 @@ def initialize_scheduler():
backup_hours = CONFIG.BACKUP_INTERVAL if 1 <= CONFIG.BACKUP_INTERVAL <= 24 else 6
schedule_job(database.make_backup, 'Backup PlexPy database',
schedule_job(database.make_backup, 'Backup Tautulli database',
hours=backup_hours, minutes=0, seconds=0, args=(True, True))
schedule_job(config.make_backup, 'Backup PlexPy config',
schedule_job(config.make_backup, 'Backup Tautulli config',
hours=backup_hours, minutes=0, seconds=0, args=(True, True))
if WS_CONNECTED and CONFIG.PMS_IP and CONFIG.PMS_TOKEN:
@ -517,7 +517,7 @@ def dbcheck():
'deleted_section INTEGER DEFAULT 0, UNIQUE(server_id, section_id))'
)
# user_login table :: This table keeps record of the PlexPy guest logins
# user_login table :: This table keeps record of the Tautulli guest logins
c_db.execute(
'CREATE TABLE IF NOT EXISTS user_login (id INTEGER PRIMARY KEY AUTOINCREMENT, '
'timestamp INTEGER, user_id INTEGER, user TEXT, user_group TEXT, '
@ -1439,28 +1439,28 @@ def shutdown(restart=False, update=False, checkout=False):
CONFIG.write()
if not restart and not update and not checkout:
logger.info(u"PlexPy is shutting down...")
logger.info(u"Tautulli is shutting down...")
if update:
logger.info(u"PlexPy is updating...")
logger.info(u"Tautulli is updating...")
try:
versioncheck.update()
except Exception as e:
logger.warn(u"PlexPy failed to update: %s. Restarting." % e)
logger.warn(u"Tautulli failed to update: %s. Restarting." % e)
if checkout:
logger.info(u"PlexPy is switching the git branch...")
logger.info(u"Tautulli is switching the git branch...")
try:
versioncheck.checkout_git_branch()
except Exception as e:
logger.warn(u"PlexPy failed to switch git branch: %s. Restarting." % e)
logger.warn(u"Tautulli failed to switch git branch: %s. Restarting." % e)
if CREATEPID:
logger.info(u"Removing pidfile %s", PIDFILE)
os.remove(PIDFILE)
if restart:
logger.info(u"PlexPy is restarting...")
logger.info(u"Tautulli is restarting...")
exe = sys.executable
args = [exe, FULL_PATH]
args += ARGS
@ -1472,10 +1472,10 @@ def shutdown(restart=False, update=False, checkout=False):
if NOFORK:
logger.info('Running as service, not forking. Exiting...')
elif os.name == 'nt':
logger.info('Restarting PlexPy with %s', args)
logger.info('Restarting Tautulli with %s', args)
subprocess.Popen(args, cwd=os.getcwd())
else:
logger.info('Restarting PlexPy with %s', args)
logger.info('Restarting Tautulli with %s', args)
os.execv(exe, args)
os._exit(0)

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import datetime
import threading
@ -86,7 +86,7 @@ class ActivityHandler(object):
if not session:
return
logger.debug(u"PlexPy ActivityHandler :: Session %s started by user %s (%s) with ratingKey %s (%s)."
logger.debug(u"Tautulli ActivityHandler :: Session %s started by user %s (%s) with ratingKey %s (%s)."
% (str(session['session_key']), str(session['user_id']), session['username'],
str(session['rating_key']), session['full_title']))
@ -97,7 +97,7 @@ class ActivityHandler(object):
def on_stop(self, force_stop=False):
if self.is_valid_session():
logger.debug(u"PlexPy ActivityHandler :: Session %s stopped." % str(self.get_session_key()))
logger.debug(u"Tautulli ActivityHandler :: Session %s stopped." % str(self.get_session_key()))
# Set the session last_paused timestamp
ap = activity_processor.ActivityProcessor()
@ -121,13 +121,13 @@ class ActivityHandler(object):
monitor_proc.write_session_history(session=db_session)
# Remove the session from our temp session table
logger.debug(u"PlexPy ActivityHandler :: Removing sessionKey %s ratingKey %s from session queue"
logger.debug(u"Tautulli ActivityHandler :: Removing sessionKey %s ratingKey %s from session queue"
% (str(self.get_session_key()), str(self.get_rating_key())))
ap.delete_session(session_key=self.get_session_key())
def on_pause(self):
if self.is_valid_session():
logger.debug(u"PlexPy ActivityHandler :: Session %s paused." % str(self.get_session_key()))
logger.debug(u"Tautulli ActivityHandler :: Session %s paused." % str(self.get_session_key()))
# Set the session last_paused timestamp
ap = activity_processor.ActivityProcessor()
@ -146,7 +146,7 @@ class ActivityHandler(object):
def on_resume(self):
if self.is_valid_session():
logger.debug(u"PlexPy ActivityHandler :: Session %s resumed." % str(self.get_session_key()))
logger.debug(u"Tautulli ActivityHandler :: Session %s resumed." % str(self.get_session_key()))
# Set the session last_paused timestamp
ap = activity_processor.ActivityProcessor()
@ -165,7 +165,7 @@ class ActivityHandler(object):
def on_buffer(self):
if self.is_valid_session():
logger.debug(u"PlexPy ActivityHandler :: Session %s is buffering." % self.get_session_key())
logger.debug(u"Tautulli ActivityHandler :: Session %s is buffering." % self.get_session_key())
ap = activity_processor.ActivityProcessor()
db_stream = ap.get_session_by_key(session_key=self.get_session_key())
@ -174,7 +174,7 @@ class ActivityHandler(object):
# Get our current buffer count
current_buffer_count = ap.get_session_buffer_count(self.get_session_key())
logger.debug(u"PlexPy ActivityHandler :: Session %s buffer count is %s." %
logger.debug(u"Tautulli ActivityHandler :: Session %s buffer count is %s." %
(self.get_session_key(), current_buffer_count))
# Get our last triggered time
@ -188,7 +188,7 @@ class ActivityHandler(object):
time_since_last_trigger = 0
if buffer_last_triggered:
logger.debug(u"PlexPy ActivityHandler :: Session %s buffer last triggered at %s." %
logger.debug(u"Tautulli ActivityHandler :: Session %s buffer last triggered at %s." %
(self.get_session_key(), buffer_last_triggered))
time_since_last_trigger = int(time.time()) - int(buffer_last_triggered)
@ -341,7 +341,7 @@ class TimelineHandler(object):
RECENTLY_ADDED_QUEUE[rating_key] = set([grandparent_rating_key])
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s, grandparent %s) added to recently added queue."
logger.debug(u"Tautulli TimelineHandler :: Library item '%s' (%s, grandparent %s) added to recently added queue."
% (title, str(rating_key), str(grandparent_rating_key)))
# Schedule a callback to clear the recently added queue
@ -357,7 +357,7 @@ class TimelineHandler(object):
parent_set.add(rating_key)
RECENTLY_ADDED_QUEUE[parent_rating_key] = parent_set
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s , parent %s) added to recently added queue."
logger.debug(u"Tautulli TimelineHandler :: Library item '%s' (%s , parent %s) added to recently added queue."
% (title, str(rating_key), str(parent_rating_key)))
# Schedule a callback to clear the recently added queue
@ -368,7 +368,7 @@ class TimelineHandler(object):
queue_set = RECENTLY_ADDED_QUEUE.get(rating_key, set())
RECENTLY_ADDED_QUEUE[rating_key] = queue_set
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s) added to recently added queue."
logger.debug(u"Tautulli TimelineHandler :: Library item '%s' (%s) added to recently added queue."
% (title, str(rating_key)))
# Schedule a callback to clear the recently added queue
@ -380,13 +380,13 @@ class TimelineHandler(object):
state_type == 5 and metadata_state is None and queue_size is None and \
rating_key in RECENTLY_ADDED_QUEUE:
logger.debug(u"PlexPy TimelineHandler :: Library item '%s' (%s) done processing metadata."
logger.debug(u"Tautulli TimelineHandler :: Library item '%s' (%s) done processing metadata."
% (title, str(rating_key)))
# An item was deleted, make sure it is removed from the queue
elif state_type == 9 and metadata_state == 'deleted':
if rating_key in RECENTLY_ADDED_QUEUE and not RECENTLY_ADDED_QUEUE[rating_key]:
logger.debug(u"PlexPy TimelineHandler :: Library item %s removed from recently added queue."
logger.debug(u"Tautulli TimelineHandler :: Library item %s removed from recently added queue."
% str(rating_key))
del_keys(rating_key)
@ -424,7 +424,7 @@ def force_stop_stream(session_key):
if success:
# If session is written to the databaase successfully, remove the session from the session table
logger.info(u"PlexPy ActivityHandler :: Removing stale stream with sessionKey %s ratingKey %s from session queue"
logger.info(u"Tautulli ActivityHandler :: Removing stale stream with sessionKey %s ratingKey %s from session queue"
% (session['session_key'], session['rating_key']))
ap.delete_session(session_key=session_key)
@ -432,7 +432,7 @@ def force_stop_stream(session_key):
sessions['write_attempts'] += 1
if sessions['write_attempts'] < plexpy.CONFIG.SESSION_DB_WRITE_ATTEMPTS:
logger.warn(u"PlexPy ActivityHandler :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
logger.warn(u"Tautulli ActivityHandler :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
"Will try again in 30 seconds. Write attempt %s."
% (sessions['session_key'], sessions['rating_key'], str(sessions['write_attempts'])))
ap.increment_write_attempts(session_key=session_key)
@ -442,10 +442,10 @@ def force_stop_stream(session_key):
args=[session_key], seconds=30)
else:
logger.warn(u"PlexPy Monitor :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
logger.warn(u"Tautulli Monitor :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
"Removing session from the database. Write attempt %s."
% (sessions['session_key'], sessions['rating_key'], str(sessions['write_attempts'])))
logger.info(u"PlexPy Monitor :: Removing stale stream with sessionKey %s ratingKey %s from session queue"
logger.info(u"Tautulli Monitor :: Removing stale stream with sessionKey %s ratingKey %s from session queue"
% (sessions['session_key'], sessions['rating_key']))
ap.delete_session(session_key=session_key)
@ -478,7 +478,7 @@ def clear_recently_added_queue(rating_key):
def on_created(rating_key, **kwargs):
logger.debug(u"PlexPy TimelineHandler :: Library item %s added to Plex." % str(rating_key))
logger.debug(u"Tautulli TimelineHandler :: Library item %s added to Plex." % str(rating_key))
pms_connect = pmsconnect.PmsConnect()
metadata = pms_connect.get_metadata_details(rating_key)
@ -488,7 +488,7 @@ def on_created(rating_key, **kwargs):
data_factory = datafactory.DataFactory()
if 'child_keys' not in kwargs:
if data_factory.get_recently_added_item(rating_key):
logger.debug(u"PlexPy TimelineHandler :: Library item %s added already. Not notifying again." % str(rating_key))
logger.debug(u"Tautulli TimelineHandler :: Library item %s added already. Not notifying again." % str(rating_key))
notify = False
if notify:
@ -506,4 +506,4 @@ def on_created(rating_key, **kwargs):
logger.debug(u"Added %s items to the recently_added database table." % str(len(all_keys)))
else:
logger.error(u"PlexPy TimelineHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
logger.error(u"Tautulli TimelineHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import threading
import time
@ -41,7 +41,7 @@ def check_active_sessions(ws_request=False):
session_list = pms_connect.get_current_activity()
monitor_db = database.MonitorDatabase()
monitor_process = activity_processor.ActivityProcessor()
logger.debug(u"PlexPy Monitor :: Checking for active streams.")
logger.debug(u"Tautulli Monitor :: Checking for active streams.")
if session_list:
media_container = session_list['sessions']
@ -59,12 +59,12 @@ def check_active_sessions(ws_request=False):
# Here we can check the play states
if session['state'] != stream['state']:
if session['state'] == 'paused':
logger.debug(u"PlexPy Monitor :: Session %s paused." % stream['session_key'])
logger.debug(u"Tautulli Monitor :: Session %s paused." % stream['session_key'])
plexpy.NOTIFY_QUEUE.put({'stream_data': stream, 'notify_action': 'on_pause'})
if session['state'] == 'playing' and stream['state'] == 'paused':
logger.debug(u"PlexPy Monitor :: Session %s resumed." % stream['session_key'])
logger.debug(u"Tautulli Monitor :: Session %s resumed." % stream['session_key'])
plexpy.NOTIFY_QUEUE.put({'stream_data': stream, 'notify_action': 'on_resume'})
@ -96,7 +96,7 @@ def check_active_sessions(ws_request=False):
# Push it on it's own thread so we don't hold up our db actions
# Our first buffer notification
if buffer_values[0]['buffer_count'] == plexpy.CONFIG.BUFFER_THRESHOLD:
logger.info(u"PlexPy Monitor :: User '%s' has triggered a buffer warning."
logger.info(u"Tautulli Monitor :: User '%s' has triggered a buffer warning."
% stream['user'])
# Set the buffer trigger time
monitor_db.action('UPDATE sessions '
@ -110,7 +110,7 @@ def check_active_sessions(ws_request=False):
# Subsequent buffer notifications after wait time
if int(time.time()) > buffer_values[0]['buffer_last_triggered'] + \
plexpy.CONFIG.BUFFER_WAIT:
logger.info(u"PlexPy Monitor :: User '%s' has triggered multiple buffer warnings."
logger.info(u"Tautulli Monitor :: User '%s' has triggered multiple buffer warnings."
% stream['user'])
# Set the buffer trigger time
monitor_db.action('UPDATE sessions '
@ -120,7 +120,7 @@ def check_active_sessions(ws_request=False):
plexpy.NOTIFY_QUEUE.put({'stream_data': stream, 'notify_action': 'on_buffer'})
logger.debug(u"PlexPy Monitor :: Session %s is buffering. Count is now %s. Last triggered %s."
logger.debug(u"Tautulli Monitor :: Session %s is buffering. Count is now %s. Last triggered %s."
% (stream['session_key'],
buffer_values[0]['buffer_count'],
buffer_values[0]['buffer_last_triggered']))
@ -140,7 +140,7 @@ def check_active_sessions(ws_request=False):
else:
# The user has stopped playing a stream
if stream['state'] != 'stopped':
logger.debug(u"PlexPy Monitor :: Session %s stopped." % stream['session_key'])
logger.debug(u"Tautulli Monitor :: Session %s stopped." % stream['session_key'])
if not stream['stopped']:
# Set the stream stop time
@ -164,7 +164,7 @@ def check_active_sessions(ws_request=False):
if success:
# If session is written to the databaase successfully, remove the session from the session table
logger.debug(u"PlexPy Monitor :: Removing sessionKey %s ratingKey %s from session queue"
logger.debug(u"Tautulli Monitor :: Removing sessionKey %s ratingKey %s from session queue"
% (stream['session_key'], stream['rating_key']))
monitor_db.action('DELETE FROM sessions WHERE session_key = ? AND rating_key = ?',
[stream['session_key'], stream['rating_key']])
@ -172,17 +172,17 @@ def check_active_sessions(ws_request=False):
stream['write_attempts'] += 1
if stream['write_attempts'] < plexpy.CONFIG.SESSION_DB_WRITE_ATTEMPTS:
logger.warn(u"PlexPy Monitor :: Failed to write sessionKey %s ratingKey %s to the database. " \
logger.warn(u"Tautulli Monitor :: Failed to write sessionKey %s ratingKey %s to the database. " \
"Will try again on the next pass. Write attempt %s."
% (stream['session_key'], stream['rating_key'], str(stream['write_attempts'])))
monitor_db.action('UPDATE sessions SET write_attempts = ? '
'WHERE session_key = ? AND rating_key = ?',
[stream['write_attempts'], stream['session_key'], stream['rating_key']])
else:
logger.warn(u"PlexPy Monitor :: Failed to write sessionKey %s ratingKey %s to the database. " \
logger.warn(u"Tautulli Monitor :: Failed to write sessionKey %s ratingKey %s to the database. " \
"Removing session from the database. Write attempt %s."
% (stream['session_key'], stream['rating_key'], str(stream['write_attempts'])))
logger.debug(u"PlexPy Monitor :: Removing sessionKey %s ratingKey %s from session queue"
logger.debug(u"Tautulli Monitor :: Removing sessionKey %s ratingKey %s from session queue"
% (stream['session_key'], stream['rating_key']))
monitor_db.action('DELETE FROM sessions WHERE session_key = ? AND rating_key = ?',
[stream['session_key'], stream['rating_key']])
@ -193,11 +193,11 @@ def check_active_sessions(ws_request=False):
new_session = monitor_process.write_session(session)
if new_session:
logger.debug(u"PlexPy Monitor :: Session %s started by user %s with ratingKey %s."
logger.debug(u"Tautulli Monitor :: Session %s started by user %s with ratingKey %s."
% (session['session_key'], session['user_id'], session['rating_key']))
else:
logger.debug(u"PlexPy Monitor :: Unable to read session list.")
logger.debug(u"Tautulli Monitor :: Unable to read session list.")
def check_recently_added():
@ -229,13 +229,13 @@ def check_recently_added():
if metadata:
metadata = [metadata]
else:
logger.error(u"PlexPy Monitor :: Unable to retrieve metadata for rating_key %s" \
logger.error(u"Tautulli Monitor :: Unable to retrieve metadata for rating_key %s" \
% str(item['rating_key']))
else:
metadata = pms_connect.get_metadata_children_details(item['rating_key'])
if not metadata:
logger.error(u"PlexPy Monitor :: Unable to retrieve children metadata for rating_key %s" \
logger.error(u"Tautulli Monitor :: Unable to retrieve children metadata for rating_key %s" \
% str(item['rating_key']))
if metadata:
@ -246,7 +246,7 @@ def check_recently_added():
library_details = library_data.get_details(section_id=item['section_id'])
if 0 < time_threshold - int(item['added_at']) <= time_interval:
logger.debug(u"PlexPy Monitor :: Library item %s added to Plex." % str(item['rating_key']))
logger.debug(u"Tautulli Monitor :: Library item %s added to Plex." % str(item['rating_key']))
plexpy.NOTIFY_QUEUE.put({'timeline_data': item, 'notify_action': 'on_created'})
@ -260,17 +260,17 @@ def check_recently_added():
if metadata:
item = metadata
else:
logger.error(u"PlexPy Monitor :: Unable to retrieve grandparent metadata for grandparent_rating_key %s" \
logger.error(u"Tautulli Monitor :: Unable to retrieve grandparent metadata for grandparent_rating_key %s" \
% str(item['rating_key']))
logger.debug(u"PlexPy Monitor :: Library item %s added to Plex." % str(item['rating_key']))
logger.debug(u"Tautulli Monitor :: Library item %s added to Plex." % str(item['rating_key']))
# Check if any notification agents have notifications enabled
plexpy.NOTIFY_QUEUE.put({'timeline_data': item, 'notify_action': 'on_created'})
def check_server_response():
logger.info(u"PlexPy Monitor :: Attempting to reconnect Plex server...")
logger.info(u"Tautulli Monitor :: Attempting to reconnect Plex server...")
try:
web_socket.start_thread()
except:
@ -294,17 +294,17 @@ def check_server_access():
# Check if the port is mapped
if not mapping_state == 'mapped':
ext_ping_count += 1
logger.warn(u"PlexPy Monitor :: Plex remote access port not mapped, ping attempt %s." \
logger.warn(u"Tautulli Monitor :: Plex remote access port not mapped, ping attempt %s." \
% str(ext_ping_count))
# Check if the port is open
elif mapping_error == 'unreachable':
ext_ping_count += 1
logger.warn(u"PlexPy Monitor :: Plex remote access port mapped, but mapping failed, ping attempt %s." \
logger.warn(u"Tautulli Monitor :: Plex remote access port mapped, but mapping failed, ping attempt %s." \
% str(ext_ping_count))
# Reset external ping counter
else:
if ext_ping_count >= plexpy.CONFIG.REMOTE_ACCESS_PING_THRESHOLD:
logger.info(u"PlexPy Monitor :: Plex remote access is back up.")
logger.info(u"Tautulli Monitor :: Plex remote access is back up.")
plexpy.NOTIFY_QUEUE.put({'notify_action': 'on_extup'})
@ -317,18 +317,18 @@ def check_server_access():
def check_server_updates():
with monitor_lock:
logger.info(u"PlexPy Monitor :: Checking for PMS updates...")
logger.info(u"Tautulli Monitor :: Checking for PMS updates...")
plex_tv = plextv.PlexTV()
download_info = plex_tv.get_plex_downloads()
if download_info:
logger.info(u"PlexPy Monitor :: Current PMS version: %s", plexpy.CONFIG.PMS_VERSION)
logger.info(u"Tautulli Monitor :: Current PMS version: %s", plexpy.CONFIG.PMS_VERSION)
if download_info['update_available']:
logger.info(u"PlexPy Monitor :: PMS update available version: %s", download_info['version'])
logger.info(u"Tautulli Monitor :: PMS update available version: %s", download_info['version'])
plexpy.NOTIFY_QUEUE.put({'notify_action': 'on_pmsupdate', 'pms_download_info': download_info})
else:
logger.info(u"PlexPy Monitor :: No PMS update available.")
logger.info(u"Tautulli Monitor :: No PMS update available.")

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import json
import threading
@ -172,7 +172,7 @@ class ActivityProcessor(object):
if str(session['rating_key']).isdigit() and session['media_type'] in ('movie', 'episode', 'track'):
logging_enabled = True
else:
logger.debug(u"PlexPy ActivityProcessor :: ratingKey %s not logged. Does not meet logging criteria. "
logger.debug(u"Tautulli ActivityProcessor :: ratingKey %s not logged. Does not meet logging criteria. "
u"Media type is '%s'" % (session['rating_key'], session['media_type']))
if str(session['paused_counter']).isdigit():
@ -184,35 +184,35 @@ class ActivityProcessor(object):
if (session['media_type'] == 'movie' or session['media_type'] == 'episode') and \
(real_play_time < int(plexpy.CONFIG.LOGGING_IGNORE_INTERVAL)):
logging_enabled = False
logger.debug(u"PlexPy ActivityProcessor :: Play duration for ratingKey %s is %s secs which is less than %s "
logger.debug(u"Tautulli ActivityProcessor :: Play duration for ratingKey %s is %s secs which is less than %s "
u"seconds, so we're not logging it." %
(session['rating_key'], str(real_play_time), plexpy.CONFIG.LOGGING_IGNORE_INTERVAL))
if not is_import and session['media_type'] == 'track':
if real_play_time < 15 and session['duration'] >= 30:
logging_enabled = False
logger.debug(u"PlexPy ActivityProcessor :: Play duration for ratingKey %s is %s secs, "
logger.debug(u"Tautulli ActivityProcessor :: Play duration for ratingKey %s is %s secs, "
u"looks like it was skipped so we're not logging it" %
(session['rating_key'], str(real_play_time)))
elif is_import and import_ignore_interval:
if (session['media_type'] == 'movie' or session['media_type'] == 'episode') and \
(real_play_time < int(import_ignore_interval)):
logging_enabled = False
logger.debug(u"PlexPy ActivityProcessor :: Play duration for ratingKey %s is %s secs which is less than %s "
logger.debug(u"Tautulli ActivityProcessor :: Play duration for ratingKey %s is %s secs which is less than %s "
u"seconds, so we're not logging it." %
(session['rating_key'], str(real_play_time), import_ignore_interval))
if not is_import and not user_details['keep_history']:
logging_enabled = False
logger.debug(u"PlexPy ActivityProcessor :: History logging for user '%s' is disabled." % user_details['username'])
logger.debug(u"Tautulli ActivityProcessor :: History logging for user '%s' is disabled." % user_details['username'])
elif not is_import and not library_details['keep_history']:
logging_enabled = False
logger.debug(u"PlexPy ActivityProcessor :: History logging for library '%s' is disabled." % library_details['section_name'])
logger.debug(u"Tautulli ActivityProcessor :: History logging for library '%s' is disabled." % library_details['section_name'])
if logging_enabled:
# Fetch metadata first so we can return false if it fails
if not is_import:
logger.debug(u"PlexPy ActivityProcessor :: Fetching metadata for item ratingKey %s" % session['rating_key'])
logger.debug(u"Tautulli ActivityProcessor :: Fetching metadata for item ratingKey %s" % session['rating_key'])
pms_connect = pmsconnect.PmsConnect()
metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']))
if not metadata:
@ -226,7 +226,7 @@ class ActivityProcessor(object):
## TODO: Fix media info from imports. Temporary media info from import session.
media_info = session
# logger.debug(u"PlexPy ActivityProcessor :: Attempting to write to session_history table...")
# logger.debug(u"Tautulli ActivityProcessor :: Attempting to write to session_history table...")
keys = {'id': None}
values = {'started': session['started'],
'stopped': stopped,
@ -251,7 +251,7 @@ class ActivityProcessor(object):
'view_offset': session['view_offset']
}
# logger.debug(u"PlexPy ActivityProcessor :: Writing session_history transaction...")
# logger.debug(u"Tautulli ActivityProcessor :: Writing session_history transaction...")
self.db.upsert(table_name='session_history', key_dict=keys, value_dict=values)
# Check if we should group the session, select the last two rows from the user
@ -290,12 +290,12 @@ class ActivityProcessor(object):
self.db.action(query=query, args=args)
# logger.debug(u"PlexPy ActivityProcessor :: Successfully written history item, last id for session_history is %s"
# logger.debug(u"Tautulli ActivityProcessor :: Successfully written history item, last id for session_history is %s"
# % last_id)
# Write the session_history_media_info table
# logger.debug(u"PlexPy ActivityProcessor :: Attempting to write to session_history_media_info table...")
# logger.debug(u"Tautulli ActivityProcessor :: Attempting to write to session_history_media_info table...")
keys = {'id': last_id}
values = {'rating_key': session['rating_key'],
'video_decision': session['video_decision'],
@ -357,7 +357,7 @@ class ActivityProcessor(object):
'optimized_version_profile': session['optimized_version_profile']
}
# logger.debug(u"PlexPy ActivityProcessor :: Writing session_history_media_info transaction...")
# logger.debug(u"Tautulli ActivityProcessor :: Writing session_history_media_info transaction...")
self.db.upsert(table_name='session_history_media_info', key_dict=keys, value_dict=values)
# Write the session_history_metadata table
@ -367,7 +367,7 @@ class ActivityProcessor(object):
genres = ";".join(metadata['genres'])
labels = ";".join(metadata['labels'])
# logger.debug(u"PlexPy ActivityProcessor :: Attempting to write to session_history_metadata table...")
# logger.debug(u"Tautulli ActivityProcessor :: Attempting to write to session_history_metadata table...")
keys = {'id': last_id}
values = {'rating_key': session['rating_key'],
'parent_rating_key': session['parent_rating_key'],
@ -403,7 +403,7 @@ class ActivityProcessor(object):
'labels': labels
}
# logger.debug(u"PlexPy ActivityProcessor :: Writing session_history_metadata transaction...")
# logger.debug(u"Tautulli ActivityProcessor :: Writing session_history_metadata transaction...")
self.db.upsert(table_name='session_history_metadata', key_dict=keys, value_dict=values)
# Return true when the session is successfully written to the database

View file

@ -1,20 +1,20 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import hashlib
@ -129,15 +129,15 @@ class API2:
self._api_kwargs = kwargs
if self._api_msg:
logger.api_debug(u'PlexPy APIv2 :: %s.' % self._api_msg)
logger.api_debug(u'Tautulli APIv2 :: %s.' % self._api_msg)
logger.api_debug(u'PlexPy APIv2 :: Cleaned kwargs: %s' % self._api_kwargs)
logger.api_debug(u'Tautulli APIv2 :: Cleaned kwargs: %s' % self._api_kwargs)
return self._api_kwargs
def get_logs(self, sort='', search='', order='desc', regex='', start=0, end=0, **kwargs):
"""
Get the PlexPy logs.
Get the Tautulli logs.
```
Required parameters:
@ -169,7 +169,7 @@ class API2:
end = int(kwargs.get('end', 0))
if regex:
logger.api_debug(u'PlexPy APIv2 :: Filtering log using regex %s' % regex)
logger.api_debug(u'Tautulli APIv2 :: Filtering log using regex %s' % regex)
reg = re.compile('u' + regex, flags=re.I)
for line in open(logfile, 'r').readlines():
@ -201,15 +201,15 @@ class API2:
templog.append(d)
if end > 0 or start > 0:
logger.api_debug(u'PlexPy APIv2 :: Slicing the log from %s to %s' % (start, end))
logger.api_debug(u'Tautulli APIv2 :: Slicing the log from %s to %s' % (start, end))
templog = templog[start:end]
if sort:
logger.api_debug(u'PlexPy APIv2 :: Sorting log based on %s' % sort)
logger.api_debug(u'Tautulli APIv2 :: Sorting log based on %s' % sort)
templog = sorted(templog, key=lambda k: k[sort])
if search:
logger.api_debug(u'PlexPy APIv2 :: Searching log values for %s' % search)
logger.api_debug(u'Tautulli APIv2 :: Searching log values for %s' % search)
tt = [d for d in templog for k, v in d.items() if search.lower() in v.lower()]
if len(tt):
@ -276,7 +276,7 @@ class API2:
return config
def sql(self, query=''):
""" Query the PlexPy database with raw SQL. Automatically makes a backup of
""" Query the Tautulli database with raw SQL. Automatically makes a backup of
the database if the latest backup is older then 24h. `api_sql` must be
manually enabled in the config file.
@ -330,40 +330,40 @@ class API2:
return data
def restart(self, **kwargs):
""" Restart PlexPy."""
""" Restart Tautulli."""
plexpy.SIGNAL = 'restart'
self._api_msg = 'Restarting plexpy'
self._api_result_type = 'success'
def update(self, **kwargs):
""" Check for PlexPy updates on Github."""
""" Check for Tautulli updates on Github."""
plexpy.SIGNAL = 'update'
self._api_msg = 'Updating plexpy'
self._api_result_type = 'success'
def refresh_libraries_list(self, **kwargs):
""" Refresh the PlexPy libraries list."""
""" Refresh the Tautulli libraries list."""
data = pmsconnect.refresh_libraries()
self._api_result_type = 'success' if data else 'error'
return data
def refresh_users_list(self, **kwargs):
""" Refresh the PlexPy users list."""
""" Refresh the Tautulli users list."""
data = plextv.refresh_users()
self._api_result_type = 'success' if data else 'error'
return data
def register_device(self, device_id='', device_name='', friendly_name='', **kwargs):
""" Registers the PlexPy Android App for notifications.
""" Registers the Tautulli Android App for notifications.
```
Required parameters:
device_name (str): The device name of the PlexPy Android App
device_id (str): The OneSignal device id of the PlexPy Android App
device_name (str): The device name of the Tautulli Android App
device_id (str): The OneSignal device id of the Tautulli Android App
Optional parameters:
friendly_name (str): A friendly name to identify the mobile device
@ -453,8 +453,8 @@ General optional parameters:
None
Optional parameters:
username (str): Your PlexPy username
password (str): Your PlexPy password
username (str): Your Tautulli username
password (str): Your Tautulli password
Returns:
string: "apikey"
@ -517,7 +517,7 @@ General optional parameters:
out = self._api_callback + '(' + out + ');'
# if we fail to generate the output fake an error
except Exception as e:
logger.api_exception(u'PlexPy APIv2 :: ' + traceback.format_exc())
logger.api_exception(u'Tautulli APIv2 :: ' + traceback.format_exc())
out['message'] = traceback.format_exc()
out['result'] = 'error'
@ -526,14 +526,14 @@ General optional parameters:
try:
out = xmltodict.unparse(out, pretty=True)
except Exception as e:
logger.api_error(u'PlexPy APIv2 :: Failed to parse xml result')
logger.api_error(u'Tautulli APIv2 :: Failed to parse xml result')
try:
out['message'] = e
out['result'] = 'error'
out = xmltodict.unparse(out, pretty=True)
except Exception as e:
logger.api_error(u'PlexPy APIv2 :: Failed to parse xml result error message %s' % e)
logger.api_error(u'Tautulli APIv2 :: Failed to parse xml result error message %s' % e)
out = '''<?xml version="1.0" encoding="utf-8"?>
<response>
<message>%s</message>
@ -548,7 +548,7 @@ General optional parameters:
""" handles the stuff from the handler """
result = {}
logger.api_debug(u'PlexPy APIv2 :: API called with kwargs: %s' % kwargs)
logger.api_debug(u'Tautulli APIv2 :: API called with kwargs: %s' % kwargs)
self._api_validate(**kwargs)
@ -566,7 +566,7 @@ General optional parameters:
result = call(**self._api_kwargs)
except Exception as e:
logger.api_error(u'PlexPy APIv2 :: Failed to run %s with %s: %s' % (self._api_cmd, self._api_kwargs, e))
logger.api_error(u'Tautulli APIv2 :: Failed to run %s with %s: %s' % (self._api_cmd, self._api_kwargs, e))
if self._api_debug:
cherrypy.request.show_tracebacks = True
# Reraise the exception so the traceback hits the browser

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
#########################################
## Stolen from Sick-Beard's classes.py ##

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
'''
Created on Aug 1, 2011
@ -24,7 +24,7 @@ from collections import OrderedDict
import version
# Identify Our Application
USER_AGENT = 'PlexPy/-' + version.PLEXPY_BRANCH + ' v' + version.PLEXPY_RELEASE_VERSION + ' (' + platform.system() + \
USER_AGENT = 'Tautulli/-' + version.PLEXPY_BRANCH + ' v' + version.PLEXPY_RELEASE_VERSION + ' (' + platform.system() + \
' ' + platform.release() + ')'
PLATFORM = platform.system()
@ -148,8 +148,8 @@ SCHEDULER_LIST = ['Check GitHub for updates',
'Refresh libraries list',
'Refresh Plex server URLs',
'Refresh Plex server name',
'Backup PlexPy database',
'Backup PlexPy config'
'Backup Tautulli database',
'Backup Tautulli config'
]
DATE_TIME_FORMATS = [
@ -234,9 +234,9 @@ NOTIFICATION_PARAMETERS = [
{
'category': 'Global',
'parameters': [
{'name': 'PlexPy Version', 'type': 'str', 'value': 'plexpy_version', 'description': 'The current version of PlexPy.'},
{'name': 'PlexPy Branch', 'type': 'str', 'value': 'plexpy_branch', 'description': 'The current git branch of PlexPy.'},
{'name': 'PlexPy Commit', 'type': 'str', 'value': 'plexpy_commit', 'description': 'The current git commit hash of PlexPy.'},
{'name': 'Tautulli Version', 'type': 'str', 'value': 'plexpy_version', 'description': 'The current version of Tautulli.'},
{'name': 'Tautulli Branch', 'type': 'str', 'value': 'plexpy_branch', 'description': 'The current git branch of Tautulli.'},
{'name': 'Tautulli Commit', 'type': 'str', 'value': 'plexpy_commit', 'description': 'The current git commit hash of Tautulli.'},
{'name': 'Server Name', 'type': 'str', 'value': 'server_name', 'description': 'The name of your Plex Server.'},
{'name': 'Server Uptime', 'type': 'str', 'value': 'server_uptime', 'description': 'The uptime (in days, hours, mins, secs) of your Plex Server.'},
{'name': 'Server Version', 'type': 'str', 'value': 'server_version', 'description': 'The current version of your Plex Server.'},
@ -424,9 +424,9 @@ NOTIFICATION_PARAMETERS = [
]
},
{
'category': 'PlexPy Update Available',
'category': 'Tautulli Update Available',
'parameters': [
{'name': 'Plexpy Update Version', 'type': 'int', 'value': 'plexpy_update_version', 'description': 'The available update version for PlexPy.'},
{'name': 'Plexpy Update Version', 'type': 'int', 'value': 'plexpy_update_version', 'description': 'The available update version for Tautulli.'},
{'name': 'Plexpy Update Tar', 'type': 'int', 'value': 'plexpy_update_tar', 'description': 'The tar download URL for the available update.'},
{'name': 'Plexpy Update Zip', 'type': 'int', 'value': 'plexpy_update_zip', 'description': 'The zip download URL for the available update.'},
{'name': 'Plexpy Update Commit', 'type': 'int', 'value': 'plexpy_update_commit', 'description': 'The commit hash for the available update.'},

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import arrow
import os
@ -117,7 +117,7 @@ _CONFIG_DEFINITIONS = {
'CONFIG_VERSION': (int, 'Advanced', 0),
'DO_NOT_OVERRIDE_GIT_BRANCH': (int, 'General', 0),
'EMAIL_ENABLED': (int, 'Email', 0),
'EMAIL_FROM_NAME': (str, 'Email', 'PlexPy'),
'EMAIL_FROM_NAME': (str, 'Email', 'Tautulli'),
'EMAIL_FROM': (str, 'Email', ''),
'EMAIL_TO': (str, 'Email', ''),
'EMAIL_CC': (str, 'Email', ''),
@ -333,36 +333,36 @@ _CONFIG_DEFINITIONS = {
'NOTIFY_CONCURRENT_BY_IP': (int, 'Monitoring', 0),
'NOTIFY_CONCURRENT_THRESHOLD': (int, 'Monitoring', 2),
'NOTIFY_WATCHED_PERCENT': (int, 'Monitoring', 85),
'NOTIFY_ON_START_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_START_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_START_BODY_TEXT': (unicode, 'Monitoring', '{user} ({player}) started playing {title}.'),
'NOTIFY_ON_STOP_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_STOP_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_STOP_BODY_TEXT': (unicode, 'Monitoring', '{user} ({player}) has stopped {title}.'),
'NOTIFY_ON_PAUSE_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_PAUSE_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_PAUSE_BODY_TEXT': (unicode, 'Monitoring', '{user} ({player}) has paused {title}.'),
'NOTIFY_ON_RESUME_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_RESUME_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_RESUME_BODY_TEXT': (unicode, 'Monitoring', '{user} ({player}) has resumed {title}.'),
'NOTIFY_ON_BUFFER_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_BUFFER_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_BUFFER_BODY_TEXT': (unicode, 'Monitoring', '{user} ({player}) is buffering {title}.'),
'NOTIFY_ON_WATCHED_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_WATCHED_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_WATCHED_BODY_TEXT': (unicode, 'Monitoring', '{user} ({player}) has watched {title}.'),
'NOTIFY_ON_CREATED_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_CREATED_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_CREATED_BODY_TEXT': (unicode, 'Monitoring', '{title} was recently added to Plex.'),
'NOTIFY_ON_EXTDOWN_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_EXTDOWN_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_EXTDOWN_BODY_TEXT': (unicode, 'Monitoring', 'The Plex Media Server remote access is down.'),
'NOTIFY_ON_INTDOWN_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_INTDOWN_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_INTDOWN_BODY_TEXT': (unicode, 'Monitoring', 'The Plex Media Server is down.'),
'NOTIFY_ON_EXTUP_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_EXTUP_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_EXTUP_BODY_TEXT': (unicode, 'Monitoring', 'The Plex Media Server remote access is back up.'),
'NOTIFY_ON_INTUP_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_INTUP_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_INTUP_BODY_TEXT': (unicode, 'Monitoring', 'The Plex Media Server is back up.'),
'NOTIFY_ON_PMSUPDATE_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_PMSUPDATE_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_PMSUPDATE_BODY_TEXT': (unicode, 'Monitoring', 'An update is available for the Plex Media Server (version {update_version}).'),
'NOTIFY_ON_CONCURRENT_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_CONCURRENT_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_CONCURRENT_BODY_TEXT': (unicode, 'Monitoring', '{user} has {user_streams} concurrent streams.'),
'NOTIFY_ON_NEWDEVICE_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_NEWDEVICE_SUBJECT_TEXT': (unicode, 'Monitoring', 'Tautulli ({server_name})'),
'NOTIFY_ON_NEWDEVICE_BODY_TEXT': (unicode, 'Monitoring', '{user} is streaming from a new device: {player}.'),
'NOTIFY_SCRIPTS_ARGS_TEXT': (unicode, 'Monitoring', ''),
'OSX_NOTIFY_APP': (str, 'OSX_Notify', '/Applications/PlexPy'),
'OSX_NOTIFY_APP': (str, 'OSX_Notify', '/Applications/Tautulli'),
'OSX_NOTIFY_ENABLED': (int, 'OSX_Notify', 0),
'OSX_NOTIFY_ON_PLAY': (int, 'OSX_Notify', 0),
'OSX_NOTIFY_ON_STOP': (int, 'OSX_Notify', 0),
@ -642,13 +642,13 @@ def make_backup(cleanup=False, scheduler=False):
try:
os.remove(file_)
except OSError as e:
logger.error(u"PlexPy Config :: Failed to delete %s from the backup folder: %s" % (file_, e))
logger.error(u"Tautulli Config :: Failed to delete %s from the backup folder: %s" % (file_, e))
if backup_file in os.listdir(backup_folder):
logger.debug(u"PlexPy Config :: Successfully backed up %s to %s" % (plexpy.CONFIG_FILE, backup_file))
logger.debug(u"Tautulli Config :: Successfully backed up %s to %s" % (plexpy.CONFIG_FILE, backup_file))
return True
else:
logger.warn(u"PlexPy Config :: Failed to backup %s to %s" % (plexpy.CONFIG_FILE, backup_file))
logger.warn(u"Tautulli Config :: Failed to backup %s to %s" % (plexpy.CONFIG_FILE, backup_file))
return False
@ -729,12 +729,12 @@ class Config(object):
new_config[section][ini_key] = self._config[section][ini_key]
# Write it to file
logger.info(u"PlexPy Config :: Writing configuration to file")
logger.info(u"Tautulli Config :: Writing configuration to file")
try:
new_config.write()
except IOError as e:
logger.error(u"PlexPy Config :: Error writing configuration file: %s", e)
logger.error(u"Tautulli Config :: Error writing configuration file: %s", e)
self._blacklist()

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import arrow
import os
@ -33,7 +33,7 @@ def drop_session_db():
def clear_history_tables():
logger.debug(u"PlexPy Database :: Deleting all session_history records... No turning back now bub.")
logger.debug(u"Tautulli Database :: Deleting all session_history records... No turning back now bub.")
monitor_db = MonitorDatabase()
monitor_db.action('DELETE FROM session_history')
monitor_db.action('DELETE FROM session_history_media_info')
@ -42,7 +42,7 @@ def clear_history_tables():
def delete_sessions():
logger.debug(u"PlexPy Database :: Clearing temporary sessions from database.")
logger.debug(u"Tautulli Database :: Clearing temporary sessions from database.")
monitor_db = MonitorDatabase()
try:
@ -50,7 +50,7 @@ def delete_sessions():
monitor_db.action('VACUUM')
return True
except Exception as e:
logger.warn(u"PlexPy Database :: Unable to clear temporary sessions from database: %s." % e)
logger.warn(u"Tautulli Database :: Unable to clear temporary sessions from database: %s." % e)
return False
def db_filename(filename=FILENAME):
@ -88,13 +88,13 @@ def make_backup(cleanup=False, scheduler=False):
try:
os.remove(file_)
except OSError as e:
logger.error(u"PlexPy Database :: Failed to delete %s from the backup folder: %s" % (file_, e))
logger.error(u"Tautulli Database :: Failed to delete %s from the backup folder: %s" % (file_, e))
if backup_file in os.listdir(backup_folder):
logger.debug(u"PlexPy Database :: Successfully backed up %s to %s" % (db_filename(), backup_file))
logger.debug(u"Tautulli Database :: Successfully backed up %s to %s" % (db_filename(), backup_file))
return True
else:
logger.warn(u"PlexPy Database :: Failed to backup %s to %s" % (db_filename(), backup_file))
logger.warn(u"Tautulli Database :: Failed to backup %s to %s" % (db_filename(), backup_file))
return False
@ -147,15 +147,15 @@ class MonitorDatabase(object):
except sqlite3.OperationalError as e:
if "unable to open database file" in e or "database is locked" in e:
logger.warn(u"PlexPy Database :: Database Error: %s", e)
logger.warn(u"Tautulli Database :: Database Error: %s", e)
attempts += 1
time.sleep(1)
else:
logger.error(u"PlexPy Database :: Database error: %s", e)
logger.error(u"Tautulli Database :: Database error: %s", e)
raise
except sqlite3.DatabaseError as e:
logger.error(u"PlexPy Database :: Fatal Error executing %s :: %s", query, e)
logger.error(u"Tautulli Database :: Fatal Error executing %s :: %s", query, e)
raise
return sql_result
@ -199,7 +199,7 @@ class MonitorDatabase(object):
try:
self.action(insert_query, value_dict.values() + key_dict.values())
except sqlite3.IntegrityError:
logger.info(u"PlexPy Database :: Queries failed: %s and %s", update_query, insert_query)
logger.info(u"Tautulli Database :: Queries failed: %s and %s", update_query, insert_query)
# We want to know if it was an update or insert
return trans_type

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import json
from itertools import groupby
@ -172,7 +172,7 @@ class DataFactory(object):
['session_history.id', 'session_history_media_info.id']],
kwargs=kwargs)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_history: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_history: %s." % e)
return {'recordsFiltered': 0,
'recordsTotal': 0,
'draw': 0,
@ -302,7 +302,7 @@ class DataFactory(object):
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_movies: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_home_stats: top_movies: %s." % e)
return None
for item in result:
@ -353,7 +353,7 @@ class DataFactory(object):
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_movies: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_home_stats: popular_movies: %s." % e)
return None
for item in result:
@ -400,7 +400,7 @@ class DataFactory(object):
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_tv: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_home_stats: top_tv: %s." % e)
return None
for item in result:
@ -450,7 +450,7 @@ class DataFactory(object):
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_tv: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_home_stats: popular_tv: %s." % e)
return None
for item in result:
@ -497,7 +497,7 @@ class DataFactory(object):
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_music: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_home_stats: top_music: %s." % e)
return None
for item in result:
@ -547,7 +547,7 @@ class DataFactory(object):
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: popular_music: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_home_stats: popular_music: %s." % e)
return None
for item in result:
@ -595,7 +595,7 @@ class DataFactory(object):
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_users: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_home_stats: top_users: %s." % e)
return None
for item in result:
@ -648,7 +648,7 @@ class DataFactory(object):
'LIMIT %s ' % (time_range, group_by, sort_type, stats_count)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: top_platforms: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_home_stats: top_platforms: %s." % e)
return None
for item in result:
@ -706,7 +706,7 @@ class DataFactory(object):
'LIMIT %s' % (time_range, group_by, movie_watched_percent, tv_watched_percent, stats_count)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: last_watched: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_home_stats: last_watched: %s." % e)
return None
for item in result:
@ -812,7 +812,7 @@ class DataFactory(object):
if result:
most_concurrent.append(calc_most_concurrent(title, result))
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_home_stats: most_concurrent: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_home_stats: most_concurrent: %s." % e)
return None
home_stats.append({'stat_id': stat,
@ -837,7 +837,7 @@ class DataFactory(object):
'ORDER BY section_type, count DESC, parent_count DESC, child_count DESC ' % ','.join(library_cards)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_library_stats: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_library_stats: %s." % e)
return None
for item in result:
@ -1033,7 +1033,7 @@ class DataFactory(object):
'%s ' % where
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_total_duration: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_total_duration: %s." % e)
return None
total_duration = 0
@ -1056,7 +1056,7 @@ class DataFactory(object):
query = 'SELECT ip_address FROM sessions WHERE session_key = %d %s' % (int(session_key), user_cond)
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_session_ip: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_session_ip: %s." % e)
return ip_address
else:
return ip_address
@ -1086,7 +1086,7 @@ class DataFactory(object):
'WHERE rating_key = ?'
poster_info = monitor_db.select_single(query, args=[poster_key])
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_poster_url: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_poster_url: %s." % e)
return poster_info
@ -1105,7 +1105,7 @@ class DataFactory(object):
monitor_db = database.MonitorDatabase()
if rating_key:
logger.info(u"PlexPy DataFactory :: Deleting poster_url for rating_key %s from the database." % rating_key)
logger.info(u"Tautulli DataFactory :: Deleting poster_url for rating_key %s from the database." % rating_key)
result = monitor_db.action('DELETE FROM poster_urls WHERE rating_key = ?', [rating_key])
return True if result else False
@ -1197,7 +1197,7 @@ class DataFactory(object):
grandparent_rating_key = result[0]['grandparent_rating_key']
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_rating_keys_list: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_rating_keys_list: %s." % e)
return {}
query = 'SELECT rating_key, parent_rating_key, grandparent_rating_key, title, parent_title, grandparent_title, ' \
@ -1244,7 +1244,7 @@ class DataFactory(object):
monitor_db = database.MonitorDatabase()
if row_id.isdigit():
logger.info(u"PlexPy DataFactory :: Deleting row id %s from the session history database." % row_id)
logger.info(u"Tautulli DataFactory :: Deleting row id %s from the session history database." % row_id)
session_history_del = \
monitor_db.action('DELETE FROM session_history WHERE id = ?', [row_id])
session_history_media_info_del = \
@ -1277,7 +1277,7 @@ class DataFactory(object):
mapping = get_pairs(old_key_list, new_key_list)
if mapping:
logger.info(u"PlexPy DataFactory :: Updating metadata in the database.")
logger.info(u"Tautulli DataFactory :: Updating metadata in the database.")
for old_key, new_key in mapping.iteritems():
metadata = pms_connect.get_metadata_details(new_key)
@ -1323,7 +1323,7 @@ class DataFactory(object):
genres = ";".join(metadata['genres'])
labels = ";".join(metadata['labels'])
#logger.info(u"PlexPy DataFactory :: Updating metadata in the database for rating key: %s." % new_rating_key)
#logger.info(u"Tautulli DataFactory :: Updating metadata in the database for rating key: %s." % new_rating_key)
monitor_db = database.MonitorDatabase()
# Update the session_history_metadata table
@ -1375,7 +1375,7 @@ class DataFactory(object):
join_evals=[],
kwargs=kwargs)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_notification_log: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_notification_log: %s." % e)
return {'recordsFiltered': 0,
'recordsTotal': 0,
'draw': 0,
@ -1420,12 +1420,12 @@ class DataFactory(object):
monitor_db = database.MonitorDatabase()
try:
logger.info(u"PlexPy DataFactory :: Clearing notification logs from database.")
logger.info(u"Tautulli DataFactory :: Clearing notification logs from database.")
monitor_db.action('DELETE FROM notify_log')
monitor_db.action('VACUUM')
return True
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for delete_notification_log: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for delete_notification_log: %s." % e)
return False
def get_user_devices(self, user_id=''):
@ -1436,7 +1436,7 @@ class DataFactory(object):
query = 'SELECT machine_id FROM session_history WHERE user_id = ? GROUP BY machine_id'
result = monitor_db.select(query=query, args=[user_id])
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_user_devices: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_user_devices: %s." % e)
return []
else:
return []
@ -1451,7 +1451,7 @@ class DataFactory(object):
query = 'SELECT * FROM recently_added WHERE rating_key = ?'
result = monitor_db.select(query=query, args=[rating_key])
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for get_recently_added_item: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for get_recently_added_item: %s." % e)
return []
else:
return []
@ -1477,7 +1477,7 @@ class DataFactory(object):
try:
monitor_db.upsert(table_name='recently_added', key_dict=keys, value_dict=values)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for set_recently_added_item: %s." % e)
logger.warn(u"Tautulli DataFactory :: Unable to execute database query for set_recently_added_item: %s." % e)
return False
return True

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import re
@ -43,14 +43,14 @@ class DataTables(object):
kwargs=None):
if not table_name:
logger.error('PlexPy DataTables :: No table name received.')
logger.error('Tautulli DataTables :: No table name received.')
return None
# Fetch all our parameters
if kwargs.get('json_data'):
parameters = helpers.process_json_kwargs(json_kwargs=kwargs.get('json_data'))
else:
logger.error('PlexPy DataTables :: Parameters for Datatables must be sent as a serialised json object '
logger.error('Tautulli DataTables :: Parameters for Datatables must be sent as a serialised json object '
'named json_data.')
return None

View file

@ -1,21 +1,21 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
class PlexPyException(Exception):
"""
Generic PlexPy Exception - should never be thrown, only subclassed
Generic Tautulli Exception - should never be thrown, only subclassed
"""

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import datetime
@ -66,7 +66,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_total_plays_per_day: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_total_plays_per_day: %s." % e)
return None
# create our date range as some days may not have any data
@ -166,7 +166,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_total_plays_per_dayofweek: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_total_plays_per_dayofweek: %s." % e)
return None
if plexpy.CONFIG.WEEK_START_MONDAY:
@ -251,7 +251,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_total_plays_per_hourofday: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_total_plays_per_hourofday: %s." % e)
return None
hours_list = ['00','01','02','03','04','05',
@ -336,7 +336,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_total_plays_per_month: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_total_plays_per_month: %s." % e)
return None
# create our date range as some months may not have any data
@ -428,7 +428,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_total_plays_by_top_10_platforms: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_total_plays_by_top_10_platforms: %s." % e)
return None
categories = []
@ -505,7 +505,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_total_plays_by_top_10_users: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_total_plays_by_top_10_users: %s." % e)
return None
categories = []
@ -588,7 +588,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_total_plays_per_stream_type: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_total_plays_per_stream_type: %s." % e)
return None
# create our date range as some days may not have any data
@ -689,7 +689,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_total_plays_by_source_resolution: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_total_plays_by_source_resolution: %s." % e)
return None
categories = []
@ -790,7 +790,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_total_plays_by_stream_resolution: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_total_plays_by_stream_resolution: %s." % e)
return None
categories = []
@ -870,7 +870,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_stream_type_by_top_10_platforms: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_stream_type_by_top_10_platforms: %s." % e)
return None
categories = []
@ -959,7 +959,7 @@ class Graphs(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_stream_type_by_top_10_users: %s." % e)
logger.warn(u"Tautulli Graphs :: Unable to execute database query for get_stream_type_by_top_10_users: %s." % e)
return None
categories = []

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import base64
import datetime
@ -399,10 +399,10 @@ def create_https_certificates(ssl_cert, ssl_key):
ips = ['IP:' + d.strip() for d in plexpy.CONFIG.HTTPS_IP.split(',') if d]
altNames = ','.join(domains + ips)
# Create the self-signed PlexPy certificate
# Create the self-signed Tautulli certificate
logger.debug(u"Generating self-signed SSL certificate.")
pkey = createKeyPair(TYPE_RSA, 2048)
cert = createSelfSignedCertificate(("PlexPy", pkey), serial, (0, 60 * 60 * 24 * 365 * 10), altNames) # ten years
cert = createSelfSignedCertificate(("Tautulli", pkey), serial, (0, 60 * 60 * 24 * 365 * 10), altNames) # ten years
# Save the key and certificate to disk
try:
@ -537,27 +537,27 @@ def install_geoip_db():
geolite2_db = plexpy.CONFIG.GEOIP_DB or os.path.join(plexpy.DATA_DIR, geolite2_db)
# Retrieve the GeoLite2 gzip file
logger.debug(u"PlexPy Helpers :: Downloading GeoLite2 gzip file from MaxMind...")
logger.debug(u"Tautulli Helpers :: Downloading GeoLite2 gzip file from MaxMind...")
try:
maxmind = urllib.URLopener()
maxmind.retrieve(maxmind_url + geolite2_gz, temp_gz)
md5_checksum = urllib2.urlopen(maxmind_url + geolite2_md5).read()
except Exception as e:
logger.error(u"PlexPy Helpers :: Failed to download GeoLite2 gzip file from MaxMind: %s" % e)
logger.error(u"Tautulli Helpers :: Failed to download GeoLite2 gzip file from MaxMind: %s" % e)
return False
# Extract the GeoLite2 database file
logger.debug(u"PlexPy Helpers :: Extracting GeoLite2 database...")
logger.debug(u"Tautulli Helpers :: Extracting GeoLite2 database...")
try:
with gzip.open(temp_gz, 'rb') as gz:
with open(geolite2_db, 'wb') as db:
db.write(gz.read())
except Exception as e:
logger.error(u"PlexPy Helpers :: Failed to extract the GeoLite2 database: %s" % e)
logger.error(u"Tautulli Helpers :: Failed to extract the GeoLite2 database: %s" % e)
return False
# Check MD5 hash for GeoLite2 database file
logger.debug(u"PlexPy Helpers :: Checking MD5 checksum for GeoLite2 database...")
logger.debug(u"Tautulli Helpers :: Checking MD5 checksum for GeoLite2 database...")
try:
hash_md5 = hashlib.md5()
with open(geolite2_db, 'rb') as f:
@ -566,37 +566,37 @@ def install_geoip_db():
md5_hash = hash_md5.hexdigest()
if md5_hash != md5_checksum:
logger.error(u"PlexPy Helpers :: MD5 checksum doesn't match for GeoLite2 database. "
logger.error(u"Tautulli Helpers :: MD5 checksum doesn't match for GeoLite2 database. "
"Checksum: %s, file hash: %s" % (md5_checksum, md5_hash))
return False
except Exception as e:
logger.error(u"PlexPy Helpers :: Failed to generate MD5 checksum for GeoLite2 database: %s" % e)
logger.error(u"Tautulli Helpers :: Failed to generate MD5 checksum for GeoLite2 database: %s" % e)
return False
# Delete temportary GeoLite2 gzip file
logger.debug(u"PlexPy Helpers :: Deleting temporary GeoLite2 gzip file...")
logger.debug(u"Tautulli Helpers :: Deleting temporary GeoLite2 gzip file...")
try:
os.remove(temp_gz)
except Exception as e:
logger.warn(u"PlexPy Helpers :: Failed to remove temporary GeoLite2 gzip file: %s" % e)
logger.warn(u"Tautulli Helpers :: Failed to remove temporary GeoLite2 gzip file: %s" % e)
logger.debug(u"PlexPy Helpers :: GeoLite2 database installed successfully.")
logger.debug(u"Tautulli Helpers :: GeoLite2 database installed successfully.")
plexpy.CONFIG.__setattr__('GEOIP_DB', geolite2_db)
plexpy.CONFIG.write()
return True
def uninstall_geoip_db():
logger.debug(u"PlexPy Helpers :: Uninstalling the GeoLite2 database...")
logger.debug(u"Tautulli Helpers :: Uninstalling the GeoLite2 database...")
try:
os.remove(plexpy.CONFIG.GEOIP_DB)
plexpy.CONFIG.__setattr__('GEOIP_DB', '')
plexpy.CONFIG.write()
except Exception as e:
logger.error(u"PlexPy Helpers :: Failed to uninstall the GeoLite2 database: %s" % e)
logger.error(u"Tautulli Helpers :: Failed to uninstall the GeoLite2 database: %s" % e)
return False
logger.debug(u"PlexPy Helpers :: GeoLite2 database uninstalled successfully.")
logger.debug(u"Tautulli Helpers :: GeoLite2 database uninstalled successfully.")
return True
def geoip_lookup(ip_address):
@ -686,14 +686,14 @@ def uploadToImgur(imgPath, imgTitle=''):
img_url = ''
if not client_id:
logger.error(u"PlexPy Helpers :: Cannot upload poster to Imgur. No Imgur client id specified in the settings.")
logger.error(u"Tautulli Helpers :: Cannot upload poster to Imgur. No Imgur client id specified in the settings.")
return img_url
try:
with open(imgPath, 'rb') as imgFile:
img = imgFile.read()
except IOError as e:
logger.error(u"PlexPy Helpers :: Unable to read image file for Imgur: %s" % e)
logger.error(u"Tautulli Helpers :: Unable to read image file for Imgur: %s" % e)
return img_url
headers = {'Authorization': 'Client-ID %s' % client_id}
@ -707,17 +707,17 @@ def uploadToImgur(imgPath, imgTitle=''):
if response and not err_msg:
t = '\'' + imgTitle + '\' ' if imgTitle else ''
logger.debug(u"PlexPy Helpers :: Image {}uploaded to Imgur.".format(t))
logger.debug(u"Tautulli Helpers :: Image {}uploaded to Imgur.".format(t))
img_url = response.json().get('data').get('link', '').replace('http://', 'https://')
else:
if err_msg:
logger.error(u"PlexPy Helpers :: Unable to upload image to Imgur: {}".format(err_msg))
logger.error(u"Tautulli Helpers :: Unable to upload image to Imgur: {}".format(err_msg))
else:
logger.error(u"PlexPy Helpers :: Unable to upload image to Imgur.")
logger.error(u"Tautulli Helpers :: Unable to upload image to Imgur.")
if req_msg:
logger.debug(u"PlexPy Helpers :: Request response: {}".format(req_msg))
logger.debug(u"Tautulli Helpers :: Request response: {}".format(req_msg))
return img_url
@ -729,7 +729,7 @@ def cache_image(url, image=None):
# Create image directory if it doesn't exist
imgdir = os.path.join(plexpy.CONFIG.CACHE_DIR, 'images/')
if not os.path.exists(imgdir):
logger.debug(u"PlexPy Helpers :: Creating image cache directory at %s" % imgdir)
logger.debug(u"Tautulli Helpers :: Creating image cache directory at %s" % imgdir)
os.makedirs(imgdir)
# Create a hash of the url to use as the filename
@ -742,7 +742,7 @@ def cache_image(url, image=None):
with open(imagefile, 'wb') as cache_file:
cache_file.write(image)
except IOError as e:
logger.error(u"PlexPy Helpers :: Failed to cache image %s: %s" % (imagefile, e))
logger.error(u"Tautulli Helpers :: Failed to cache image %s: %s" % (imagefile, e))
# Try to return the image from the cache directory
if os.path.isfile(imagefile):

View file

@ -1,20 +1,20 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
from httplib import HTTPSConnection
from httplib import HTTPConnection
@ -64,7 +64,7 @@ class HTTPHandler(object):
if not self.ssl_verify and hasattr(ssl, '_create_unverified_context'):
context = ssl._create_unverified_context()
handler = HTTPSConnection(host=self.host, port=self.port, timeout=timeout, context=context)
logger.warn(u"PlexPy HTTP Handler :: Unverified HTTPS request made. This connection is not secure.")
logger.warn(u"Tautulli HTTP Handler :: Unverified HTTPS request made. This connection is not secure.")
else:
handler = HTTPSConnection(host=self.host, port=self.port, timeout=timeout)
else:

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import json
import os
@ -39,9 +39,9 @@ def update_section_ids():
query = 'SELECT section_id, section_type FROM library_sections'
library_results = monitor_db.select(query=query)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for update_section_ids: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for update_section_ids: %s." % e)
logger.warn(u"PlexPy Libraries :: Unable to update section_id's in database.")
logger.warn(u"Tautulli Libraries :: Unable to update section_id's in database.")
plexpy.CONFIG.UPDATE_SECTION_IDS = 1
plexpy.CONFIG.write()
return None
@ -51,7 +51,7 @@ def update_section_ids():
plexpy.CONFIG.write()
return None
logger.debug(u"PlexPy Libraries :: Updating section_id's in database.")
logger.debug(u"Tautulli Libraries :: Updating section_id's in database.")
# Get rating_key: section_id mapping pairs
key_mappings = {}
@ -68,7 +68,7 @@ def update_section_ids():
children_list = library_children['childern_list']
key_mappings.update({child['rating_key']:child['section_id'] for child in children_list})
else:
logger.warn(u"PlexPy Libraries :: Unable to get a list of library items for section_id %s." % section_id)
logger.warn(u"Tautulli Libraries :: Unable to get a list of library items for section_id %s." % section_id)
error_keys = set()
for item in history_results:
@ -86,10 +86,10 @@ def update_section_ids():
error_keys.add(item['rating_key'])
if error_keys:
logger.info(u"PlexPy Libraries :: Updated all section_id's in database except for rating_keys: %s." %
logger.info(u"Tautulli Libraries :: Updated all section_id's in database except for rating_keys: %s." %
', '.join(str(key) for key in error_keys))
else:
logger.info(u"PlexPy Libraries :: Updated all section_id's in database.")
logger.info(u"Tautulli Libraries :: Updated all section_id's in database.")
plexpy.CONFIG.UPDATE_SECTION_IDS = 0
plexpy.CONFIG.write()
@ -105,9 +105,9 @@ def update_labels():
query = 'SELECT section_id, section_type FROM library_sections'
library_results = monitor_db.select(query=query)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for update_labels: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for update_labels: %s." % e)
logger.warn(u"PlexPy Libraries :: Unable to update labels in database.")
logger.warn(u"Tautulli Libraries :: Unable to update labels in database.")
plexpy.CONFIG.UPDATE_LABELS = 1
plexpy.CONFIG.write()
return None
@ -117,7 +117,7 @@ def update_labels():
plexpy.CONFIG.write()
return None
logger.debug(u"PlexPy Libraries :: Updating labels in database.")
logger.debug(u"Tautulli Libraries :: Updating labels in database.")
# Get rating_key: section_id mapping pairs
key_mappings = {}
@ -148,7 +148,7 @@ def update_labels():
key_mappings[rating_key] = [label['label_title']]
else:
logger.warn(u"PlexPy Libraries :: Unable to get a list of library items for section_id %s."
logger.warn(u"Tautulli Libraries :: Unable to get a list of library items for section_id %s."
% section_id)
error_keys = set()
@ -162,10 +162,10 @@ def update_labels():
error_keys.add(rating_key)
if error_keys:
logger.info(u"PlexPy Libraries :: Updated all labels in database except for rating_keys: %s." %
logger.info(u"Tautulli Libraries :: Updated all labels in database except for rating_keys: %s." %
', '.join(str(key) for key in error_keys))
else:
logger.info(u"PlexPy Libraries :: Updated all labels in database.")
logger.info(u"Tautulli Libraries :: Updated all labels in database.")
plexpy.CONFIG.UPDATE_LABELS = 0
plexpy.CONFIG.write()
@ -239,7 +239,7 @@ class Libraries(object):
['session_history_metadata.id', 'session_history_media_info.id']],
kwargs=kwargs)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_list: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for get_list: %s." % e)
return default_return
result = query['result']
@ -308,19 +308,19 @@ class Libraries(object):
return default_return
if section_id and not str(section_id).isdigit():
logger.warn(u"PlexPy Libraries :: Datatable media info called but invalid section_id provided.")
logger.warn(u"Tautulli Libraries :: Datatable media info called but invalid section_id provided.")
return default_return
elif rating_key and not str(rating_key).isdigit():
logger.warn(u"PlexPy Libraries :: Datatable media info called but invalid rating_key provided.")
logger.warn(u"Tautulli Libraries :: Datatable media info called but invalid rating_key provided.")
return default_return
elif not section_id and not rating_key:
logger.warn(u"PlexPy Libraries :: Datatable media info called but no input provided.")
logger.warn(u"Tautulli Libraries :: Datatable media info called but no input provided.")
return default_return
# Get the library details
library_details = self.get_details(section_id=section_id)
if library_details['section_id'] == None:
logger.debug(u"PlexPy Libraries :: Library section_id %s not found." % section_id)
logger.debug(u"Tautulli Libraries :: Library section_id %s not found." % section_id)
return default_return
if not section_type:
@ -350,7 +350,7 @@ class Libraries(object):
'GROUP BY session_history.%s ' % (count_by, group_by)
result = monitor_db.select(query, args=[section_id])
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_datatables_media_info2: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for get_datatables_media_info2: %s." % e)
return default_return
watched_list = {}
@ -367,8 +367,8 @@ class Libraries(object):
rows = json.load(inFile)
library_count = len(rows)
except IOError as e:
#logger.debug(u"PlexPy Libraries :: No JSON file for rating_key %s." % rating_key)
#logger.debug(u"PlexPy Libraries :: Refreshing data and creating new JSON file for rating_key %s." % rating_key)
#logger.debug(u"Tautulli Libraries :: No JSON file for rating_key %s." % rating_key)
#logger.debug(u"Tautulli Libraries :: Refreshing data and creating new JSON file for rating_key %s." % rating_key)
pass
elif section_id:
try:
@ -377,8 +377,8 @@ class Libraries(object):
rows = json.load(inFile)
library_count = len(rows)
except IOError as e:
#logger.debug(u"PlexPy Libraries :: No JSON file for library section_id %s." % section_id)
#logger.debug(u"PlexPy Libraries :: Refreshing data and creating new JSON file for section_id %s." % section_id)
#logger.debug(u"Tautulli Libraries :: No JSON file for library section_id %s." % section_id)
#logger.debug(u"Tautulli Libraries :: Refreshing data and creating new JSON file for section_id %s." % section_id)
pass
# If no cache was imported, get all library children items
@ -398,7 +398,7 @@ class Libraries(object):
library_count = library_children['library_count']
children_list = library_children['childern_list']
else:
logger.warn(u"PlexPy Libraries :: Unable to get a list of library items.")
logger.warn(u"Tautulli Libraries :: Unable to get a list of library items.")
return default_return
new_rows = []
@ -442,14 +442,14 @@ class Libraries(object):
with open(outFilePath, 'w') as outFile:
json.dump(rows, outFile)
except IOError as e:
logger.debug(u"PlexPy Libraries :: Unable to create cache file for rating_key %s." % rating_key)
logger.debug(u"Tautulli Libraries :: Unable to create cache file for rating_key %s." % rating_key)
elif section_id:
try:
outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info_%s.json' % section_id)
with open(outFilePath, 'w') as outFile:
json.dump(rows, outFile)
except IOError as e:
logger.debug(u"PlexPy Libraries :: Unable to create cache file for section_id %s." % section_id)
logger.debug(u"Tautulli Libraries :: Unable to create cache file for section_id %s." % section_id)
# Update the last_played and play_count
for item in rows:
@ -519,16 +519,16 @@ class Libraries(object):
return False
if section_id and not str(section_id).isdigit():
logger.warn(u"PlexPy Libraries :: Datatable media info file size called but invalid section_id provided.")
logger.warn(u"Tautulli Libraries :: Datatable media info file size called but invalid section_id provided.")
return False
elif rating_key and not str(rating_key).isdigit():
logger.warn(u"PlexPy Libraries :: Datatable media info file size called but invalid rating_key provided.")
logger.warn(u"Tautulli Libraries :: Datatable media info file size called but invalid rating_key provided.")
return False
# Get the library details
library_details = self.get_details(section_id=section_id)
if library_details['section_id'] == None:
logger.debug(u"PlexPy Libraries :: Library section_id %s not found." % section_id)
logger.debug(u"Tautulli Libraries :: Library section_id %s not found." % section_id)
return False
if library_details['section_type'] == 'photo':
return False
@ -536,24 +536,24 @@ class Libraries(object):
rows = []
# Import media info cache from json file
if rating_key:
#logger.debug(u"PlexPy Libraries :: Getting file sizes for rating_key %s." % rating_key)
#logger.debug(u"Tautulli Libraries :: Getting file sizes for rating_key %s." % rating_key)
try:
inFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info_%s-%s.json' % (section_id, rating_key))
with open(inFilePath, 'r') as inFile:
rows = json.load(inFile)
except IOError as e:
#logger.debug(u"PlexPy Libraries :: No JSON file for rating_key %s." % rating_key)
#logger.debug(u"PlexPy Libraries :: Refreshing data and creating new JSON file for rating_key %s." % rating_key)
#logger.debug(u"Tautulli Libraries :: No JSON file for rating_key %s." % rating_key)
#logger.debug(u"Tautulli Libraries :: Refreshing data and creating new JSON file for rating_key %s." % rating_key)
pass
elif section_id:
logger.debug(u"PlexPy Libraries :: Getting file sizes for section_id %s." % section_id)
logger.debug(u"Tautulli Libraries :: Getting file sizes for section_id %s." % section_id)
try:
inFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info_%s.json' % section_id)
with open(inFilePath, 'r') as inFile:
rows = json.load(inFile)
except IOError as e:
#logger.debug(u"PlexPy Libraries :: No JSON file for library section_id %s." % section_id)
#logger.debug(u"PlexPy Libraries :: Refreshing data and creating new JSON file for section_id %s." % section_id)
#logger.debug(u"Tautulli Libraries :: No JSON file for library section_id %s." % section_id)
#logger.debug(u"Tautulli Libraries :: Refreshing data and creating new JSON file for section_id %s." % section_id)
pass
# Get the total file size for each item
@ -585,20 +585,20 @@ class Libraries(object):
with open(outFilePath, 'w') as outFile:
json.dump(rows, outFile)
except IOError as e:
logger.debug(u"PlexPy Libraries :: Unable to create cache file with file sizes for rating_key %s." % rating_key)
logger.debug(u"Tautulli Libraries :: Unable to create cache file with file sizes for rating_key %s." % rating_key)
elif section_id:
try:
outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info_%s.json' % section_id)
with open(outFilePath, 'w') as outFile:
json.dump(rows, outFile)
except IOError as e:
logger.debug(u"PlexPy Libraries :: Unable to create cache file with file sizes for section_id %s." % section_id)
logger.debug(u"Tautulli Libraries :: Unable to create cache file with file sizes for section_id %s." % section_id)
if rating_key:
#logger.debug(u"PlexPy Libraries :: File sizes updated for rating_key %s." % rating_key)
#logger.debug(u"Tautulli Libraries :: File sizes updated for rating_key %s." % rating_key)
pass
elif section_id:
logger.debug(u"PlexPy Libraries :: File sizes updated for section_id %s." % section_id)
logger.debug(u"Tautulli Libraries :: File sizes updated for section_id %s." % section_id)
return True
@ -614,7 +614,7 @@ class Libraries(object):
try:
monitor_db.upsert('library_sections', value_dict, key_dict)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for set_config: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for set_config: %s." % e)
def get_details(self, section_id=None):
default_return = {'section_id': 0,
@ -647,7 +647,7 @@ class Libraries(object):
else:
result = []
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_details: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for get_details: %s." % e)
result = []
library_details = {}
@ -680,7 +680,7 @@ class Libraries(object):
return library_details
else:
logger.warn(u"PlexPy Libraries :: Unable to retrieve library %s from database. Requesting library list refresh."
logger.warn(u"Tautulli Libraries :: Unable to retrieve library %s from database. Requesting library list refresh."
% section_id)
# Let's first refresh the libraries list to make sure the library isn't newly added and not in the db yet
pmsconnect.refresh_libraries()
@ -691,7 +691,7 @@ class Libraries(object):
return library_details
else:
logger.warn(u"PlexPy Users :: Unable to retrieve library %s from database. Returning 'Local' library."
logger.warn(u"Tautulli Users :: Unable to retrieve library %s from database. Returning 'Local' library."
% section_id)
# If there is no library data we must return something
return default_return
@ -731,7 +731,7 @@ class Libraries(object):
else:
result = []
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_watch_time_stats: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for get_watch_time_stats: %s." % e)
result = []
for item in result:
@ -774,7 +774,7 @@ class Libraries(object):
else:
result = []
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_user_stats: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for get_user_stats: %s." % e)
result = []
for item in result:
@ -813,7 +813,7 @@ class Libraries(object):
else:
result = []
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_recently_watched: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for get_recently_watched: %s." % e)
result = []
for row in result:
@ -853,7 +853,7 @@ class Libraries(object):
query = 'SELECT section_id, section_name FROM library_sections WHERE deleted_section = 0'
result = monitor_db.select(query=query)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_sections: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for get_sections: %s." % e)
return None
libraries = []
@ -870,7 +870,7 @@ class Libraries(object):
try:
if section_id.isdigit():
logger.info(u"PlexPy Libraries :: Deleting all history for library id %s from database." % section_id)
logger.info(u"Tautulli Libraries :: Deleting all history for library id %s from database." % section_id)
session_history_media_info_del = \
monitor_db.action('DELETE FROM '
'session_history_media_info '
@ -894,7 +894,7 @@ class Libraries(object):
else:
return 'Unable to delete items, section_id not valid.'
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for delete_all_history: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for delete_all_history: %s." % e)
def delete(self, section_id=None):
monitor_db = database.MonitorDatabase()
@ -902,7 +902,7 @@ class Libraries(object):
try:
if section_id.isdigit():
self.delete_all_history(section_id)
logger.info(u"PlexPy Libraries :: Deleting library with id %s from database." % section_id)
logger.info(u"Tautulli Libraries :: Deleting library with id %s from database." % section_id)
monitor_db.action('UPDATE library_sections SET deleted_section = 1 WHERE section_id = ?', [section_id])
monitor_db.action('UPDATE library_sections SET keep_history = 0 WHERE section_id = ?', [section_id])
monitor_db.action('UPDATE library_sections SET do_notify = 0 WHERE section_id = ?', [section_id])
@ -918,14 +918,14 @@ class Libraries(object):
else:
return 'Unable to delete library, section_id not valid.'
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for delete: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for delete: %s." % e)
def undelete(self, section_id=None, section_name=None):
monitor_db = database.MonitorDatabase()
try:
if section_id and section_id.isdigit():
logger.info(u"PlexPy Libraries :: Re-adding library with id %s to database." % section_id)
logger.info(u"Tautulli Libraries :: Re-adding library with id %s to database." % section_id)
monitor_db.action('UPDATE library_sections SET deleted_section = 0 WHERE section_id = ?', [section_id])
monitor_db.action('UPDATE library_sections SET keep_history = 1 WHERE section_id = ?', [section_id])
monitor_db.action('UPDATE library_sections SET do_notify = 1 WHERE section_id = ?', [section_id])
@ -933,7 +933,7 @@ class Libraries(object):
return 'Re-added library with id %s.' % section_id
elif section_name:
logger.info(u"PlexPy Libraries :: Re-adding library with name %s to database." % section_name)
logger.info(u"Tautulli Libraries :: Re-adding library with name %s to database." % section_name)
monitor_db.action('UPDATE library_sections SET deleted_section = 0 WHERE section_name = ?', [section_name])
monitor_db.action('UPDATE library_sections SET keep_history = 1 WHERE section_name = ?', [section_name])
monitor_db.action('UPDATE library_sections SET do_notify = 1 WHERE section_name = ?', [section_name])
@ -943,7 +943,7 @@ class Libraries(object):
else:
return 'Unable to re-add library, section_id or section_name not valid.'
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for undelete: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to execute database query for undelete: %s." % e)
def delete_datatable_media_info_cache(self, section_id=None):
import os
@ -953,12 +953,12 @@ class Libraries(object):
[os.remove(os.path.join(plexpy.CONFIG.CACHE_DIR, f)) for f in os.listdir(plexpy.CONFIG.CACHE_DIR)
if f.startswith('media_info-%s' % section_id) and f.endswith('.json')]
logger.debug(u"PlexPy Libraries :: Deleted media info table cache for section_id %s." % section_id)
logger.debug(u"Tautulli Libraries :: Deleted media info table cache for section_id %s." % section_id)
return 'Deleted media info table cache for library with id %s.' % section_id
else:
return 'Unable to delete media info table cache, section_id not valid.'
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to delete media info table cache: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to delete media info table cache: %s." % e)
def delete_duplicate_libraries(self):
monitor_db = database.MonitorDatabase()
@ -969,16 +969,16 @@ class Libraries(object):
server_id = plexpy.CONFIG.PMS_IDENTIFIER
try:
logger.debug(u"PlexPy Libraries :: Deleting libraries where server_id does not match %s." % server_id)
logger.debug(u"Tautulli Libraries :: Deleting libraries where server_id does not match %s." % server_id)
monitor_db.action('DELETE FROM library_sections WHERE server_id != ?', [server_id])
return 'Deleted duplicate libraries from the database.'
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to delete duplicate libraries: %s." % e)
logger.warn(u"Tautulli Libraries :: Unable to delete duplicate libraries: %s." % e)
def update_libraries_db_notify():
logger.info(u"PlexPy Libraries :: Upgrading library notification toggles...")
logger.info(u"Tautulli Libraries :: Upgrading library notification toggles...")
# Set flag first in case something fails we don't want to keep re-adding the notifiers
plexpy.CONFIG.__setattr__('UPDATE_LIBRARIES_DB_NOTIFY', 0)

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import os
@ -55,7 +55,7 @@ def get_log_tail(window=20, parsed=True, log_type="server"):
clean_lines.append(full_line)
if line_error:
logger.error('PlexPy was unable to parse some lines of the Plex Media Server log.')
logger.error('Tautulli was unable to parse some lines of the Plex Media Server log.')
return clean_lines
else:

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
from logutils.queue import QueueHandler, QueueListener
from logging import handlers
@ -38,11 +38,11 @@ MAX_FILES = 5
_BLACKLIST_WORDS = set()
# PlexPy logger
# Tautulli logger
logger = logging.getLogger("plexpy")
# PlexPy API logger
# Tautulli API logger
logger_api = logging.getLogger("plexpy_api")
# PlexPy websocket logger
# Tautulli websocket logger
logger_plex_websocket = logging.getLogger("plex_websocket")
# Global queue for multiprocessing logging
@ -177,7 +177,7 @@ def initMultiprocessing():
def initLogger(console=False, log_dir=False, verbose=False):
"""
Setup logging for PlexPy. It uses the logger instance with the name
Setup logging for Tautulli. It uses the logger instance with the name
'plexpy'. Three log handlers are added:
* RotatingFileHandler: for the file plexpy.log
@ -185,7 +185,7 @@ def initLogger(console=False, log_dir=False, verbose=False):
* StreamHandler: for console (if console)
Console logging is only enabled if console is set to True. This method can
be invoked multiple times, during different stages of PlexPy.
be invoked multiple times, during different stages of Tautulli.
"""
# Close and remove old handlers. This is required to reinit the loggers
@ -213,7 +213,7 @@ def initLogger(console=False, log_dir=False, verbose=False):
if log_dir:
file_formatter = logging.Formatter('%(asctime)s - %(levelname)-7s :: %(threadName)s : %(message)s', '%Y-%m-%d %H:%M:%S')
# Main PlexPy logger
# Main Tautulli logger
filename = os.path.join(log_dir, FILENAME)
file_handler = handlers.RotatingFileHandler(filename, maxBytes=MAX_SIZE, backupCount=MAX_FILES)
file_handler.setLevel(logging.DEBUG)
@ -221,7 +221,7 @@ def initLogger(console=False, log_dir=False, verbose=False):
logger.addHandler(file_handler)
# PlexPy API logger
# Tautulli API logger
filename = os.path.join(log_dir, FILENAME_API)
file_handler = handlers.RotatingFileHandler(filename, maxBytes=MAX_SIZE, backupCount=MAX_FILES)
file_handler.setLevel(logging.DEBUG)
@ -229,7 +229,7 @@ def initLogger(console=False, log_dir=False, verbose=False):
logger_api.addHandler(file_handler)
# PlexPy websocket logger
# Tautulli websocket logger
filename = os.path.join(log_dir, FILENAME_PLEX_WEBSOCKET)
file_handler = handlers.RotatingFileHandler(filename, maxBytes=MAX_SIZE, backupCount=MAX_FILES)
file_handler.setLevel(logging.DEBUG)
@ -307,7 +307,7 @@ def initHooks(global_exceptions=True, thread_exceptions=True, pass_original=True
threading.Thread.__init__ = new_init
# Expose logger methods
# Main PlexPy logger
# Main Tautulli logger
info = logger.info
warn = logger.warn
error = logger.error
@ -315,7 +315,7 @@ debug = logger.debug
warning = logger.warning
exception = logger.exception
# PlexPy API logger
# Tautulli API logger
api_info = logger_api.info
api_warn = logger_api.warn
api_error = logger_api.error
@ -323,7 +323,7 @@ api_debug = logger_api.debug
api_warning = logger_api.warning
api_exception = logger_api.exception
# PlexPy websocket logger
# Tautulli websocket logger
websocket_info = logger_plex_websocket.info
websocket_warn = logger_plex_websocket.warn
websocket_error = logger_plex_websocket.error

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import time
@ -64,13 +64,13 @@ def add_mobile_device(device_id=None, device_name=None, device_token=None, frien
try:
result = db.upsert(table_name='mobile_devices', key_dict=keys, value_dict=values)
except Exception as e:
logger.warn(u"PlexPy MobileApp :: Failed to register mobile device in the database: %s." % e)
logger.warn(u"Tautulli MobileApp :: Failed to register mobile device in the database: %s." % e)
return
if result == 'insert':
logger.info(u"PlexPy MobileApp :: Registered mobile device '%s' in the database." % device_name)
logger.info(u"Tautulli MobileApp :: Registered mobile device '%s' in the database." % device_name)
else:
logger.debug(u"PlexPy MobileApp :: Re-registered mobile device '%s' in the database." % device_name)
logger.debug(u"Tautulli MobileApp :: Re-registered mobile device '%s' in the database." % device_name)
return True
@ -79,7 +79,7 @@ def get_mobile_device_config(mobile_device_id=None):
if str(mobile_device_id).isdigit():
mobile_device_id = int(mobile_device_id)
else:
logger.error(u"PlexPy MobileApp :: Unable to retrieve mobile device config: invalid mobile_device_id %s." % mobile_device_id)
logger.error(u"Tautulli MobileApp :: Unable to retrieve mobile device config: invalid mobile_device_id %s." % mobile_device_id)
return None
db = database.MonitorDatabase()
@ -93,7 +93,7 @@ def set_mobile_device_config(mobile_device_id=None, **kwargs):
if str(mobile_device_id).isdigit():
mobile_device_id = int(mobile_device_id)
else:
logger.error(u"PlexPy MobileApp :: Unable to set exisiting mobile device: invalid mobile_device_id %s." % mobile_device_id)
logger.error(u"Tautulli MobileApp :: Unable to set exisiting mobile device: invalid mobile_device_id %s." % mobile_device_id)
return False
keys = {'id': mobile_device_id}
@ -105,10 +105,10 @@ def set_mobile_device_config(mobile_device_id=None, **kwargs):
db = database.MonitorDatabase()
try:
db.upsert(table_name='mobile_devices', key_dict=keys, value_dict=values)
logger.info(u"PlexPy MobileApp :: Updated mobile device agent: mobile_device_id %s." % mobile_device_id)
logger.info(u"Tautulli MobileApp :: Updated mobile device agent: mobile_device_id %s." % mobile_device_id)
return True
except Exception as e:
logger.warn(u"PlexPy MobileApp :: Unable to update mobile device: %s." % e)
logger.warn(u"Tautulli MobileApp :: Unable to update mobile device: %s." % e)
return False
@ -116,7 +116,7 @@ def delete_mobile_device(mobile_device_id=None):
db = database.MonitorDatabase()
if mobile_device_id:
logger.debug(u"PlexPy MobileApp :: Deleting device_id %s from the database." % mobile_device_id)
logger.debug(u"Tautulli MobileApp :: Deleting device_id %s from the database." % mobile_device_id)
result = db.action('DELETE FROM mobile_devices WHERE id = ?', args=[mobile_device_id])
return True
else:
@ -132,7 +132,7 @@ def set_last_seen(device_token=None):
result = db.action('UPDATE mobile_devices SET last_seen = ? WHERE device_token = ?',
args=[last_seen, device_token])
except Exception as e:
logger.warn(u"PlexPy MobileApp :: Failed to set last_seen time for device: %s." % e)
logger.warn(u"Tautulli MobileApp :: Failed to set last_seen time for device: %s." % e)
return

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import arrow
@ -54,15 +54,15 @@ def process_queue():
else:
add_notifier_each(**params)
except Exception as e:
logger.exception(u"PlexPy NotificationHandler :: Notification thread exception: %s" % e)
logger.exception(u"Tautulli NotificationHandler :: Notification thread exception: %s" % e)
queue.task_done()
logger.info(u"PlexPy NotificationHandler :: Notification thread exiting...")
logger.info(u"Tautulli NotificationHandler :: Notification thread exiting...")
def start_threads(num_threads=1):
logger.info(u"PlexPy NotificationHandler :: Starting background notification handler ({} threads).".format(num_threads))
logger.info(u"Tautulli NotificationHandler :: Starting background notification handler ({} threads).".format(num_threads))
for x in range(num_threads):
thread = threading.Thread(target=process_queue)
thread.daemon = True
@ -71,7 +71,7 @@ def start_threads(num_threads=1):
def add_notifier_each(notifier_id=None, notify_action=None, stream_data=None, timeline_data=None, manual_trigger=False, **kwargs):
if not notify_action:
logger.debug(u"PlexPy NotificationHandler :: Notify called but no action received.")
logger.debug(u"Tautulli NotificationHandler :: Notify called but no action received.")
return
if notifier_id:
@ -101,7 +101,7 @@ def add_notifier_each(notifier_id=None, notify_action=None, stream_data=None, ti
**kwargs)
if not parameters:
logger.error(u"PlexPy NotificationHandler :: Failed to build notification parameters.")
logger.error(u"Tautulli NotificationHandler :: Failed to build notification parameters.")
return
for notifier in notifiers_enabled:
@ -117,7 +117,7 @@ def add_notifier_each(notifier_id=None, notify_action=None, stream_data=None, ti
data.update(kwargs)
plexpy.NOTIFY_QUEUE.put(data)
else:
logger.debug(u"PlexPy NotificationHandler :: Custom notification conditions not satisfied, skipping notifier_id %s." % notifier['id'])
logger.debug(u"Tautulli NotificationHandler :: Custom notification conditions not satisfied, skipping notifier_id %s." % notifier['id'])
# Add on_concurrent and on_newdevice to queue if action is on_play
if notify_action == 'on_play':
@ -137,11 +137,11 @@ def notify_conditions(notify_action=None, stream_data=None, timeline_data=None):
library_details = library_data.get_details(section_id=stream_data['section_id'])
if not user_details['do_notify']:
logger.debug(u"PlexPy NotificationHandler :: Notifications for user '%s' are disabled." % user_details['username'])
logger.debug(u"Tautulli NotificationHandler :: Notifications for user '%s' are disabled." % user_details['username'])
return False
elif not library_details['do_notify'] and notify_action not in ('on_concurrent', 'on_newdevice'):
logger.debug(u"PlexPy NotificationHandler :: Notifications for library '%s' are disabled." % library_details['section_name'])
logger.debug(u"Tautulli NotificationHandler :: Notifications for library '%s' are disabled." % library_details['section_name'])
return False
if notify_action == 'on_concurrent':
@ -184,7 +184,7 @@ def notify_conditions(notify_action=None, stream_data=None, timeline_data=None):
library_details = library_data.get_details(section_id=timeline_data['section_id'])
if not library_details['do_notify_created']:
# logger.debug(u"PlexPy NotificationHandler :: Notifications for library '%s' is disabled." % library_details['section_name'])
# logger.debug(u"Tautulli NotificationHandler :: Notifications for library '%s' is disabled." % library_details['section_name'])
return False
return True
@ -200,7 +200,7 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
custom_conditions_logic = notifier_config['custom_conditions_logic']
if custom_conditions_logic:
logger.debug(u"PlexPy NotificationHandler :: Checking custom notification conditions for notifier_id %s." % notifier_id)
logger.debug(u"Tautulli NotificationHandler :: Checking custom notification conditions for notifier_id %s." % notifier_id)
custom_conditions = json.loads(notifier_config['custom_conditions'])
@ -208,7 +208,7 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
# Parse and validate the custom conditions logic
logic_groups = helpers.parse_condition_logic_string(custom_conditions_logic, len(custom_conditions))
except ValueError as e:
logger.error(u"PlexPy NotificationHandler :: Unable to parse custom condition logic '%s': %s."
logger.error(u"Tautulli NotificationHandler :: Unable to parse custom condition logic '%s': %s."
% (custom_conditions_logic, e))
return False
@ -241,7 +241,7 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
values = [float(v) for v in values]
except Exception as e:
logger.error(u"PlexPy NotificationHandler :: Unable to cast condition '%s' to type '%s'."
logger.error(u"Tautulli NotificationHandler :: Unable to cast condition '%s' to type '%s'."
% (parameter, parameter_type))
return False
@ -257,7 +257,7 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
parameter_value = float(parameters[parameter])
except Exception as e:
logger.error(u"PlexPy NotificationHandler :: Unable to cast parameter '%s' to type '%s'."
logger.error(u"Tautulli NotificationHandler :: Unable to cast parameter '%s' to type '%s'."
% (parameter, parameter_type))
return False
@ -287,17 +287,17 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
evaluated_conditions.append(any(parameter_value < c for c in values))
else:
logger.warn(u"PlexPy NotificationHandler :: Invalid condition operator '%s'." % operator)
logger.warn(u"Tautulli NotificationHandler :: Invalid condition operator '%s'." % operator)
evaluated_conditions.append(None)
# Format and evaluate the logic string
try:
evaluated_logic = helpers.eval_logic_groups_to_bool(logic_groups, evaluated_conditions)
except Exception as e:
logger.error(u"PlexPy NotificationHandler :: Unable to evaluate custom condition logic: %s." % e)
logger.error(u"Tautulli NotificationHandler :: Unable to evaluate custom condition logic: %s." % e)
return False
logger.debug(u"PlexPy NotificationHandler :: Custom condition evaluated to '%s'." % str(evaluated_logic))
logger.debug(u"Tautulli NotificationHandler :: Custom condition evaluated to '%s'." % str(evaluated_logic))
return evaluated_logic
return True
@ -311,7 +311,7 @@ def notify(notifier_id=None, notify_action=None, stream_data=None, timeline_data
# Return if the notification has already been sent
return
logger.info(u"PlexPy NotificationHandler :: Preparing notifications for notifier_id %s." % notifier_id)
logger.info(u"Tautulli NotificationHandler :: Preparing notifications for notifier_id %s." % notifier_id)
notifier_config = notifiers.get_notifier_config(notifier_id=notifier_id)
@ -319,7 +319,7 @@ def notify(notifier_id=None, notify_action=None, stream_data=None, timeline_data
return
if notify_action == 'test':
subject = kwargs.pop('subject', 'PlexPy')
subject = kwargs.pop('subject', 'Tautulli')
body = kwargs.pop('body', 'Test Notification')
script_args = kwargs.pop('script_args', [])
else:
@ -404,7 +404,7 @@ def set_notify_state(notify_action, notifier, subject, body, script_args, sessio
monitor_db.upsert(table_name='notify_log', key_dict=keys, value_dict=values)
return monitor_db.last_insert_id()
else:
logger.error(u"PlexPy NotificationHandler :: Unable to set notify state.")
logger.error(u"Tautulli NotificationHandler :: Unable to set notify state.")
def set_notify_success(notification_id):
@ -432,7 +432,7 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
updated_at = server_times['updated_at']
server_uptime = helpers.human_duration(int(time.time() - helpers.cast_to_int(updated_at)))
else:
logger.error(u"PlexPy NotificationHandler :: Unable to retrieve server uptime.")
logger.error(u"Tautulli NotificationHandler :: Unable to retrieve server uptime.")
server_uptime = 'N/A'
# Get metadata for the item
@ -445,7 +445,7 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
metadata = pms_connect.get_metadata_details(rating_key=rating_key)
if not metadata:
logger.error(u"PlexPy NotificationHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
logger.error(u"Tautulli NotificationHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
return None
## TODO: Check list of media info items, currently only grabs first item
@ -827,7 +827,7 @@ def build_server_notify_params(notify_action=None, **kwargs):
updated_at = server_times['updated_at']
server_uptime = helpers.human_duration(int(time.time() - helpers.cast_to_int(updated_at)))
else:
logger.error(u"PlexPy NotificationHandler :: Unable to retrieve server uptime.")
logger.error(u"Tautulli NotificationHandler :: Unable to retrieve server uptime.")
server_uptime = 'N/A'
available_params = {# Global paramaters
@ -853,7 +853,7 @@ def build_server_notify_params(notify_action=None, **kwargs):
'update_extra_info': pms_download_info.get('extra_info',''),
'update_changelog_added': pms_download_info.get('changelog_added',''),
'update_changelog_fixed': pms_download_info.get('changelog_fixed',''),
# PlexPy update parameters
# Tautulli update parameters
'plexpy_update_version': plexpy_download_info.get('tag_name', ''),
'plexpy_update_tar': plexpy_download_info.get('tarball_url', ''),
'plexpy_update_zip': plexpy_download_info.get('zipball_url', ''),
@ -876,10 +876,10 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
# Make sure subject and body text are strings
if not isinstance(subject, basestring):
logger.error(u"PlexPy NotificationHandler :: Invalid subject text. Using fallback.")
logger.error(u"Tautulli NotificationHandler :: Invalid subject text. Using fallback.")
subject = default_subject
if not isinstance(body, basestring):
logger.error(u"PlexPy NotificationHandler :: Invalid body text. Using fallback.")
logger.error(u"Tautulli NotificationHandler :: Invalid body text. Using fallback.")
body = default_body
media_type = parameters.get('media_type')
@ -919,10 +919,10 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
try:
script_args = [custom_formatter.format(unicode(arg), **parameters) for arg in subject.split()]
except LookupError as e:
logger.error(u"PlexPy NotificationHandler :: Unable to parse field %s in script argument. Using fallback." % e)
logger.error(u"Tautulli NotificationHandler :: Unable to parse field %s in script argument. Using fallback." % e)
script_args = []
except Exception as e:
logger.error(u"PlexPy NotificationHandler :: Unable to parse custom script arguments: %s. Using fallback." % e)
logger.error(u"Tautulli NotificationHandler :: Unable to parse custom script arguments: %s. Using fallback." % e)
script_args = []
else:
script_args = []
@ -930,19 +930,19 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
try:
subject = custom_formatter.format(unicode(subject), **parameters)
except LookupError as e:
logger.error(u"PlexPy NotificationHandler :: Unable to parse field %s in notification subject. Using fallback." % e)
logger.error(u"Tautulli NotificationHandler :: Unable to parse field %s in notification subject. Using fallback." % e)
subject = unicode(default_subject).format(**parameters)
except Exception as e:
logger.error(u"PlexPy NotificationHandler :: Unable to parse custom notification subject: %s. Using fallback." % e)
logger.error(u"Tautulli NotificationHandler :: Unable to parse custom notification subject: %s. Using fallback." % e)
subject = unicode(default_subject).format(**parameters)
try:
body = custom_formatter.format(unicode(body), **parameters)
except LookupError as e:
logger.error(u"PlexPy NotificationHandler :: Unable to parse field %s in notification body. Using fallback." % e)
logger.error(u"Tautulli NotificationHandler :: Unable to parse field %s in notification body. Using fallback." % e)
body = unicode(default_body).format(**parameters)
except Exception as e:
logger.error(u"PlexPy NotificationHandler :: Unable to parse custom notification body: %s. Using fallback." % e)
logger.error(u"Tautulli NotificationHandler :: Unable to parse custom notification body: %s. Using fallback." % e)
body = unicode(default_body).format(**parameters)
return subject, body, script_args
@ -1030,7 +1030,7 @@ def get_poster_info(poster_thumb, poster_key, poster_title):
# Delete the cached poster
os.remove(poster_file)
except Exception as e:
logger.error(u"PlexPy NotificationHandler :: Unable to retrieve poster for rating_key %s: %s." % (str(metadata['rating_key']), e))
logger.error(u"Tautulli NotificationHandler :: Unable to retrieve poster for rating_key %s: %s." % (str(metadata['rating_key']), e))
return poster_info
@ -1043,16 +1043,16 @@ def lookup_tvmaze_by_id(rating_key=None, thetvdb_id=None, imdb_id=None):
'WHERE rating_key = ?'
tvmaze_info = db.select_single(query, args=[rating_key])
except Exception as e:
logger.warn(u"PlexPy NotificationHandler :: Unable to execute database query for lookup_tvmaze_by_tvdb_id: %s." % e)
logger.warn(u"Tautulli NotificationHandler :: Unable to execute database query for lookup_tvmaze_by_tvdb_id: %s." % e)
return {}
if not tvmaze_info:
tvmaze_info = {}
if thetvdb_id:
logger.debug(u"PlexPy NotificationHandler :: Looking up TVmaze info for thetvdb_id '{}'.".format(thetvdb_id))
logger.debug(u"Tautulli NotificationHandler :: Looking up TVmaze info for thetvdb_id '{}'.".format(thetvdb_id))
else:
logger.debug(u"PlexPy NotificationHandler :: Looking up TVmaze info for imdb_id '{}'.".format(imdb_id))
logger.debug(u"Tautulli NotificationHandler :: Looking up TVmaze info for imdb_id '{}'.".format(imdb_id))
params = {'thetvdb': thetvdb_id} if thetvdb_id else {'imdb': imdb_id}
response, err_msg, req_msg = request.request_response2('http://api.tvmaze.com/lookup/shows', params=params)
@ -1076,10 +1076,10 @@ def lookup_tvmaze_by_id(rating_key=None, thetvdb_id=None, imdb_id=None):
else:
if err_msg:
logger.error(u"PlexPy NotificationHandler :: {}".format(err_msg))
logger.error(u"Tautulli NotificationHandler :: {}".format(err_msg))
if req_msg:
logger.debug(u"PlexPy NotificationHandler :: Request response: {}".format(req_msg))
logger.debug(u"Tautulli NotificationHandler :: Request response: {}".format(req_msg))
return tvmaze_info
@ -1092,16 +1092,16 @@ def lookup_themoviedb_by_id(rating_key=None, thetvdb_id=None, imdb_id=None):
'WHERE rating_key = ?'
themoviedb_info = db.select_single(query, args=[rating_key])
except Exception as e:
logger.warn(u"PlexPy NotificationHandler :: Unable to execute database query for lookup_themoviedb_by_imdb_id: %s." % e)
logger.warn(u"Tautulli NotificationHandler :: Unable to execute database query for lookup_themoviedb_by_imdb_id: %s." % e)
return {}
if not themoviedb_info:
themoviedb_info = {}
if thetvdb_id:
logger.debug(u"PlexPy NotificationHandler :: Looking up The Movie Database info for thetvdb_id '{}'.".format(thetvdb_id))
logger.debug(u"Tautulli NotificationHandler :: Looking up The Movie Database info for thetvdb_id '{}'.".format(thetvdb_id))
else:
logger.debug(u"PlexPy NotificationHandler :: Looking up The Movie Database info for imdb_id '{}'.".format(imdb_id))
logger.debug(u"Tautulli NotificationHandler :: Looking up The Movie Database info for imdb_id '{}'.".format(imdb_id))
params = {'api_key': plexpy.CONFIG.THEMOVIEDB_APIKEY,
'external_source': 'tvdb_id' if thetvdb_id else 'imdb_id'
@ -1138,10 +1138,10 @@ def lookup_themoviedb_by_id(rating_key=None, thetvdb_id=None, imdb_id=None):
else:
if err_msg:
logger.error(u"PlexPy NotificationHandler :: {}".format(err_msg))
logger.error(u"Tautulli NotificationHandler :: {}".format(err_msg))
if req_msg:
logger.debug(u"PlexPy NotificationHandler :: Request response: {}".format(req_msg))
logger.debug(u"Tautulli NotificationHandler :: Request response: {}".format(req_msg))
return themoviedb_info
@ -1157,7 +1157,7 @@ def get_themoviedb_info(rating_key=None, media_type=None, themoviedb_id=None):
'WHERE rating_key = ?'
result = db.select_single(query, args=[rating_key])
except Exception as e:
logger.warn(u"PlexPy NotificationHandler :: Unable to execute database query for get_themoviedb_info: %s." % e)
logger.warn(u"Tautulli NotificationHandler :: Unable to execute database query for get_themoviedb_info: %s." % e)
return {}
if result:
@ -1168,7 +1168,7 @@ def get_themoviedb_info(rating_key=None, media_type=None, themoviedb_id=None):
themoviedb_json = {}
logger.debug(u"PlexPy NotificationHandler :: Looking up The Movie Database info for themoviedb_id '{}'.".format(themoviedb_id))
logger.debug(u"Tautulli NotificationHandler :: Looking up The Movie Database info for themoviedb_id '{}'.".format(themoviedb_id))
params = {'api_key': plexpy.CONFIG.THEMOVIEDB_APIKEY}
response, err_msg, req_msg = request.request_response2('https://api.themoviedb.org/3/{}/{}'.format(media_type, themoviedb_id), params=params)
@ -1178,10 +1178,10 @@ def get_themoviedb_info(rating_key=None, media_type=None, themoviedb_id=None):
else:
if err_msg:
logger.error(u"PlexPy NotificationHandler :: {}".format(err_msg))
logger.error(u"Tautulli NotificationHandler :: {}".format(err_msg))
if req_msg:
logger.debug(u"PlexPy NotificationHandler :: Request response: {}".format(req_msg))
logger.debug(u"Tautulli NotificationHandler :: Request response: {}".format(req_msg))
return themoviedb_json

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import base64
import bleach
@ -92,7 +92,7 @@ AGENT_IDS = {'growl': 0,
def available_notification_agents():
agents = [{'label': 'PlexPy Android App',
agents = [{'label': 'Tautulli Remote Android App',
'name': 'androidapp',
'id': AGENT_IDS['androidapp']
},
@ -200,7 +200,7 @@ def available_notification_actions():
actions = [{'label': 'Playback Start',
'name': 'on_play',
'description': 'Trigger a notification when a stream is started.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': '{user} ({player}) started playing {title}.',
'icon': 'fa-play',
'media_types': ('movie', 'episode', 'track')
@ -208,7 +208,7 @@ def available_notification_actions():
{'label': 'Playback Stop',
'name': 'on_stop',
'description': 'Trigger a notification when a stream is stopped.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': '{user} ({player}) has stopped {title}.',
'icon': 'fa-stop',
'media_types': ('movie', 'episode', 'track')
@ -216,7 +216,7 @@ def available_notification_actions():
{'label': 'Playback Pause',
'name': 'on_pause',
'description': 'Trigger a notification when a stream is paused.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': '{user} ({player}) has paused {title}.',
'icon': 'fa-pause',
'media_types': ('movie', 'episode', 'track')
@ -224,7 +224,7 @@ def available_notification_actions():
{'label': 'Playback Resume',
'name': 'on_resume',
'description': 'Trigger a notification when a stream is resumed.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': '{user} ({player}) has resumed {title}.',
'icon': 'fa-play',
'media_types': ('movie', 'episode', 'track')
@ -232,7 +232,7 @@ def available_notification_actions():
{'label': 'Watched',
'name': 'on_watched',
'description': 'Trigger a notification when a video stream reaches the specified watch percentage.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': '{user} ({player}) has watched {title}.',
'icon': 'fa-eye',
'media_types': ('movie', 'episode', 'track')
@ -240,7 +240,7 @@ def available_notification_actions():
{'label': 'Buffer Warning',
'name': 'on_buffer',
'description': 'Trigger a notification when a stream exceeds the specified buffer threshold.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': '{user} ({player}) is buffering {title}.',
'icon': 'fa-spinner',
'media_types': ('movie', 'episode', 'track')
@ -248,7 +248,7 @@ def available_notification_actions():
{'label': 'User Concurrent Streams',
'name': 'on_concurrent',
'description': 'Trigger a notification when a user exceeds the concurrent stream threshold.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': '{user} has {user_streams} concurrent streams.',
'icon': 'fa-arrow-circle-o-right',
'media_types': ('movie', 'episode', 'track')
@ -256,7 +256,7 @@ def available_notification_actions():
{'label': 'User New Device',
'name': 'on_newdevice',
'description': 'Trigger a notification when a user streams from a new device.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': '{user} is streaming from a new device: {player}.',
'icon': 'fa-desktop',
'media_types': ('movie', 'episode', 'track')
@ -264,7 +264,7 @@ def available_notification_actions():
{'label': 'Recently Added',
'name': 'on_created',
'description': 'Trigger a notification when a media item is added to the Plex Media Server.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': '{title} was recently added to Plex.',
'icon': 'fa-download',
'media_types': ('movie', 'show', 'season', 'episode', 'artist', 'album', 'track')
@ -272,7 +272,7 @@ def available_notification_actions():
{'label': 'Plex Server Down',
'name': 'on_intdown',
'description': 'Trigger a notification when the Plex Media Server cannot be reached internally.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': 'The Plex Media Server is down.',
'icon': 'fa-server',
'media_types': ('server',)
@ -280,7 +280,7 @@ def available_notification_actions():
{'label': 'Plex Server Back Up',
'name': 'on_intup',
'description': 'Trigger a notification when the Plex Media Server can be reached internally after being down.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': 'The Plex Media Server is back up.',
'icon': 'fa-server',
'media_types': ('server',)
@ -288,7 +288,7 @@ def available_notification_actions():
{'label': 'Plex Remote Access Down',
'name': 'on_extdown',
'description': 'Trigger a notification when the Plex Media Server cannot be reached externally.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': 'The Plex Media Server remote access is down.',
'icon': 'fa-server',
'media_types': ('server',)
@ -296,7 +296,7 @@ def available_notification_actions():
{'label': 'Plex Remote Access Back Up',
'name': 'on_extup',
'description': 'Trigger a notification when the Plex Media Server can be reached externally after being down.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': 'The Plex Media Server remote access is back up.',
'icon': 'fa-server',
'media_types': ('server',)
@ -304,16 +304,16 @@ def available_notification_actions():
{'label': 'Plex Update Available',
'name': 'on_pmsupdate',
'description': 'Trigger a notification when an update for the Plex Media Server is available.',
'subject': 'PlexPy ({server_name})',
'subject': 'Tautulli ({server_name})',
'body': 'An update is available for the Plex Media Server (version {update_version}).',
'icon': 'fa-refresh',
'media_types': ('server',)
},
{'label': 'PlexPy Update Available',
{'label': 'Tautulli Update Available',
'name': 'on_plexpyupdate',
'description': 'Trigger a notification when an update for the PlexPy is available.',
'subject': 'PlexPy ({server_name})',
'body': 'An update is available for PlexPy (version {plexpy_update_version}).',
'description': 'Trigger a notification when an update for the Tautulli is available.',
'subject': 'Tautulli ({server_name})',
'body': 'An update is available for Tautulli (version {plexpy_update_version}).',
'icon': 'fa-refresh',
'media_types': ('server',)
}
@ -418,7 +418,7 @@ def delete_notifier(notifier_id=None):
db = database.MonitorDatabase()
if str(notifier_id).isdigit():
logger.debug(u"PlexPy Notifiers :: Deleting notifier_id %s from the database." % notifier_id)
logger.debug(u"Tautulli Notifiers :: Deleting notifier_id %s from the database." % notifier_id)
result = db.action('DELETE FROM notifiers WHERE id = ?',
args=[notifier_id])
return True
@ -430,7 +430,7 @@ def get_notifier_config(notifier_id=None):
if str(notifier_id).isdigit():
notifier_id = int(notifier_id)
else:
logger.error(u"PlexPy Notifiers :: Unable to retrieve notifier config: invalid notifier_id %s." % notifier_id)
logger.error(u"Tautulli Notifiers :: Unable to retrieve notifier config: invalid notifier_id %s." % notifier_id)
return None
db = database.MonitorDatabase()
@ -445,7 +445,7 @@ def get_notifier_config(notifier_id=None):
notifier_agent = get_agent_class(agent_id=result['agent_id'], config=config)
notifier_config = notifier_agent.return_config_options()
except Exception as e:
logger.error(u"PlexPy Notifiers :: Failed to get notifier config options: %s." % e)
logger.error(u"Tautulli Notifiers :: Failed to get notifier config options: %s." % e)
return
notify_actions = get_notify_actions()
@ -470,13 +470,13 @@ def add_notifier_config(agent_id=None, **kwargs):
if str(agent_id).isdigit():
agent_id = int(agent_id)
else:
logger.error(u"PlexPy Notifiers :: Unable to add new notifier: invalid agent_id %s." % agent_id)
logger.error(u"Tautulli Notifiers :: Unable to add new notifier: invalid agent_id %s." % agent_id)
return False
agent = next((a for a in available_notification_agents() if a['id'] == agent_id), None)
if not agent:
logger.error(u"PlexPy Notifiers :: Unable to retrieve new notification agent: invalid agent_id %s." % agent_id)
logger.error(u"Tautulli Notifiers :: Unable to retrieve new notification agent: invalid agent_id %s." % agent_id)
return False
keys = {'id': None}
@ -499,11 +499,11 @@ def add_notifier_config(agent_id=None, **kwargs):
try:
db.upsert(table_name='notifiers', key_dict=keys, value_dict=values)
notifier_id = db.last_insert_id()
logger.info(u"PlexPy Notifiers :: Added new notification agent: %s (notifier_id %s)." % (agent['label'], notifier_id))
logger.info(u"Tautulli Notifiers :: Added new notification agent: %s (notifier_id %s)." % (agent['label'], notifier_id))
blacklist_logger()
return notifier_id
except Exception as e:
logger.warn(u"PlexPy Notifiers :: Unable to add notification agent: %s." % e)
logger.warn(u"Tautulli Notifiers :: Unable to add notification agent: %s." % e)
return False
@ -511,13 +511,13 @@ def set_notifier_config(notifier_id=None, agent_id=None, **kwargs):
if str(agent_id).isdigit():
agent_id = int(agent_id)
else:
logger.error(u"PlexPy Notifiers :: Unable to set exisiting notifier: invalid agent_id %s." % agent_id)
logger.error(u"Tautulli Notifiers :: Unable to set exisiting notifier: invalid agent_id %s." % agent_id)
return False
agent = next((a for a in available_notification_agents() if a['id'] == agent_id), None)
if not agent:
logger.error(u"PlexPy Notifiers :: Unable to retrieve existing notification agent: invalid agent_id %s." % agent_id)
logger.error(u"Tautulli Notifiers :: Unable to retrieve existing notification agent: invalid agent_id %s." % agent_id)
return False
notify_actions = get_notify_actions()
@ -549,11 +549,11 @@ def set_notifier_config(notifier_id=None, agent_id=None, **kwargs):
db = database.MonitorDatabase()
try:
db.upsert(table_name='notifiers', key_dict=keys, value_dict=values)
logger.info(u"PlexPy Notifiers :: Updated notification agent: %s (notifier_id %s)." % (agent['label'], notifier_id))
logger.info(u"Tautulli Notifiers :: Updated notification agent: %s (notifier_id %s)." % (agent['label'], notifier_id))
blacklist_logger()
return True
except Exception as e:
logger.warn(u"PlexPy Notifiers :: Unable to update notification agent: %s." % e)
logger.warn(u"Tautulli Notifiers :: Unable to update notification agent: %s." % e)
return False
@ -568,7 +568,7 @@ def send_notification(notifier_id=None, subject='', body='', notify_action='', n
notification_id=notification_id,
**kwargs)
else:
logger.debug(u"PlexPy Notifiers :: Notification requested but no notifier_id received.")
logger.debug(u"Tautulli Notifiers :: Notification requested but no notifier_id received.")
def blacklist_logger():
@ -721,7 +721,7 @@ class Notifier(object):
response, err_msg, req_msg = request.request_response2(url, method, **kwargs)
if response and not err_msg:
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
return True
else:
@ -729,13 +729,13 @@ class Notifier(object):
if response is not None and response.status_code >= 400 and response.status_code < 500:
verify_msg = " Verify you notification agent settings are correct."
logger.error(u"PlexPy Notifiers :: {name} notification failed.{}".format(verify_msg, name=self.NAME))
logger.error(u"Tautulli Notifiers :: {name} notification failed.{}".format(verify_msg, name=self.NAME))
if err_msg:
logger.error(u"PlexPy Notifiers :: {}".format(err_msg))
logger.error(u"Tautulli Notifiers :: {}".format(err_msg))
if req_msg:
logger.debug(u"PlexPy Notifiers :: Request response: {}".format(req_msg))
logger.debug(u"Tautulli Notifiers :: Request response: {}".format(req_msg))
return False
@ -746,9 +746,9 @@ class Notifier(object):
class ANDROIDAPP(Notifier):
"""
PlexPy Android app notifications
Tautulli Remote Android app notifications
"""
NAME = 'PlexPy Android App'
NAME = 'Tautulli Remote Android App'
_DEFAULT_CONFIG = {'device_id': '',
'priority': 3
}
@ -762,7 +762,7 @@ class ANDROIDAPP(Notifier):
# Check mobile device is still registered
device = mobile_app.get_mobile_devices(device_id=self.config['device_id'])
if not device:
logger.warn(u"PlexPy Notifiers :: Unable to send Android app notification: device not registered.")
logger.warn(u"Tautulli Notifiers :: Unable to send Android app notification: device not registered.")
return
else:
device = device[0]
@ -806,20 +806,20 @@ class ANDROIDAPP(Notifier):
payload = {'app_id': self._ONESIGNAL_APP_ID,
'include_player_ids': [self.config['device_id']],
'contents': {'en': 'PlexPy Notification'},
'contents': {'en': 'Tautulli Notification'},
'data': {'encrypted': True,
'cipher_text': base64.b64encode(encrypted_data),
'nonce': base64.b64encode(nonce),
'salt': base64.b64encode(salt)}
}
else:
logger.warn(u"PlexPy Notifiers :: PyCryptodome library is missing. "
logger.warn(u"Tautulli Notifiers :: PyCryptodome library is missing. "
"Android app notifications will be sent unecrypted. "
"Install the library to encrypt the notifications.")
payload = {'app_id': self._ONESIGNAL_APP_ID,
'include_player_ids': [self.config['device_id']],
'contents': {'en': 'PlexPy Notification'},
'contents': {'en': 'Tautulli Notification'},
'data': {'encrypted': False,
'plain_text': plaintext_data}
}
@ -837,7 +837,7 @@ class ANDROIDAPP(Notifier):
query = 'SELECT * FROM mobile_devices'
result = db.select(query=query)
except Exception as e:
logger.warn(u"PlexPy Notifiers :: Unable to retrieve Android app devices list: %s." % e)
logger.warn(u"Tautulli Notifiers :: Unable to retrieve Android app devices list: %s." % e)
return {'': ''}
devices = {}
@ -893,7 +893,7 @@ class ANDROIDAPP(Notifier):
'name': 'androidapp_device_id',
'description': 'Set your Android app device or ' \
'<a data-tab-destination="tabs-android_app" data-toggle="tab" data-dismiss="modal" ' \
'style="cursor: pointer;">register a new device</a> with PlexPy.',
'style="cursor: pointer;">register a new device</a> with Tautulli.',
'input_type': 'select',
'select_options': devices
})
@ -997,7 +997,7 @@ class BROWSER(Notifier):
if not subject or not body:
return
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
return True
def get_notifications(self):
@ -1280,11 +1280,11 @@ class EMAIL(Notifier):
mailserver.sendmail(self.config['from'], recipients, msg.as_string())
mailserver.quit()
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
return True
except Exception as e:
logger.error(u"PlexPy Notifiers :: {name} notification failed: {e}".format(name=self.NAME, e=e))
logger.error(u"Tautulli Notifiers :: {name} notification failed: {e}".format(name=self.NAME, e=e))
return False
def return_config_options(self):
@ -1390,7 +1390,7 @@ class FACEBOOK(Notifier):
perms=['user_managed_groups','publish_actions'])
def _get_credentials(self, code=''):
logger.info(u"PlexPy Notifiers :: Requesting access token from {name}.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: Requesting access token from {name}.".format(name=self.NAME))
app_id = plexpy.CONFIG.FACEBOOK_APP_ID
app_secret = plexpy.CONFIG.FACEBOOK_APP_SECRET
@ -1412,7 +1412,7 @@ class FACEBOOK(Notifier):
plexpy.CONFIG.FACEBOOK_TOKEN = response['access_token']
except Exception as e:
logger.error(u"PlexPy Notifiers :: Error requesting {name} access token: {e}".format(name=self.NAME, e=e))
logger.error(u"Tautulli Notifiers :: Error requesting {name} access token: {e}".format(name=self.NAME, e=e))
plexpy.CONFIG.FACEBOOK_TOKEN = ''
# Clear out temporary config values
@ -1428,14 +1428,14 @@ class FACEBOOK(Notifier):
try:
api.put_object(parent_object=self.config['group_id'], connection_name='feed', **data)
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
return True
except Exception as e:
logger.error(u"PlexPy Notifiers :: Error sending {name} post: {e}".format(name=self.NAME, e=e))
logger.error(u"Tautulli Notifiers :: Error sending {name} post: {e}".format(name=self.NAME, e=e))
return False
else:
logger.error(u"PlexPy Notifiers :: Error sending {name} post: No {name} Group ID provided.".format(name=self.NAME))
logger.error(u"Tautulli Notifiers :: Error sending {name} post: No {name} Group ID provided.".format(name=self.NAME))
return False
def notify(self, subject='', body='', action='', **kwargs):
@ -1472,19 +1472,19 @@ class FACEBOOK(Notifier):
Facebook Developers</a> to add a new app using <strong>basic setup</strong>.<br>\
Step 2: Click <strong>Add Product</strong> on the left, then <strong>Get Started</strong> \
for <strong>Facebook Login</strong>.<br>\
Step 3: Fill in <strong>Valid OAuth redirect URIs</strong> with your PlexPy URL (e.g. http://localhost:8181).<br>\
Step 3: Fill in <strong>Valid OAuth redirect URIs</strong> with your Tautulli URL (e.g. http://localhost:8181).<br>\
Step 4: Click <strong>App Review</strong> on the left and toggle "make public" to <strong>Yes</strong>.<br>\
Step 5: Fill in the <strong>PlexPy URL</strong> below with the exact same URL from Step 3.<br>\
Step 5: Fill in the <strong>Tautulli URL</strong> below with the exact same URL from Step 3.<br>\
Step 6: Fill in the <strong>App ID</strong> and <strong>App Secret</strong> below.<br>\
Step 7: Click the <strong>Request Authorization</strong> button below to retrieve your access token.<br>\
Step 8: Fill in your <strong>Access Token</strong> below if it is not filled in automatically.<br>\
Step 9: Fill in your <strong>Group ID</strong> number below. It can be found in the URL of your group page.',
'input_type': 'help'
},
{'label': 'PlexPy URL',
{'label': 'Tautulli URL',
'value': self.config['redirect_uri'],
'name': 'facebook_redirect_uri',
'description': 'Your PlexPy URL. This will tell Facebook where to redirect you after authorization.\
'description': 'Your Tautulli URL. This will tell Facebook where to redirect you after authorization.\
(e.g. http://localhost:8181)',
'input_type': 'text'
},
@ -1595,13 +1595,13 @@ class GROUPME(Notifier):
r = requests.post('https://image.groupme.com/pictures', headers=headers, data=poster_content)
if r.status_code == 200:
logger.info(u"PlexPy Notifiers :: {name} poster sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} poster sent.".format(name=self.NAME))
r_content = r.json()
data['attachments'] = [{'type': 'image',
'url': r_content['payload']['picture_url']}]
else:
logger.error(u"PlexPy Notifiers :: {name} poster failed: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"PlexPy Notifiers :: Request response: {}".format(request.server_message(r, True)))
logger.error(u"Tautulli Notifiers :: {name} poster failed: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"Tautulli Notifiers :: Request response: {}".format(request.server_message(r, True)))
return False
return self.make_request('https://api.groupme.com/v3/bots/post', json=data)
@ -1666,7 +1666,7 @@ class GROWL(Notifier):
# Register notification
growl = gntp.notifier.GrowlNotifier(
applicationName='PlexPy',
applicationName='Tautulli',
notifications=['New Event'],
defaultNotifications=['New Event'],
hostname=host,
@ -1677,10 +1677,10 @@ class GROWL(Notifier):
try:
growl.register()
except gntp.notifier.errors.NetworkError:
logger.error(u"PlexPy Notifiers :: {name} notification failed: network error".format(name=self.NAME))
logger.error(u"Tautulli Notifiers :: {name} notification failed: network error".format(name=self.NAME))
return False
except gntp.notifier.errors.AuthError:
logger.error(u"PlexPy Notifiers :: {name} notification failed: authentication error".format(name=self.NAME))
logger.error(u"Tautulli Notifiers :: {name} notification failed: authentication error".format(name=self.NAME))
return False
# Fix message
@ -1700,10 +1700,10 @@ class GROWL(Notifier):
description=body,
icon=image
)
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
return True
except gntp.notifier.errors.NetworkError:
logger.error(u"PlexPy Notifiers :: {name} notification failed: network error".format(name=self.NAME))
logger.error(u"Tautulli Notifiers :: {name} notification failed: network error".format(name=self.NAME))
return False
def return_config_options(self):
@ -1969,15 +1969,15 @@ class JOIN(Notifier):
if r.status_code == 200:
response_data = r.json()
if response_data.get('success'):
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
return True
else:
error_msg = response_data.get('errorMessage')
logger.error(u"PlexPy Notifiers :: {name} notification failed: {msg}".format(name=self.NAME, msg=error_msg))
logger.error(u"Tautulli Notifiers :: {name} notification failed: {msg}".format(name=self.NAME, msg=error_msg))
return False
else:
logger.error(u"PlexPy Notifiers :: {name} notification failed: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"PlexPy Notifiers :: Request response: {}".format(request.server_message(r, True)))
logger.error(u"Tautulli Notifiers :: {name} notification failed: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"Tautulli Notifiers :: Request response: {}".format(request.server_message(r, True)))
return False
def get_devices(self):
@ -1995,11 +1995,11 @@ class JOIN(Notifier):
return devices
else:
error_msg = response_data.get('errorMessage')
logger.info(u"PlexPy Notifiers :: Unable to retrieve {name} devices list: {msg}".format(name=self.NAME, msg=error_msg))
logger.info(u"Tautulli Notifiers :: Unable to retrieve {name} devices list: {msg}".format(name=self.NAME, msg=error_msg))
return {'': ''}
else:
logger.error(u"PlexPy Notifiers :: Unable to retrieve {name} devices list: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"PlexPy Notifiers :: Request response: {}".format(request.server_message(r, True)))
logger.error(u"Tautulli Notifiers :: Unable to retrieve {name} devices list: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"Tautulli Notifiers :: Request response: {}".format(request.server_message(r, True)))
return {'': ''}
else:
@ -2061,7 +2061,7 @@ class MQTT(Notifier):
return
if not self.config['topic']:
logger.error(u"PlexPy Notifiers :: MQTT topic not specified.")
logger.error(u"Tautulli Notifiers :: MQTT topic not specified.")
return
data = {'subject': subject.encode("utf-8"),
@ -2166,7 +2166,7 @@ class NMA(Notifier):
if not subject or not body:
return
title = 'PlexPy'
title = 'Tautulli'
batch = False
p = pynma.PyNMA()
@ -2179,10 +2179,10 @@ class NMA(Notifier):
response = p.push(title, subject, body, priority=self.config['priority'], batch_mode=batch)
if response[self.config['api_key']][u'code'] == u'200':
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
return True
else:
logger.error(u"PlexPy Notifiers :: {name} notification failed.".format(name=self.NAME))
logger.error(u"Tautulli Notifiers :: {name} notification failed.".format(name=self.NAME))
return False
def return_config_options(self):
@ -2209,7 +2209,7 @@ class OSX(Notifier):
OSX notifications
"""
NAME = 'OSX Notify'
_DEFAULT_CONFIG = {'notify_app': '/Applications/PlexPy'
_DEFAULT_CONFIG = {'notify_app': '/Applications/Tautulli'
}
def __init__(self, config=None):
@ -2219,7 +2219,7 @@ class OSX(Notifier):
self.objc = __import__("objc")
self.AppKit = __import__("AppKit")
except:
# logger.error(u"PlexPy Notifiers :: Cannot load OSX Notifications agent.")
# logger.error(u"Tautulli Notifiers :: Cannot load OSX Notifications agent.")
pass
def validate(self):
@ -2278,13 +2278,13 @@ class OSX(Notifier):
notification_center = NSUserNotificationCenter.defaultUserNotificationCenter()
notification_center.deliverNotification_(notification)
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
del pool
return True
except Exception as e:
logger.error(u"PlexPy Notifiers :: {name} failed: {e}".format(name=self.NAME, e=e))
logger.error(u"Tautulli Notifiers :: {name} failed: {e}".format(name=self.NAME, e=e))
return False
def return_config_options(self):
@ -2292,7 +2292,7 @@ class OSX(Notifier):
'value': self.config['notify_app'],
'name': 'osx_notify_app',
'description': 'Enter the path/application name to be registered with the '
'Notification Center, default is /Applications/PlexPy.',
'Notification Center, default is /Applications/Tautulli.',
'input_type': 'text'
}
]
@ -2352,7 +2352,7 @@ class PLEX(Notifier):
image = os.path.join(plexpy.DATA_DIR, os.path.abspath("data/interfaces/default/images/logo.png"))
for host in hosts:
logger.info(u"PlexPy Notifiers :: Sending notification command to {name} @ {host}".format(name=self.NAME, host=host))
logger.info(u"Tautulli Notifiers :: Sending notification command to {name} @ {host}".format(name=self.NAME, host=host))
try:
version = self._sendjson(host, 'Application.GetProperties', {'properties': ['version']})['version']['major']
@ -2368,10 +2368,10 @@ class PLEX(Notifier):
if not request:
raise Exception
else:
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
except Exception as e:
logger.error(u"PlexPy Notifiers :: {name} notification failed: {e}".format(name=self.NAME, e=e))
logger.error(u"Tautulli Notifiers :: {name} notification failed: {e}".format(name=self.NAME, e=e))
return False
return True
@ -2426,7 +2426,7 @@ class PROWL(Notifier):
return
data = {'apikey': self.config['key'],
'application': 'PlexPy',
'application': 'Tautulli',
'event': subject.encode("utf-8"),
'description': body.encode("utf-8"),
'priority': self.config['priority']}
@ -2531,8 +2531,8 @@ class PUSHBULLET(Notifier):
devices.update({'': ''})
return devices
else:
logger.error(u"PlexPy Notifiers :: Unable to retrieve {name} devices list: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"PlexPy Notifiers :: Request response: {}".format(request.server_message(r, True)))
logger.error(u"Tautulli Notifiers :: Unable to retrieve {name} devices list: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"Tautulli Notifiers :: Request response: {}".format(request.server_message(r, True)))
return {'': ''}
else:
@ -2628,8 +2628,8 @@ class PUSHOVER(Notifier):
sounds.update({'': ''})
return sounds
else:
logger.error(u"PlexPy Notifiers :: Unable to retrieve {name} sounds list: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"PlexPy Notifiers :: Request response: {}".format(request.server_message(r, True)))
logger.error(u"Tautulli Notifiers :: Unable to retrieve {name} sounds list: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"Tautulli Notifiers :: Request response: {}".format(request.server_message(r, True)))
return {'': ''}
else:
@ -2744,7 +2744,7 @@ class SCRIPTS(Notifier):
def run_script(self, script):
def kill_script(process):
logger.warn(u"PlexPy Notifiers :: Script exceeded timeout limit of %d seconds. "
logger.warn(u"Tautulli Notifiers :: Script exceeded timeout limit of %d seconds. "
"Script killed." % self.config['timeout'])
process.kill()
self.script_killed = True
@ -2771,20 +2771,20 @@ class SCRIPTS(Notifier):
if timer: timer.cancel()
except OSError as e:
logger.error(u"PlexPy Notifiers :: Failed to run script: %s" % e)
logger.error(u"Tautulli Notifiers :: Failed to run script: %s" % e)
return False
if error:
err = '\n '.join([l for l in error.splitlines()])
logger.error(u"PlexPy Notifiers :: Script error: \n %s" % err)
logger.error(u"Tautulli Notifiers :: Script error: \n %s" % err)
return False
if output:
out = '\n '.join([l for l in output.splitlines()])
logger.debug(u"PlexPy Notifiers :: Script returned: \n %s" % out)
logger.debug(u"Tautulli Notifiers :: Script returned: \n %s" % out)
if not self.script_killed:
logger.info(u"PlexPy Notifiers :: Script notification sent.")
logger.info(u"Tautulli Notifiers :: Script notification sent.")
return True
def notify(self, subject='', body='', action='', **kwargs):
@ -2795,22 +2795,22 @@ class SCRIPTS(Notifier):
action(string): 'play'
"""
if not self.config['script_folder']:
logger.error(u"PlexPy Notifiers :: No script folder specified.")
logger.error(u"Tautulli Notifiers :: No script folder specified.")
return
script_args = kwargs.get('script_args', [])
logger.debug(u"PlexPy Notifiers :: Trying to run notify script, action: %s, arguments: %s"
logger.debug(u"Tautulli Notifiers :: Trying to run notify script, action: %s, arguments: %s"
% (action, script_args))
script = kwargs.get('script', self.config.get('script', ''))
# Don't try to run the script if the action does not have one
if action and not script:
logger.debug(u"PlexPy Notifiers :: No script selected for action %s, exiting..." % action)
logger.debug(u"Tautulli Notifiers :: No script selected for action %s, exiting..." % action)
return
elif not script:
logger.debug(u"PlexPy Notifiers :: No script selected, exiting...")
logger.debug(u"Tautulli Notifiers :: No script selected, exiting...")
return
name, ext = os.path.splitext(script)
@ -2842,8 +2842,8 @@ class SCRIPTS(Notifier):
script.extend(script_args)
logger.debug(u"PlexPy Notifiers :: Full script is: %s" % script)
logger.debug(u"PlexPy Notifiers :: Executing script in a new thread.")
logger.debug(u"Tautulli Notifiers :: Full script is: %s" % script)
logger.debug(u"Tautulli Notifiers :: Executing script in a new thread.")
thread = threading.Thread(target=self.run_script, args=(script,)).start()
return True
@ -3097,10 +3097,10 @@ class TELEGRAM(Notifier):
r = requests.post('https://api.telegram.org/bot{}/sendPhoto'.format(self.config['bot_token']), json=poster_data)
if r.status_code == 200:
logger.info(u"PlexPy Notifiers :: {name} poster sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} poster sent.".format(name=self.NAME))
else:
logger.error(u"PlexPy Notifiers :: {name} poster failed: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"PlexPy Notifiers :: Request response: {}".format(request.server_message(r, True)))
logger.error(u"Tautulli Notifiers :: {name} poster failed: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug(u"Tautulli Notifiers :: Request response: {}".format(request.server_message(r, True)))
data['text'] = text
@ -3183,16 +3183,16 @@ class TWITTER(Notifier):
access_token = self.config['access_token']
access_token_secret = self.config['access_token_secret']
# logger.info(u"PlexPy Notifiers :: Sending tweet: " + message)
# logger.info(u"Tautulli Notifiers :: Sending tweet: " + message)
api = twitter.Api(consumer_key, consumer_secret, access_token, access_token_secret)
try:
api.PostUpdate(message, media=attachment)
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
return True
except Exception as e:
logger.error(u"PlexPy Notifiers :: {name} notification failed: {e}".format(name=self.NAME, e=e))
logger.error(u"Tautulli Notifiers :: {name} notification failed: {e}".format(name=self.NAME, e=e))
return False
def notify(self, subject='', body='', action='', **kwargs):
@ -3312,7 +3312,7 @@ class XBMC(Notifier):
image = os.path.join(plexpy.DATA_DIR, os.path.abspath("data/interfaces/default/images/logo.png"))
for host in hosts:
logger.info(u"PlexPy Notifiers :: Sending notification command to XMBC @ " + host)
logger.info(u"Tautulli Notifiers :: Sending notification command to XMBC @ " + host)
try:
version = self._sendjson(host, 'Application.GetProperties', {'properties': ['version']})['version']['major']
@ -3328,10 +3328,10 @@ class XBMC(Notifier):
if not request:
raise Exception
else:
logger.info(u"PlexPy Notifiers :: {name} notification sent.".format(name=self.NAME))
logger.info(u"Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
except Exception as e:
logger.error(u"PlexPy Notifiers :: {name} notification failed: {e}".format(name=self.NAME, e=e))
logger.error(u"Tautulli Notifiers :: {name} notification failed: {e}".format(name=self.NAME, e=e))
return False
return True
@ -3373,7 +3373,7 @@ class XBMC(Notifier):
def upgrade_config_to_db():
logger.info(u"PlexPy Notifiers :: Upgrading to new notification system...")
logger.info(u"Tautulli Notifiers :: Upgrading to new notification system...")
# Set flag first in case something fails we don't want to keep re-adding the notifiers
plexpy.CONFIG.__setattr__('UPDATE_NOTIFIERS_DB', 0)

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import arrow
import sqlite3
@ -33,13 +33,13 @@ def extract_plexivity_xml(xml=None):
try:
xml_parse = minidom.parseString(clean_xml)
except:
logger.warn(u"PlexPy Importer :: Error parsing XML for Plexivity database.")
logger.warn(u"Tautulli Importer :: Error parsing XML for Plexivity database.")
return None
# I think Plexivity only tracked videos and not music?
xml_head = xml_parse.getElementsByTagName('Video')
if not xml_head:
logger.warn(u"PlexPy Importer :: Error parsing XML for Plexivity database.")
logger.warn(u"Tautulli Importer :: Error parsing XML for Plexivity database.")
return None
for a in xml_head:
@ -238,23 +238,23 @@ def validate_database(database=None, table_name=None):
try:
connection = sqlite3.connect(database, timeout=20)
except sqlite3.OperationalError:
logger.error(u"PlexPy Importer :: Invalid database specified.")
logger.error(u"Tautulli Importer :: Invalid database specified.")
return 'Invalid database specified.'
except ValueError:
logger.error(u"PlexPy Importer :: Invalid database specified.")
logger.error(u"Tautulli Importer :: Invalid database specified.")
return 'Invalid database specified.'
except:
logger.error(u"PlexPy Importer :: Uncaught exception.")
logger.error(u"Tautulli Importer :: Uncaught exception.")
return 'Uncaught exception.'
try:
connection.execute('SELECT xml from %s' % table_name)
connection.close()
except sqlite3.OperationalError:
logger.error(u"PlexPy Importer :: Invalid database specified.")
logger.error(u"Tautulli Importer :: Invalid database specified.")
return 'Invalid database specified.'
except:
logger.error(u"PlexPy Importer :: Uncaught exception.")
logger.error(u"Tautulli Importer :: Uncaught exception.")
return 'Uncaught exception.'
return 'success'
@ -265,19 +265,19 @@ def import_from_plexivity(database=None, table_name=None, import_ignore_interval
connection = sqlite3.connect(database, timeout=20)
connection.row_factory = sqlite3.Row
except sqlite3.OperationalError:
logger.error(u"PlexPy Importer :: Invalid filename.")
logger.error(u"Tautulli Importer :: Invalid filename.")
return None
except ValueError:
logger.error(u"PlexPy Importer :: Invalid filename.")
logger.error(u"Tautulli Importer :: Invalid filename.")
return None
try:
connection.execute('SELECT xml from %s' % table_name)
except sqlite3.OperationalError:
logger.error(u"PlexPy Importer :: Database specified does not contain the required fields.")
logger.error(u"Tautulli Importer :: Database specified does not contain the required fields.")
return None
logger.debug(u"PlexPy Importer :: Plexivity data import in progress...")
logger.debug(u"Tautulli Importer :: Plexivity data import in progress...")
ap = activity_processor.ActivityProcessor()
user_data = users.Users()
@ -286,7 +286,7 @@ def import_from_plexivity(database=None, table_name=None, import_ignore_interval
try:
plextv.refresh_users()
except:
logger.debug(u"PlexPy Importer :: Unable to refresh the users list. Aborting import.")
logger.debug(u"Tautulli Importer :: Unable to refresh the users list. Aborting import.")
return None
query = 'SELECT id AS id, ' \
@ -319,13 +319,13 @@ def import_from_plexivity(database=None, table_name=None, import_ignore_interval
# If we get back None from our xml extractor skip over the record and log error.
if not extracted_xml:
logger.error(u"PlexPy Importer :: Skipping record with id %s due to malformed xml."
logger.error(u"Tautulli Importer :: Skipping record with id %s due to malformed xml."
% str(row['id']))
continue
# Skip line if we don't have a ratingKey to work with
#if not row['rating_key']:
# logger.error(u"PlexPy Importer :: Skipping record due to null ratingKey.")
# logger.error(u"Tautulli Importer :: Skipping record due to null ratingKey.")
# continue
# If the user_id no longer exists in the friends list, pull it from the xml.
@ -427,13 +427,13 @@ def import_from_plexivity(database=None, table_name=None, import_ignore_interval
is_import=True,
import_ignore_interval=import_ignore_interval)
else:
logger.debug(u"PlexPy Importer :: Item has bad rating_key: %s" % session_history_metadata['rating_key'])
logger.debug(u"Tautulli Importer :: Item has bad rating_key: %s" % session_history_metadata['rating_key'])
logger.debug(u"PlexPy Importer :: Plexivity data import complete.")
logger.debug(u"Tautulli Importer :: Plexivity data import complete.")
import_users()
def import_users():
logger.debug(u"PlexPy Importer :: Importing Plexivity Users...")
logger.debug(u"Tautulli Importer :: Importing Plexivity Users...")
monitor_db = database.MonitorDatabase()
query = 'INSERT OR IGNORE INTO users (user_id, username) ' \
@ -442,6 +442,6 @@ def import_users():
try:
monitor_db.action(query)
logger.debug(u"PlexPy Importer :: Users imported.")
logger.debug(u"Tautulli Importer :: Users imported.")
except:
logger.debug(u"PlexPy Importer :: Failed to import users.")
logger.debug(u"Tautulli Importer :: Failed to import users.")

View file

@ -1,20 +1,20 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import base64
import json
@ -32,7 +32,7 @@ import session
def refresh_users():
logger.info(u"PlexPy PlexTV :: Requesting users list refresh...")
logger.info(u"Tautulli PlexTV :: Requesting users list refresh...")
result = PlexTV().get_full_users_list()
monitor_db = database.MonitorDatabase()
@ -81,15 +81,15 @@ def refresh_users():
monitor_db.upsert('users', new_value_dict, control_value_dict)
logger.info(u"PlexPy PlexTV :: Users list refreshed.")
logger.info(u"Tautulli PlexTV :: Users list refreshed.")
return True
else:
logger.warn(u"PlexPy PlexTV :: Unable to refresh users list.")
logger.warn(u"Tautulli PlexTV :: Unable to refresh users list.")
return False
def get_real_pms_url():
logger.info(u"PlexPy PlexTV :: Requesting URLs for server...")
logger.info(u"Tautulli PlexTV :: Requesting URLs for server...")
# Reset any current PMS_URL value
plexpy.CONFIG.__setattr__('PMS_URL', '')
@ -124,13 +124,13 @@ def get_real_pms_url():
and c['port'] == str(plexpy.CONFIG.PMS_PORT)), conns[0])
plexpy.CONFIG.__setattr__('PMS_URL', conn['uri'])
plexpy.CONFIG.write()
logger.info(u"PlexPy PlexTV :: Server URL retrieved.")
logger.info(u"Tautulli PlexTV :: Server URL retrieved.")
# get_server_urls() failed or PMS_URL not found, fallback url doesn't use SSL
if not plexpy.CONFIG.PMS_URL:
plexpy.CONFIG.__setattr__('PMS_URL', fallback_url)
plexpy.CONFIG.write()
logger.warn(u"PlexPy PlexTV :: Unable to retrieve server URLs. Using user-defined value without SSL.")
logger.warn(u"Tautulli PlexTV :: Unable to retrieve server URLs. Using user-defined value without SSL.")
# Not using SSL, remote has no effect
else:
@ -139,7 +139,7 @@ def get_real_pms_url():
plexpy.CONFIG.__setattr__('PMS_URL', fallback_url)
plexpy.CONFIG.write()
logger.info(u"PlexPy PlexTV :: Using user-defined URL.")
logger.info(u"Tautulli PlexTV :: Using user-defined URL.")
class PlexTV(object):
@ -173,8 +173,8 @@ class PlexTV(object):
uri = '/users/sign_in.xml'
base64string = base64.b64encode(('%s:%s' % (self.username, self.password)).encode('utf-8'))
headers = {'Content-Type': 'application/xml; charset=utf-8',
'X-Plex-Device-Name': 'PlexPy',
'X-Plex-Product': 'PlexPy',
'X-Plex-Device-Name': 'Tautulli',
'X-Plex-Product': 'Tautulli',
'X-Plex-Version': plexpy.common.VERSION_NUMBER,
'X-Plex-Platform': plexpy.common.PLATFORM,
'X-Plex-Platform-Version': plexpy.common.PLATFORM_VERSION,
@ -202,9 +202,9 @@ class PlexTV(object):
'user_id': xml_head[0].getAttribute('id')
}
else:
logger.warn(u"PlexPy PlexTV :: Could not get Plex authentication token.")
logger.warn(u"Tautulli PlexTV :: Could not get Plex authentication token.")
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_token: %s." % e)
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_token: %s." % e)
return None
return user
@ -213,27 +213,27 @@ class PlexTV(object):
def get_plexpy_pms_token(self, force=False):
if force:
logger.debug(u"PlexPy PlexTV :: Forcing refresh of Plex.tv token.")
logger.debug(u"Tautulli PlexTV :: Forcing refresh of Plex.tv token.")
devices_list = self.get_devices_list()
device_id = next((d for d in devices_list if d['device_identifier'] == plexpy.CONFIG.PMS_UUID), {}).get('device_id', None)
if device_id:
logger.debug(u"PlexPy PlexTV :: Removing PlexPy from Plex.tv devices.")
logger.debug(u"Tautulli PlexTV :: Removing Tautulli from Plex.tv devices.")
try:
self.delete_plextv_device(device_id=device_id)
except:
logger.error(u"PlexPy PlexTV :: Failed to remove PlexPy from Plex.tv devices.")
logger.error(u"Tautulli PlexTV :: Failed to remove Tautulli from Plex.tv devices.")
return None
else:
logger.warn(u"PlexPy PlexTV :: No existing PlexPy device found.")
logger.warn(u"Tautulli PlexTV :: No existing Tautulli device found.")
logger.info(u"PlexPy PlexTV :: Fetching a new Plex.tv token for PlexPy.")
logger.info(u"Tautulli PlexTV :: Fetching a new Plex.tv token for Tautulli.")
user = self.get_token()
if user:
token = user['auth_token']
plexpy.CONFIG.__setattr__('PMS_TOKEN', token)
plexpy.CONFIG.write()
logger.info(u"PlexPy PlexTV :: Updated Plex.tv token for PlexPy.")
logger.info(u"Tautulli PlexTV :: Updated Plex.tv token for Tautulli.")
return token
@ -244,7 +244,7 @@ class PlexTV(object):
try:
xml_head = servers.getElementsByTagName('Server')
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_server_token: %s." % e)
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_server_token: %s." % e)
return None
for a in xml_head:
@ -366,15 +366,15 @@ class PlexTV(object):
try:
xml_parse = minidom.parseString(own_account)
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_full_users_list own account: %s" % e)
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_full_users_list own account: %s" % e)
return []
except:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_full_users_list own account.")
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_full_users_list own account.")
return []
xml_head = xml_parse.getElementsByTagName('user')
if not xml_head:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_full_users_list.")
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_full_users_list.")
else:
for a in xml_head:
own_details = {"user_id": helpers.get_xml_attr(a, 'id'),
@ -396,15 +396,15 @@ class PlexTV(object):
try:
xml_parse = minidom.parseString(friends_list)
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_full_users_list friends list: %s" % e)
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_full_users_list friends list: %s" % e)
return []
except:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_full_users_list friends list.")
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_full_users_list friends list.")
return []
xml_head = xml_parse.getElementsByTagName('User')
if not xml_head:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_full_users_list.")
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_full_users_list.")
else:
for a in xml_head:
friend = {"user_id": helpers.get_xml_attr(a, 'id'),
@ -434,16 +434,16 @@ class PlexTV(object):
try:
xml_parse = minidom.parseString(sync_list)
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_synced_items: %s" % e)
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_synced_items: %s" % e)
return []
except:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_synced_items.")
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_synced_items.")
return []
xml_head = xml_parse.getElementsByTagName('SyncList')
if not xml_head:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_synced_items.")
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_synced_items.")
else:
for a in xml_head:
sync_id = helpers.get_xml_attr(a, 'id')
@ -536,7 +536,7 @@ class PlexTV(object):
return session.filter_session_info(synced_items, filter_key='user_id')
def delete_sync(self, client_id, sync_id):
logger.info(u"PlexPy PlexTV :: Deleting sync item '%s'." % sync_id)
logger.info(u"Tautulli PlexTV :: Deleting sync item '%s'." % sync_id)
self.delete_plextv_sync(client_id=client_id, sync_id=sync_id)
def get_server_urls(self, include_https=True):
@ -544,7 +544,7 @@ class PlexTV(object):
if plexpy.CONFIG.PMS_IDENTIFIER:
server_id = plexpy.CONFIG.PMS_IDENTIFIER
else:
logger.error(u"PlexPy PlexTV :: Unable to retrieve server identity.")
logger.error(u"Tautulli PlexTV :: Unable to retrieve server identity.")
return {}
plextv_resources = self.get_plextv_resources(include_https=include_https)
@ -552,16 +552,16 @@ class PlexTV(object):
try:
xml_parse = minidom.parseString(plextv_resources)
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_server_urls: %s" % e)
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_server_urls: %s" % e)
return {}
except:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_server_urls.")
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_server_urls.")
return {}
try:
xml_head = xml_parse.getElementsByTagName('Device')
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_server_urls: %s." % e)
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_server_urls: %s." % e)
return {}
# Function to get all connections for a device
@ -607,7 +607,7 @@ class PlexTV(object):
plexpy.CONFIG.PMS_IDENTIFIER = helpers.get_xml_attr(a, 'clientIdentifier')
plexpy.CONFIG.write()
logger.info(u"PlexPy PlexTV :: PMS identifier changed from %s to %s."
logger.info(u"Tautulli PlexTV :: PMS identifier changed from %s to %s."
% (server_id, plexpy.CONFIG.PMS_IDENTIFIER))
server = get_connections(a)
@ -625,7 +625,7 @@ class PlexTV(object):
try:
xml_head = servers.getElementsByTagName('Server')
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_server_times: %s." % e)
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_server_times: %s." % e)
return {}
for a in xml_head:
@ -646,7 +646,7 @@ class PlexTV(object):
try:
xml_head = servers.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Failed to get servers from plex: %s." % e)
logger.warn(u"Tautulli PlexTV :: Failed to get servers from plex: %s." % e)
return []
for a in xml_head:
@ -691,16 +691,16 @@ class PlexTV(object):
return clean_servers
def get_plex_downloads(self):
logger.debug(u"PlexPy PlexTV :: Retrieving current server version.")
logger.debug(u"Tautulli PlexTV :: Retrieving current server version.")
pmsconnect.PmsConnect().set_server_version()
logger.debug(u"PlexPy PlexTV :: Plex update channel is %s." % plexpy.CONFIG.PMS_UPDATE_CHANNEL)
logger.debug(u"Tautulli PlexTV :: Plex update channel is %s." % plexpy.CONFIG.PMS_UPDATE_CHANNEL)
plex_downloads = self.get_plextv_downloads(plexpass=(plexpy.CONFIG.PMS_UPDATE_CHANNEL == 'plexpass'))
try:
available_downloads = json.loads(plex_downloads)
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to load JSON for get_plex_updates.")
logger.warn(u"Tautulli PlexTV :: Unable to load JSON for get_plex_updates.")
return {}
# Get the updates for the platform
@ -709,7 +709,7 @@ class PlexTV(object):
available_downloads.get('nas').get(pms_platform)
if not platform_downloads:
logger.error(u"PlexPy PlexTV :: Unable to retrieve Plex updates: Could not match server platform: %s."
logger.error(u"Tautulli PlexTV :: Unable to retrieve Plex updates: Could not match server platform: %s."
% pms_platform)
return {}
@ -717,11 +717,11 @@ class PlexTV(object):
v_new = helpers.cast_to_int("".join(v.zfill(4) for v in platform_downloads.get('version', '').split('-')[0].split('.')[:4]))
if not v_old:
logger.error(u"PlexPy PlexTV :: Unable to retrieve Plex updates: Invalid current server version: %s."
logger.error(u"Tautulli PlexTV :: Unable to retrieve Plex updates: Invalid current server version: %s."
% plexpy.CONFIG.PMS_VERSION)
return {}
if not v_new:
logger.error(u"PlexPy PlexTV :: Unable to retrieve Plex updates: Invalid new server version: %s."
logger.error(u"Tautulli PlexTV :: Unable to retrieve Plex updates: Invalid new server version: %s."
% platform_downloads.get('version'))
return {}
@ -752,13 +752,13 @@ class PlexTV(object):
try:
subscription = account_data.getElementsByTagName('subscription')
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_plexpass_status: %s." % e)
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_plexpass_status: %s." % e)
return False
if subscription and helpers.get_xml_attr(subscription[0], 'active') == '1':
return True
else:
logger.debug(u"PlexPy PlexTV :: Plex Pass subscription not found.")
logger.debug(u"Tautulli PlexTV :: Plex Pass subscription not found.")
plexpy.CONFIG.__setattr__('PMS_PLEXPASS', 0)
plexpy.CONFIG.write()
return False
@ -769,7 +769,7 @@ class PlexTV(object):
try:
xml_head = devices.getElementsByTagName('Device')
except Exception as e:
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_devices_list: %s." % e)
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_devices_list: %s." % e)
return []
devices_list = []

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import sqlite3
from xml.dom import minidom
@ -32,12 +32,12 @@ def extract_plexwatch_xml(xml=None):
try:
xml_parse = minidom.parseString(clean_xml)
except:
logger.warn(u"PlexPy Importer :: Error parsing XML for PlexWatch database.")
logger.warn(u"Tautulli Importer :: Error parsing XML for PlexWatch database.")
return None
xml_head = xml_parse.getElementsByTagName('opt')
if not xml_head:
logger.warn(u"PlexPy Importer :: Error parsing XML for PlexWatch database.")
logger.warn(u"Tautulli Importer :: Error parsing XML for PlexWatch database.")
return None
for a in xml_head:
@ -229,23 +229,23 @@ def validate_database(database=None, table_name=None):
try:
connection = sqlite3.connect(database, timeout=20)
except sqlite3.OperationalError:
logger.error(u"PlexPy Importer :: Invalid database specified.")
logger.error(u"Tautulli Importer :: Invalid database specified.")
return 'Invalid database specified.'
except ValueError:
logger.error(u"PlexPy Importer :: Invalid database specified.")
logger.error(u"Tautulli Importer :: Invalid database specified.")
return 'Invalid database specified.'
except:
logger.error(u"PlexPy Importer :: Uncaught exception.")
logger.error(u"Tautulli Importer :: Uncaught exception.")
return 'Uncaught exception.'
try:
connection.execute('SELECT ratingKey from %s' % table_name)
connection.close()
except sqlite3.OperationalError:
logger.error(u"PlexPy Importer :: Invalid database specified.")
logger.error(u"Tautulli Importer :: Invalid database specified.")
return 'Invalid database specified.'
except:
logger.error(u"PlexPy Importer :: Uncaught exception.")
logger.error(u"Tautulli Importer :: Uncaught exception.")
return 'Uncaught exception.'
return 'success'
@ -256,19 +256,19 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval
connection = sqlite3.connect(database, timeout=20)
connection.row_factory = sqlite3.Row
except sqlite3.OperationalError:
logger.error(u"PlexPy Importer :: Invalid filename.")
logger.error(u"Tautulli Importer :: Invalid filename.")
return None
except ValueError:
logger.error(u"PlexPy Importer :: Invalid filename.")
logger.error(u"Tautulli Importer :: Invalid filename.")
return None
try:
connection.execute('SELECT ratingKey from %s' % table_name)
except sqlite3.OperationalError:
logger.error(u"PlexPy Importer :: Database specified does not contain the required fields.")
logger.error(u"Tautulli Importer :: Database specified does not contain the required fields.")
return None
logger.debug(u"PlexPy Importer :: PlexWatch data import in progress...")
logger.debug(u"Tautulli Importer :: PlexWatch data import in progress...")
ap = activity_processor.ActivityProcessor()
user_data = users.Users()
@ -277,7 +277,7 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval
try:
plextv.refresh_users()
except:
logger.debug(u"PlexPy Importer :: Unable to refresh the users list. Aborting import.")
logger.debug(u"Tautulli Importer :: Unable to refresh the users list. Aborting import.")
return None
query = 'SELECT time AS started, ' \
@ -312,13 +312,13 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval
# If we get back None from our xml extractor skip over the record and log error.
if not extracted_xml:
logger.error(u"PlexPy Importer :: Skipping record with ratingKey %s due to malformed xml."
logger.error(u"Tautulli Importer :: Skipping record with ratingKey %s due to malformed xml."
% str(row['rating_key']))
continue
# Skip line if we don't have a ratingKey to work with
if not row['rating_key']:
logger.error(u"PlexPy Importer :: Skipping record due to null ratingKey.")
logger.error(u"Tautulli Importer :: Skipping record due to null ratingKey.")
continue
# If the user_id no longer exists in the friends list, pull it from the xml.
@ -420,13 +420,13 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval
is_import=True,
import_ignore_interval=import_ignore_interval)
else:
logger.debug(u"PlexPy Importer :: Item has bad rating_key: %s" % session_history_metadata['rating_key'])
logger.debug(u"Tautulli Importer :: Item has bad rating_key: %s" % session_history_metadata['rating_key'])
logger.debug(u"PlexPy Importer :: PlexWatch data import complete.")
logger.debug(u"Tautulli Importer :: PlexWatch data import complete.")
import_users()
def import_users():
logger.debug(u"PlexPy Importer :: Importing PlexWatch Users...")
logger.debug(u"Tautulli Importer :: Importing PlexWatch Users...")
monitor_db = database.MonitorDatabase()
query = 'INSERT OR IGNORE INTO users (user_id, username) ' \
@ -435,6 +435,6 @@ def import_users():
try:
monitor_db.action(query)
logger.debug(u"PlexPy Importer :: Users imported.")
logger.debug(u"Tautulli Importer :: Users imported.")
except:
logger.debug(u"PlexPy Importer :: Failed to import users.")
logger.debug(u"Tautulli Importer :: Failed to import users.")

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import threading
import urllib
@ -29,7 +29,7 @@ import users
def get_server_friendly_name():
logger.info(u"PlexPy Pmsconnect :: Requesting name from server...")
logger.info(u"Tautulli Pmsconnect :: Requesting name from server...")
server_name = PmsConnect().get_server_pref(pref='FriendlyName')
# If friendly name is blank
@ -43,17 +43,17 @@ def get_server_friendly_name():
if server_name and server_name != plexpy.CONFIG.PMS_NAME:
plexpy.CONFIG.__setattr__('PMS_NAME', server_name)
plexpy.CONFIG.write()
logger.info(u"PlexPy Pmsconnect :: Server name retrieved.")
logger.info(u"Tautulli Pmsconnect :: Server name retrieved.")
return server_name
def refresh_libraries():
logger.info(u"PlexPy Pmsconnect :: Requesting libraries list refresh...")
logger.info(u"Tautulli Pmsconnect :: Requesting libraries list refresh...")
server_id = plexpy.CONFIG.PMS_IDENTIFIER
if not server_id:
logger.error(u"PlexPy Pmsconnect :: No PMS identifier, cannot refresh libraries. Verify server in settings.")
logger.error(u"Tautulli Pmsconnect :: No PMS identifier, cannot refresh libraries. Verify server in settings.")
return
library_sections = PmsConnect().get_library_details()
@ -101,10 +101,10 @@ def refresh_libraries():
# # Start library labels update on it's own thread
# threading.Thread(target=libraries.update_labels).start()
logger.info(u"PlexPy Pmsconnect :: Libraries list refreshed.")
logger.info(u"Tautulli Pmsconnect :: Libraries list refreshed.")
return True
else:
logger.warn(u"PlexPy Pmsconnect :: Unable to refresh libraries list.")
logger.warn(u"Tautulli Pmsconnect :: Unable to refresh libraries list.")
return False
@ -527,7 +527,7 @@ class PmsConnect(object):
try:
xml_head = recent.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_recently_added: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_recently_added: %s." % e)
return []
recents_list = []
@ -601,7 +601,7 @@ class PmsConnect(object):
try:
xml_head = metadata.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_metadata: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_metadata: %s." % e)
return {}
metadata = {}
@ -626,7 +626,7 @@ class PmsConnect(object):
metadata_main = a.getElementsByTagName('Photo')[0]
metadata_type = helpers.get_xml_attr(metadata_main, 'type')
else:
logger.debug(u"PlexPy Pmsconnect :: Metadata failed")
logger.debug(u"Tautulli Pmsconnect :: Metadata failed")
return {}
section_id = helpers.get_xml_attr(a, 'librarySectionID')
@ -1167,7 +1167,7 @@ class PmsConnect(object):
try:
xml_head = metadata.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_metadata_children: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_metadata_children: %s." % e)
return []
metadata_list = []
@ -1217,7 +1217,7 @@ class PmsConnect(object):
try:
xml_head = libraries_data.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_library_metadata_details: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_library_metadata_details: %s." % e)
return []
metadata_list = []
@ -1262,7 +1262,7 @@ class PmsConnect(object):
try:
xml_head = session_data.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_current_activity: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_current_activity: %s." % e)
return []
session_list = []
@ -1739,7 +1739,7 @@ class PmsConnect(object):
try:
xml_head = children_data.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_children_list: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_children_list: %s." % e)
return []
children_list = []
@ -1747,7 +1747,7 @@ class PmsConnect(object):
for a in xml_head:
if a.getAttribute('size'):
if a.getAttribute('size') == '0':
logger.debug(u"PlexPy Pmsconnect :: No children data.")
logger.debug(u"Tautulli Pmsconnect :: No children data.")
children_list = {'children_count': '0',
'children_list': []
}
@ -1795,7 +1795,7 @@ class PmsConnect(object):
try:
xml_head = recent.getElementsByTagName('Server')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_server_list: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_server_list: %s." % e)
return []
server_info = []
@ -1822,7 +1822,7 @@ class PmsConnect(object):
try:
xml_head = identity.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_local_server_identity: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_local_server_identity: %s." % e)
return {}
server_identity = {}
@ -1847,7 +1847,7 @@ class PmsConnect(object):
try:
xml_head = prefs.getElementsByTagName('Setting')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_local_server_name: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_local_server_name: %s." % e)
return ''
pref_value = 'None'
@ -1858,7 +1858,7 @@ class PmsConnect(object):
return pref_value
else:
logger.debug(u"PlexPy Pmsconnect :: Server preferences queried but no parameter received.")
logger.debug(u"Tautulli Pmsconnect :: Server preferences queried but no parameter received.")
return None
def get_server_children(self):
@ -1872,7 +1872,7 @@ class PmsConnect(object):
try:
xml_head = libraries_data.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_libraries_list: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_libraries_list: %s." % e)
return []
libraries_list = []
@ -1880,7 +1880,7 @@ class PmsConnect(object):
for a in xml_head:
if a.getAttribute('size'):
if a.getAttribute('size') == '0':
logger.debug(u"PlexPy Pmsconnect :: No libraries data.")
logger.debug(u"Tautulli Pmsconnect :: No libraries data.")
libraries_list = {'libraries_count': '0',
'libraries_list': []
}
@ -1943,13 +1943,13 @@ class PmsConnect(object):
elif str(rating_key).isdigit():
library_data = self.get_children_list(str(rating_key), output_format='xml')
else:
logger.warn(u"PlexPy Pmsconnect :: get_library_children called by invalid section_id or rating_key provided.")
logger.warn(u"Tautulli Pmsconnect :: get_library_children called by invalid section_id or rating_key provided.")
return []
try:
xml_head = library_data.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_library_children_details: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_library_children_details: %s." % e)
return []
childern_list = []
@ -1957,7 +1957,7 @@ class PmsConnect(object):
for a in xml_head:
if a.getAttribute('size'):
if a.getAttribute('size') == '0':
logger.debug(u"PlexPy Pmsconnect :: No library data.")
logger.debug(u"Tautulli Pmsconnect :: No library data.")
childern_list = {'library_count': '0',
'childern_list': []
}
@ -2092,7 +2092,7 @@ class PmsConnect(object):
try:
xml_head = labels_data.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_library_label_details: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_library_label_details: %s." % e)
return None
labels_list = []
@ -2100,7 +2100,7 @@ class PmsConnect(object):
for a in xml_head:
if a.getAttribute('size'):
if a.getAttribute('size') == '0':
logger.debug(u"PlexPy Pmsconnect :: No labels data.")
logger.debug(u"Tautulli Pmsconnect :: No labels data.")
return labels_list
if a.getElementsByTagName('Directory'):
@ -2146,7 +2146,7 @@ class PmsConnect(object):
return result[0], result[1]
else:
logger.error(u"PlexPy Pmsconnect :: Image proxy queried but no input received.")
logger.error(u"Tautulli Pmsconnect :: Image proxy queried but no input received.")
def get_search_results(self, query='', limit=''):
"""
@ -2159,7 +2159,7 @@ class PmsConnect(object):
try:
xml_head = search_results.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_search_result: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_search_result: %s." % e)
return []
search_results_list = {'movie': [],
@ -2241,7 +2241,7 @@ class PmsConnect(object):
section_id = metadata['section_id']
library_name = metadata['library_name']
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to get parent_rating_key for get_rating_keys_list: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to get parent_rating_key for get_rating_keys_list: %s." % e)
return {}
elif media_type == 'episode' or media_type == 'track':
@ -2251,7 +2251,7 @@ class PmsConnect(object):
section_id = metadata['section_id']
library_name = metadata['library_name']
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to get grandparent_rating_key for get_rating_keys_list: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to get grandparent_rating_key for get_rating_keys_list: %s." % e)
return {}
# get parent_rating_keys
@ -2260,7 +2260,7 @@ class PmsConnect(object):
try:
xml_head = metadata.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_rating_keys_list: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_rating_keys_list: %s." % e)
return {}
for a in xml_head:
@ -2288,7 +2288,7 @@ class PmsConnect(object):
try:
xml_head = metadata.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_rating_keys_list: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_rating_keys_list: %s." % e)
return {}
for a in xml_head:
@ -2336,7 +2336,7 @@ class PmsConnect(object):
try:
xml_head = account_data.getElementsByTagName('MyPlex')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_server_response: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_server_response: %s." % e)
return None
server_response = {}
@ -2358,13 +2358,13 @@ class PmsConnect(object):
try:
xml_head = updater_status.getElementsByTagName('MediaContainer')
except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_update_staus: %s." % e)
logger.warn(u"Tautulli Pmsconnect :: Unable to parse XML for get_update_staus: %s." % e)
# Catch the malformed XML on certain PMX version.
# XML parser helper returns empty list if there is an error parsing XML
if updater_status == []:
logger.warn(u"Plex API updater XML is broken on the current PMS version. Please update your PMS manually.")
logger.info(u"PlexPy is unable to check for Plex updates. Disabling check for Plex updates.")
logger.info(u"Tautulli is unable to check for Plex updates. Disabling check for Plex updates.")
# Disable check for Plex updates
plexpy.CONFIG.MONITOR_PMS_UPDATES = 0

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
from bs4 import BeautifulSoup
from xml.dom import minidom

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import cherrypy

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import httpagentparser
import time
@ -93,7 +93,7 @@ class Users(object):
['session_history.id', 'session_history_media_info.id']],
kwargs=kwargs)
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_list: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for get_list: %s." % e)
return default_return
users = query['result']
@ -204,7 +204,7 @@ class Users(object):
['session_history.id', 'session_history_media_info.id']],
kwargs=kwargs)
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_unique_ips: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for get_unique_ips: %s." % e)
return default_return
results = query['result']
@ -264,7 +264,7 @@ class Users(object):
try:
monitor_db.upsert('users', value_dict, key_dict)
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for set_config: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for set_config: %s." % e)
def get_details(self, user_id=None, user=None, email=None):
default_return = {'user_id': 0,
@ -313,7 +313,7 @@ class Users(object):
else:
result = []
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_details: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for get_details: %s." % e)
result = []
user_details = {}
@ -357,7 +357,7 @@ class Users(object):
return user_details
else:
logger.warn(u"PlexPy Users :: Unable to retrieve user %s from database. Requesting user list refresh."
logger.warn(u"Tautulli Users :: Unable to retrieve user %s from database. Requesting user list refresh."
% user_id if user_id else user)
# Let's first refresh the user list to make sure the user isn't newly added and not in the db yet
plextv.refresh_users()
@ -368,7 +368,7 @@ class Users(object):
return user_details
else:
logger.warn(u"PlexPy Users :: Unable to retrieve user %s from database. Returning 'Local' user."
logger.warn(u"Tautulli Users :: Unable to retrieve user %s from database. Returning 'Local' user."
% user_id if user_id else user)
# If there is no user data we must return something
# Use "Local" user to retain compatibility with PlexWatch database value
@ -407,7 +407,7 @@ class Users(object):
else:
result = []
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_watch_time_stats: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for get_watch_time_stats: %s." % e)
result = []
for item in result:
@ -447,7 +447,7 @@ class Users(object):
else:
result = []
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_player_stats: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for get_player_stats: %s." % e)
result = []
for item in result:
@ -492,7 +492,7 @@ class Users(object):
else:
result = []
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_recently_watched: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for get_recently_watched: %s." % e)
result = []
for row in result:
@ -527,7 +527,7 @@ class Users(object):
try:
if str(user_id).isdigit():
logger.info(u"PlexPy Users :: Deleting all history for user id %s from database." % user_id)
logger.info(u"Tautulli Users :: Deleting all history for user id %s from database." % user_id)
session_history_media_info_del = \
monitor_db.action('DELETE FROM '
'session_history_media_info '
@ -551,7 +551,7 @@ class Users(object):
else:
return 'Unable to delete items. Input user_id not valid.'
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for delete_all_history: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for delete_all_history: %s." % e)
def delete(self, user_id=None):
monitor_db = database.MonitorDatabase()
@ -559,7 +559,7 @@ class Users(object):
try:
if str(user_id).isdigit():
self.delete_all_history(user_id)
logger.info(u"PlexPy Users :: Deleting user with id %s from database." % user_id)
logger.info(u"Tautulli Users :: Deleting user with id %s from database." % user_id)
monitor_db.action('UPDATE users SET deleted_user = 1 WHERE user_id = ?', [user_id])
monitor_db.action('UPDATE users SET keep_history = 0 WHERE user_id = ?', [user_id])
monitor_db.action('UPDATE users SET do_notify = 0 WHERE user_id = ?', [user_id])
@ -568,21 +568,21 @@ class Users(object):
else:
return 'Unable to delete user, user_id not valid.'
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for delete: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for delete: %s." % e)
def undelete(self, user_id=None, username=None):
monitor_db = database.MonitorDatabase()
try:
if user_id and str(user_id).isdigit():
logger.info(u"PlexPy Users :: Re-adding user with id %s to database." % user_id)
logger.info(u"Tautulli Users :: Re-adding user with id %s to database." % user_id)
monitor_db.action('UPDATE users SET deleted_user = 0 WHERE user_id = ?', [user_id])
monitor_db.action('UPDATE users SET keep_history = 1 WHERE user_id = ?', [user_id])
monitor_db.action('UPDATE users SET do_notify = 1 WHERE user_id = ?', [user_id])
return 'Re-added user with id %s.' % user_id
elif username:
logger.info(u"PlexPy Users :: Re-adding user with username %s to database." % username)
logger.info(u"Tautulli Users :: Re-adding user with username %s to database." % username)
monitor_db.action('UPDATE users SET deleted_user = 0 WHERE username = ?', [username])
monitor_db.action('UPDATE users SET keep_history = 1 WHERE username = ?', [username])
monitor_db.action('UPDATE users SET do_notify = 1 WHERE username = ?', [username])
@ -591,7 +591,7 @@ class Users(object):
else:
return 'Unable to re-add user, user_id or username not valid.'
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for undelete: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for undelete: %s." % e)
# Keep method for PlexWatch/Plexivity import
def get_user_id(self, user=None):
@ -625,7 +625,7 @@ class Users(object):
result = monitor_db.select(query)
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_user_names: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for get_user_names: %s." % e)
return None
return session.friendly_name_to_username(result)
@ -662,7 +662,7 @@ class Users(object):
'WHERE user_id = ?'
result = monitor_db.select_single(query, args=[user_id])
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_filters: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for get_filters: %s." % e)
result = {}
filters_list = {}
@ -698,7 +698,7 @@ class Users(object):
try:
monitor_db.upsert(table_name='user_login', key_dict=keys, value_dict=values)
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for set_login_log: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for set_login_log: %s." % e)
def get_datatables_user_login(self, user_id=None, kwargs=None):
default_return = {'recordsFiltered': 0,
@ -739,7 +739,7 @@ class Users(object):
join_evals=[['user_login.user_id', 'users.user_id']],
kwargs=kwargs)
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for get_datatables_user_login: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for get_datatables_user_login: %s." % e)
return default_return
results = query['result']
@ -774,10 +774,10 @@ class Users(object):
monitor_db = database.MonitorDatabase()
try:
logger.info(u"PlexPy Users :: Clearing login logs from database.")
logger.info(u"Tautulli Users :: Clearing login logs from database.")
monitor_db.action('DELETE FROM user_login')
monitor_db.action('VACUUM')
return True
except Exception as e:
logger.warn(u"PlexPy Users :: Unable to execute database query for delete_login_log: %s." % e)
logger.warn(u"Tautulli Users :: Unable to execute database query for delete_login_log: %s." % e)
return False

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import os
import platform
@ -149,11 +149,11 @@ def checkGithub(auto_update=False):
# See how many commits behind we are
if not plexpy.CURRENT_VERSION:
logger.info('You are running an unknown version of PlexPy. Run the updater to identify your version')
logger.info('You are running an unknown version of Tautulli. Run the updater to identify your version')
return plexpy.LATEST_VERSION
if plexpy.LATEST_VERSION == plexpy.CURRENT_VERSION:
logger.info('PlexPy is up to date')
logger.info('Tautulli is up to date')
return plexpy.LATEST_VERSION
logger.info('Comparing currently installed version with latest GitHub version')
@ -185,7 +185,7 @@ def checkGithub(auto_update=False):
plexpy.shutdown(restart=True, update=True)
elif plexpy.COMMITS_BEHIND == 0:
logger.info('PlexPy is up to date')
logger.info('Tautulli is up to date')
return plexpy.LATEST_VERSION
@ -338,5 +338,5 @@ def read_changelog(latest_only=False):
return output
except IOError as e:
logger.error('PlexPy Version Checker :: Unable to open changelog file. %s' % e)
logger.error('Tautulli Version Checker :: Unable to open changelog file. %s' % e)
return '<h4>Unable to open changelog file</h4>'

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
# Mostly borrowed from https://github.com/trakt/Plex-Trakt-Scrobbler
@ -75,26 +75,26 @@ def run():
# Try an open the websocket connection
while not plexpy.WS_CONNECTED and reconnects <= plexpy.CONFIG.WEBSOCKET_CONNECTION_ATTEMPTS:
try:
logger.info(u"PlexPy WebSocket :: Opening%s websocket, connection attempt %s." % (secure, str(reconnects + 1)))
logger.info(u"Tautulli WebSocket :: Opening%s websocket, connection attempt %s." % (secure, str(reconnects + 1)))
ws = create_connection(uri, header=header)
reconnects = 0
logger.info(u"PlexPy WebSocket :: Ready")
logger.info(u"Tautulli WebSocket :: Ready")
plexpy.WS_CONNECTED = True
if not plexpy.PLEX_SERVER_UP:
logger.info(u"PlexPy WebSocket :: The Plex Media Server is back up.")
logger.info(u"Tautulli WebSocket :: The Plex Media Server is back up.")
plexpy.NOTIFY_QUEUE.put({'notify_action': 'on_intup'})
plexpy.PLEX_SERVER_UP = True
plexpy.initialize_scheduler()
except IOError as e:
logger.error(u"PlexPy WebSocket :: %s." % e)
logger.error(u"Tautulli WebSocket :: %s." % e)
reconnects += 1
time.sleep(plexpy.CONFIG.WEBSOCKET_CONNECTION_TIMEOUT)
except (websocket.WebSocketException, Exception) as e:
logger.error(u"PlexPy WebSocket :: %s." % e)
logger.error(u"Tautulli WebSocket :: %s." % e)
plexpy.WS_CONNECTED = False
ws_exception = True
break
@ -114,13 +114,13 @@ def run():
if reconnects > 1:
time.sleep(plexpy.CONFIG.WEBSOCKET_CONNECTION_TIMEOUT)
logger.warn(u"PlexPy WebSocket :: Connection has closed, reconnection attempt %s." % reconnects)
logger.warn(u"Tautulli WebSocket :: Connection has closed, reconnection attempt %s." % reconnects)
try:
ws = create_connection(uri, header=header)
logger.info(u"PlexPy WebSocket :: Ready")
logger.info(u"Tautulli WebSocket :: Ready")
plexpy.WS_CONNECTED = True
except IOError as e:
logger.info(u"PlexPy WebSocket :: %s." % e)
logger.info(u"Tautulli WebSocket :: %s." % e)
else:
ws.shutdown()
@ -128,30 +128,30 @@ def run():
break
except (websocket.WebSocketException, Exception) as e:
logger.error(u"PlexPy WebSocket :: %s." % e)
logger.error(u"Tautulli WebSocket :: %s." % e)
plexpy.WS_CONNECTED = False
ws_exception = True
break
# Check if we recieved a restart notification and close websocket connection cleanly
if ws_reconnect:
logger.info(u"PlexPy WebSocket :: Reconnecting websocket...")
logger.info(u"Tautulli WebSocket :: Reconnecting websocket...")
ws.shutdown()
plexpy.WS_CONNECTED = False
start_thread()
if not plexpy.WS_CONNECTED and not ws_reconnect:
logger.error(u"PlexPy WebSocket :: Connection unavailable.")
logger.error(u"Tautulli WebSocket :: Connection unavailable.")
if not ws_exception and plexpy.PLEX_SERVER_UP:
logger.info(u"PlexPy WebSocket :: Unable to get an internal response from the server, Plex server is down.")
logger.info(u"Tautulli WebSocket :: Unable to get an internal response from the server, Plex server is down.")
plexpy.NOTIFY_QUEUE.put({'notify_action': 'on_intdown'})
plexpy.PLEX_SERVER_UP = False
on_disconnect()
plexpy.initialize_scheduler()
logger.debug(u"PlexPy WebSocket :: Leaving thread.")
logger.debug(u"Tautulli WebSocket :: Leaving thread.")
def receive(ws):
@ -178,7 +178,7 @@ def process(opcode, data):
logger.websocket_debug(data)
info = json.loads(data)
except Exception as e:
logger.warn(u"PlexPy WebSocket :: Error decoding message from websocket: %s" % e)
logger.warn(u"Tautulli WebSocket :: Error decoding message from websocket: %s" % e)
logger.debug(data)
return False
@ -192,26 +192,26 @@ def process(opcode, data):
time_line = info.get('PlaySessionStateNotification', info.get('_children', {}))
if not time_line:
logger.debug(u"PlexPy WebSocket :: Session found but unable to get timeline data.")
logger.debug(u"Tautulli WebSocket :: Session found but unable to get timeline data.")
return False
try:
activity = activity_handler.ActivityHandler(timeline=time_line[0])
activity.process()
except Exception as e:
logger.error(u"PlexPy WebSocket :: Failed to process session data: %s." % e)
logger.error(u"Tautulli WebSocket :: Failed to process session data: %s." % e)
if type == 'timeline':
time_line = info.get('TimelineEntry', info.get('_children', {}))
if not time_line:
logger.debug(u"PlexPy WebSocket :: Timeline event found but unable to get timeline data.")
logger.debug(u"Tautulli WebSocket :: Timeline event found but unable to get timeline data.")
return False
try:
activity = activity_handler.TimelineHandler(timeline=time_line[0])
activity.process()
except Exception as e:
logger.error(u"PlexPy WebSocket :: Failed to process timeline data: %s." % e)
logger.error(u"Tautulli WebSocket :: Failed to process timeline data: %s." % e)
return True

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
# http://tools.cherrypy.org/wiki/AuthenticationAndAccessRestrictions
@ -66,7 +66,7 @@ def user_login(username=None, password=None):
# Register the new user / update the access tokens.
monitor_db = MonitorDatabase()
try:
logger.debug(u"PlexPy WebAuth :: Regestering tokens for user '%s' in the database." % username)
logger.debug(u"Tautulli WebAuth :: Regestering tokens for user '%s' in the database." % username)
result = monitor_db.action('UPDATE users SET user_token = ?, server_token = ? WHERE user_id = ?',
[user_token, server_token, user_id])
@ -76,16 +76,16 @@ def user_login(username=None, password=None):
# Successful login
return True
else:
logger.warn(u"PlexPy WebAuth :: Unable to register user '%s' in database." % username)
logger.warn(u"Tautulli WebAuth :: Unable to register user '%s' in database." % username)
return None
except Exception as e:
logger.warn(u"PlexPy WebAuth :: Unable to register user '%s' in database: %s." % (username, e))
logger.warn(u"Tautulli WebAuth :: Unable to register user '%s' in database: %s." % (username, e))
return None
else:
logger.warn(u"PlexPy WebAuth :: Unable to retrieve Plex.tv server token for user '%s'." % username)
logger.warn(u"Tautulli WebAuth :: Unable to retrieve Plex.tv server token for user '%s'." % username)
return None
else:
logger.warn(u"PlexPy WebAuth :: Unable to retrieve Plex.tv user token for user '%s'." % username)
logger.warn(u"Tautulli WebAuth :: Unable to retrieve Plex.tv user token for user '%s'." % username)
return None
return None
@ -193,11 +193,11 @@ class AuthController(object):
user_agent=user_agent,
success=1)
logger.debug(u"PlexPy WebAuth :: %s user '%s' logged into PlexPy." % (user_group.capitalize(), username))
logger.debug(u"Tautulli WebAuth :: %s user '%s' logged into Tautulli." % (user_group.capitalize(), username))
def on_logout(self, username, user_group):
"""Called on logout"""
logger.debug(u"PlexPy WebAuth :: %s User '%s' logged out of PlexPy." % (user_group.capitalize(), username))
logger.debug(u"Tautulli WebAuth :: %s User '%s' logged out of Tautulli." % (user_group.capitalize(), username))
def on_login_failed(self, username):
"""Called on failed login"""
@ -256,11 +256,11 @@ class AuthController(object):
elif admin_login == '1':
self.on_login_failed(username)
logger.debug(u"PlexPy WebAuth :: Invalid admin login attempt from '%s'." % username)
logger.debug(u"Tautulli WebAuth :: Invalid admin login attempt from '%s'." % username)
raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT)
else:
self.on_login_failed(username)
logger.debug(u"PlexPy WebAuth :: Invalid login attempt from '%s'." % username)
logger.debug(u"Tautulli WebAuth :: Invalid login attempt from '%s'." % username)
return self.get_loginform(username, u"Incorrect username/email or password.")
@cherrypy.expose

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import hashlib
import json
@ -192,7 +192,7 @@ class WebInterface(object):
@requireAuth()
@addtoapi()
def get_date_formats(self, **kwargs):
""" Get the date and time formats used by PlexPy.
""" Get the date and time formats used by Tautulli.
```
Required parameters:
@ -400,7 +400,7 @@ class WebInterface(object):
@requireAuth()
@addtoapi("get_libraries_table")
def get_library_list(self, **kwargs):
""" Get the data on the PlexPy libraries table.
""" Get the data on the Tautulli libraries table.
```
Required parameters:
@ -553,7 +553,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def edit_library(self, section_id=None, **kwargs):
""" Update a library section on PlexPy.
""" Update a library section on Tautulli.
```
Required parameters:
@ -664,7 +664,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def get_library_media_info(self, section_id=None, section_type=None, rating_key=None, refresh='', **kwargs):
""" Get the data on the PlexPy media info tables.
""" Get the data on the Tautulli media info tables.
```
Required parameters:
@ -910,7 +910,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def delete_all_library_history(self, section_id, **kwargs):
""" Delete all PlexPy history for a specific library.
""" Delete all Tautulli history for a specific library.
```
Required parameters:
@ -938,7 +938,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def delete_library(self, section_id, **kwargs):
""" Delete a library section from PlexPy. Also erases all history for the library.
""" Delete a library section from Tautulli. Also erases all history for the library.
```
Required parameters:
@ -966,7 +966,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def undelete_library(self, section_id=None, section_name=None, **kwargs):
""" Restore a deleted library section to PlexPy.
""" Restore a deleted library section to Tautulli.
```
Required parameters:
@ -1066,7 +1066,7 @@ class WebInterface(object):
@requireAuth()
@addtoapi("get_users_table")
def get_user_list(self, **kwargs):
""" Get the data on PlexPy users table.
""" Get the data on Tautulli users table.
```
Required parameters:
@ -1179,7 +1179,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def edit_user(self, user_id=None, **kwargs):
""" Update a user on PlexPy.
""" Update a user on Tautulli.
```
Required parameters:
@ -1276,7 +1276,7 @@ class WebInterface(object):
@requireAuth()
@addtoapi()
def get_user_ips(self, user_id=None, **kwargs):
""" Get the data on PlexPy users IP table.
""" Get the data on Tautulli users IP table.
```
Required parameters:
@ -1342,7 +1342,7 @@ class WebInterface(object):
@requireAuth()
@addtoapi()
def get_user_logins(self, user_id=None, **kwargs):
""" Get the data on PlexPy user login table.
""" Get the data on Tautulli user login table.
```
Required parameters:
@ -1527,7 +1527,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def delete_all_user_history(self, user_id, **kwargs):
""" Delete all PlexPy history for a specific user.
""" Delete all Tautulli history for a specific user.
```
Required parameters:
@ -1553,7 +1553,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def delete_user(self, user_id, **kwargs):
""" Delete a user from PlexPy. Also erases all history for the user.
""" Delete a user from Tautulli. Also erases all history for the user.
```
Required parameters:
@ -1579,7 +1579,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def undelete_user(self, user_id=None, username=None, **kwargs):
""" Restore a deleted user to PlexPy.
""" Restore a deleted user to Tautulli.
```
Required parameters:
@ -1619,7 +1619,7 @@ class WebInterface(object):
@requireAuth()
@addtoapi()
def get_history(self, user=None, user_id=None, grouping=None, **kwargs):
""" Get the PlexPy history.
""" Get the Tautulli history.
```
Required parameters:
@ -2401,7 +2401,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def get_notification_log(self, **kwargs):
""" Get the data on the PlexPy notification logs table.
""" Get the data on the Tautulli notification logs table.
```
Required parameters:
@ -2430,7 +2430,7 @@ class WebInterface(object):
"rating_key": 153037,
"script_args": "[]",
"session_key": 147,
"subject_text": "PlexPy (Winterfell-Server)",
"subject_text": "Tautulli (Winterfell-Server)",
"timestamp": 1462253821,
"user": "DanyKhaleesi69",
"user_id": 8008135
@ -2463,7 +2463,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def delete_notification_log(self, **kwargs):
""" Delete the PlexPy notification logs.
""" Delete the Tautulli notification logs.
```
Required paramters:
@ -2488,7 +2488,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def delete_login_log(self, **kwargs):
""" Delete the PlexPy login logs.
""" Delete the Tautulli login logs.
```
Required paramters:
@ -3128,8 +3128,8 @@ class WebInterface(object):
@cherrypy.expose
@requireAuth(member_of("admin"))
@addtoapi("notify")
def send_notification(self, notifier_id=None, subject='PlexPy', body='Test notification', notify_action='', **kwargs):
""" Send a notification using PlexPy.
def send_notification(self, notifier_id=None, subject='Tautulli', body='Test notification', notify_action='', **kwargs):
""" Send a notification using Tautulli.
```
Required parameters:
@ -3210,11 +3210,11 @@ class WebInterface(object):
access_token = facebook._get_credentials(code)
if access_token:
return "Facebook authorization successful. PlexPy can send notification to Facebook. " \
return "Facebook authorization successful. Tautulli can send notification to Facebook. " \
"Your Facebook access token is:" \
"<pre>{0}</pre>You may close this page.".format(access_token)
else:
return "Failed to request authorization from Facebook. Check the PlexPy logs for details.<br />You may close this page."
return "Failed to request authorization from Facebook. Check the Tautulli logs for details.<br />You may close this page."
@cherrypy.expose
@cherrypy.tools.json_out()
@ -3342,7 +3342,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def import_database(self, app=None, database_path=None, table_name=None, import_ignore_interval=0, **kwargs):
""" Import a PlexWatch or Plexivity database into PlexPy.
""" Import a PlexWatch or Plexivity database into Tautulli.
```
Required parameters:
@ -3368,7 +3368,7 @@ class WebInterface(object):
kwargs={'database': database_path,
'table_name': table_name,
'import_ignore_interval': import_ignore_interval}).start()
return 'Import has started. Check the PlexPy logs to monitor any problems.'
return 'Import has started. Check the Tautulli logs to monitor any problems.'
else:
return db_check_msg
elif app.lower() == 'plexivity':
@ -3379,7 +3379,7 @@ class WebInterface(object):
kwargs={'database': database_path,
'table_name': table_name,
'import_ignore_interval': import_ignore_interval}).start()
return 'Import has started. Check the PlexPy logs to monitor any problems.'
return 'Import has started. Check the Tautulli logs to monitor any problems.'
else:
return db_check_msg
else:
@ -3401,7 +3401,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def get_pms_token(self, username=None, password=None, **kwargs):
""" Get the user's Plex token used for PlexPy.
""" Get the user's Plex token used for Tautulli.
```
Required parameters:
@ -3412,7 +3412,7 @@ class WebInterface(object):
None
Returns:
string: The Plex token used for PlexPy
string: The Plex token used for Tautulli
```
"""
if not username and not password:
@ -3431,7 +3431,7 @@ class WebInterface(object):
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
def get_plexpy_pms_token(self, username=None, password=None, force=False, **kwargs):
""" Fetch a new Plex.tv token for PlexPy """
""" Fetch a new Plex.tv token for Tautulli """
if not username and not password:
return None
@ -3656,7 +3656,7 @@ class WebInterface(object):
@requireAuth()
@addtoapi('notify_recently_added')
def send_manual_on_created(self, notifier_id='', rating_key='', **kwargs):
""" Send a recently added notification using PlexPy.
""" Send a recently added notification using Tautulli.
```
Required parameters:
@ -3786,7 +3786,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def download_config(self, **kwargs):
""" Download the PlexPy configuration file. """
""" Download the Tautulli configuration file. """
config_file = config.FILENAME
try:
@ -3800,7 +3800,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def download_database(self, **kwargs):
""" Download the PlexPy database file. """
""" Download the Tautulli database file. """
database_file = database.FILENAME
try:
@ -3817,7 +3817,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def download_log(self, logfile='', **kwargs):
""" Download the PlexPy log file. """
""" Download the Tautulli log file. """
if logfile == "plexpy_api":
filename = logger.FILENAME_API
log = logger.logger_api
@ -4000,7 +4000,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def update_metadata_details(self, old_rating_key, new_rating_key, media_type, **kwargs):
""" Update the metadata in the PlexPy database by matching rating keys.
""" Update the metadata in the Tautulli database by matching rating keys.
Also updates all parents or children of the media item if it is a show/season/episode
or artist/album/track.
@ -4068,7 +4068,7 @@ class WebInterface(object):
@requireAuth(member_of("admin"))
@addtoapi()
def get_old_rating_keys(self, rating_key='', media_type='', **kwargs):
""" Get a list of old rating keys from the PlexPy database for all of the item's parent/children.
""" Get a list of old rating keys from the Tautulli database for all of the item's parent/children.
```
Required parameters:

View file

@ -1,17 +1,17 @@
# This file is part of PlexPy.
# This file is part of Tautulli.
#
# PlexPy is free software: you can redistribute it and/or modify
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PlexPy is distributed in the hope that it will be useful,
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import os
import sys
@ -37,11 +37,11 @@ def initialize(options):
if plexpy.CONFIG.HTTPS_CREATE_CERT and \
(not (https_cert and os.path.exists(https_cert)) or not (https_key and os.path.exists(https_key))):
if not create_https_certificates(https_cert, https_key):
logger.warn(u"PlexPy WebStart :: Unable to create certificate and key. Disabling HTTPS")
logger.warn(u"Tautulli WebStart :: Unable to create certificate and key. Disabling HTTPS")
enable_https = False
if not (os.path.exists(https_cert) and os.path.exists(https_key)):
logger.warn(u"PlexPy WebStart :: Disabled HTTPS because of missing certificate and key.")
logger.warn(u"Tautulli WebStart :: Disabled HTTPS because of missing certificate and key.")
enable_https = False
options_dict = {
@ -67,7 +67,7 @@ def initialize(options):
protocol = "http"
if options['http_password']:
logger.info(u"PlexPy WebStart :: Web server authentication is enabled, username is '%s'", options['http_username'])
logger.info(u"Tautulli WebStart :: Web server authentication is enabled, username is '%s'", options['http_username'])
if options['http_basic_auth']:
auth_enabled = session_enabled = False
basic_auth_enabled = True
@ -97,7 +97,7 @@ def initialize(options):
'tools.sessions.on': session_enabled,
'tools.sessions.timeout': 30 * 24 * 60, # 30 days
'tools.auth_basic.on': basic_auth_enabled,
'tools.auth_basic.realm': 'PlexPy web server',
'tools.auth_basic.realm': 'Tautulli web server',
'tools.auth_basic.checkpassword': cherrypy.lib.auth_basic.checkpassword_dict({
options['http_username']: options['http_password']})
},
@ -221,7 +221,7 @@ def initialize(options):
cherrypy.tree.mount(WebInterface(), options['http_root'], config=conf)
try:
logger.info(u"PlexPy WebStart :: Starting PlexPy web server on %s://%s:%d%s", protocol,
logger.info(u"Tautulli WebStart :: Starting Tautulli web server on %s://%s:%d%s", protocol,
options['http_host'], options['http_port'], options['http_root'])
cherrypy.process.servers.check_port(str(options['http_host']), options['http_port'])
if not plexpy.DEV: