Add very early attempt at retrieving IP address per stream.

This commit is contained in:
Tim 2015-07-06 00:45:42 +02:00
parent 9d5dabca14
commit 7a5cad1a31
5 changed files with 125 additions and 34 deletions

View file

@ -22,10 +22,13 @@ thumb Returns the location of the item's thumbnail. Use with p
art Returns the location of the item's artwork art Returns the location of the item's artwork
progress_percent Returns the current progress of the item. 0 to 100. progress_percent Returns the current progress of the item. 0 to 100.
user Returns the name of the user owning the session. user Returns the name of the user owning the session.
user_id Returns the Plex user id if available.
machine_id Returns the machine id of the players being used.
friendly_name Returns the friendlly name of the user owning the session. friendly_name Returns the friendlly name of the user owning the session.
state Returns the state of the current session. Either 'playing', 'paused' or 'buffering'. state Returns the state of the current session. Either 'playing', 'paused' or 'buffering'.
title Returns the name of the episode, movie or music track. title Returns the name of the episode, movie or music track.
player Returns the name of the platform used to play the stream. player Returns the name of the platform used to play the stream.
platform Returns the type of platform used to play the stream.
audio_decision Returns the audio transcode decision. Either 'transcode', 'copy' or 'direct play'. audio_decision Returns the audio transcode decision. Either 'transcode', 'copy' or 'direct play'.
audio_codec Returns the name of the audio codec. audio_codec Returns the name of the audio codec.
audio_channels Returns the number of audio channels. audio_channels Returns the number of audio channels.
@ -134,7 +137,7 @@ DOCUMENTATION :: END
</div> </div>
</div> </div>
<script> <script>
$("#platform-${a['session_key']}").html("<img src='" + getPlatformImagePath('${a['player']}') + "'>"); $("#platform-${a['session_key']}").html("<img src='" + getPlatformImagePath('${a['platform']}') + "'>");
</script> </script>
% endfor % endfor

View file

@ -18,7 +18,7 @@ import re
import os import os
import plexpy import plexpy
def get_log_tail(window=20): def get_log_tail(window=20, parsed=True):
if plexpy.CONFIG.PMS_LOGS_FOLDER: if plexpy.CONFIG.PMS_LOGS_FOLDER:
log_file = os.path.join(plexpy.CONFIG.PMS_LOGS_FOLDER, 'Plex Media Server.log') log_file = os.path.join(plexpy.CONFIG.PMS_LOGS_FOLDER, 'Plex Media Server.log')
@ -33,6 +33,7 @@ def get_log_tail(window=20):
log_lines = tail(logfile, window) log_lines = tail(logfile, window)
if parsed:
line_error = False line_error = False
clean_lines = [] clean_lines = []
for i in log_lines: for i in log_lines:
@ -52,6 +53,8 @@ def get_log_tail(window=20):
return clean_lines return clean_lines
return log_lines
# http://stackoverflow.com/a/13790289/2405162 # http://stackoverflow.com/a/13790289/2405162
def tail(f, lines=1, _buffer=4098): def tail(f, lines=1, _buffer=4098):
"""Tail a file and get X lines from the end""" """Tail a file and get X lines from the end"""

View file

@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License # 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 PlexPy. If not, see <http://www.gnu.org/licenses/>.
from plexpy import logger, helpers, plexwatch, pmsconnect, notification_handler, config from plexpy import logger, helpers, plexwatch, pmsconnect, notification_handler, config, log_reader
from xml.dom import minidom from xml.dom import minidom
from httplib import HTTPSConnection from httplib import HTTPSConnection
@ -23,6 +23,8 @@ import os
import sqlite3 import sqlite3
import threading import threading
import plexpy import plexpy
import re
import time
monitor_lock = threading.Lock() monitor_lock = threading.Lock()
@ -32,6 +34,7 @@ def check_active_sessions():
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
session_list = pms_connect.get_current_activity() session_list = pms_connect.get_current_activity()
monitor_db = MonitorDatabase() monitor_db = MonitorDatabase()
# logger.debug(u"Checking for active streams.")
if session_list['stream_count'] != '0': if session_list['stream_count'] != '0':
media_container = session_list['sessions'] media_container = session_list['sessions']
@ -46,6 +49,7 @@ def check_active_sessions():
title = session['title'] title = session['title']
parent_title = session['parent_title'] parent_title = session['parent_title']
grandparent_title = session['grandparent_title'] grandparent_title = session['grandparent_title']
machine_id = session['machine_id']
write_session = monitor_db.write_session_key(session_key, rating_key, media_type) write_session = monitor_db.write_session_key(session_key, rating_key, media_type)
if write_session == 'insert': if write_session == 'insert':
@ -60,6 +64,12 @@ def check_active_sessions():
pushmessage = '%s (%s) starting playing %s' % (friendly_name, platform, item_title) pushmessage = '%s (%s) starting playing %s' % (friendly_name, platform, item_title)
notification_handler.push_nofitications(pushmessage, 'PlexPy Playback started', 'Playback Started') notification_handler.push_nofitications(pushmessage, 'PlexPy Playback started', 'Playback Started')
# Try and grab IP address from logs
if plexpy.CONFIG.PMS_LOGS_FOLDER:
monitor_processing = MonitorProcessing()
ip_address = monitor_processing.find_session_ip(rating_key=rating_key,
machine_id=machine_id)
keys = {'session_key': session_key, keys = {'session_key': session_key,
'rating_key': rating_key} 'rating_key': rating_key}
active_streams.append(keys) active_streams.append(keys)
@ -186,3 +196,54 @@ class MonitorDatabase(object):
# We want to know if it was an update or insert # We want to know if it was an update or insert
return trans_type return trans_type
class MonitorProcessing(object):
def __init__(self):
pass
def find_session_ip(self, rating_key=None, machine_id=None):
logger.debug(u"Requesting log lines...")
log_lines = log_reader.get_log_tail(window=5000, parsed=False)
rating_key_line = 'metadata%2F' + rating_key
machine_id_line = 'session=' + machine_id
for line in reversed(log_lines):
# We're good if we find a line with both machine id and rating key
# This is usually when there is a transcode session
if machine_id_line in line and rating_key_line in line:
# Currently only checking for ipv4 addresses
ipv4 = re.findall(r'[0-9]+(?:\.[0-9]+){3}', line)
if ipv4:
# The logged IP will always be the first match and we don't want localhost entries
if ipv4[0] != '127.0.0.1':
logger.debug(u"Matched IP address (%s) for stream ratingKey %s and machineIdentifier %s."
% (ipv4[0], rating_key, machine_id))
return ipv4[0]
logger.debug(u"Unable to find IP address on first pass. Attempting fallback check in 5 seconds...")
# Wait for the log to catch up and read in new lines
time.sleep(5)
logger.debug(u"Requesting log lines...")
log_lines = log_reader.get_log_tail(window=5000, parsed=False)
for line in reversed(log_lines):
if 'GET /:/timeline' in line and rating_key_line in line:
# Currently only checking for ipv4 addresses
# This method can return the wrong IP address if more than one user
# starts watching the same media item around the same time.
ipv4 = re.findall(r'[0-9]+(?:\.[0-9]+){3}', line)
if ipv4:
# The logged IP will always be the first match and we don't want localhost entries
if ipv4[0] != '127.0.0.1':
logger.debug(u"Matched IP address (%s) for stream ratingKey %s." % (ipv4[0], rating_key))
return ipv4[0]
logger.debug(u"Unable to find IP address on fallback search. Not logging IP address.")
return None

View file

@ -24,7 +24,7 @@ class PmsConnect(object):
""" """
def __init__(self): def __init__(self):
self.protocol = 'HTTPS' self.protocol = 'HTTP'
self.request_handler = http_handler.HTTPHandler(host=plexpy.CONFIG.PMS_IP, self.request_handler = http_handler.HTTPHandler(host=plexpy.CONFIG.PMS_IP,
port=plexpy.CONFIG.PMS_PORT, port=plexpy.CONFIG.PMS_PORT,
token=plexpy.CONFIG.PMS_TOKEN) token=plexpy.CONFIG.PMS_TOKEN)
@ -196,7 +196,7 @@ class PmsConnect(object):
for a in xml_head: for a in xml_head:
if a.getAttribute('size'): if a.getAttribute('size'):
if a.getAttribute('size') == '0': if a.getAttribute('size') == '0':
output = {'recently_added': None} output = {'recently_added': []}
return output return output
if a.getElementsByTagName('Directory'): if a.getElementsByTagName('Directory'):
@ -459,14 +459,24 @@ class PmsConnect(object):
duration = helpers.get_xml_attr(media_info, 'duration') duration = helpers.get_xml_attr(media_info, 'duration')
progress = helpers.get_xml_attr(session, 'viewOffset') progress = helpers.get_xml_attr(session, 'viewOffset')
user_details = plex_watch.get_user_details(
user=helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title'))
if helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier').endswith('_Track'):
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')[:-6]
else:
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'art': helpers.get_xml_attr(session, 'art'), 'art': helpers.get_xml_attr(session, 'art'),
'parent_thumb': helpers.get_xml_attr(session, 'parentThumb'), 'parent_thumb': helpers.get_xml_attr(session, 'parentThumb'),
'thumb': helpers.get_xml_attr(session, 'thumb'), 'thumb': helpers.get_xml_attr(session, 'thumb'),
'user': helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title'), 'user': helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title'),
'friendly_name': plex_watch.get_user_friendly_name( 'user_id': user_details['user_id'],
helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title')), 'friendly_name': user_details['friendly_name'],
'player': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'), 'player': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'title'),
'platform': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'),
'machine_id': machine_id,
'state': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'), 'state': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'),
'grandparent_title': helpers.get_xml_attr(session, 'grandparentTitle'), 'grandparent_title': helpers.get_xml_attr(session, 'grandparentTitle'),
'parent_title': helpers.get_xml_attr(session, 'parentTitle'), 'parent_title': helpers.get_xml_attr(session, 'parentTitle'),
@ -528,15 +538,25 @@ class PmsConnect(object):
thumb = helpers.get_xml_attr(session, 'thumb') thumb = helpers.get_xml_attr(session, 'thumb')
use_indexes = 0 use_indexes = 0
user_details = plex_watch.get_user_details(
user=helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title'))
if helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier').endswith('_Video'):
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')[:-6]
else:
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')
if helpers.get_xml_attr(session, 'type') == 'episode': if helpers.get_xml_attr(session, 'type') == 'episode':
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'art': helpers.get_xml_attr(session, 'art'), 'art': helpers.get_xml_attr(session, 'art'),
'parent_thumb': helpers.get_xml_attr(session, 'parentThumb'), 'parent_thumb': helpers.get_xml_attr(session, 'parentThumb'),
'thumb': thumb, 'thumb': thumb,
'user': helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title'), 'user': helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title'),
'friendly_name': plex_watch.get_user_friendly_name( 'user_id': user_details['user_id'],
helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title')), 'friendly_name': user_details['friendly_name'],
'player': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'), 'player': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'title'),
'platform': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'),
'machine_id': machine_id,
'state': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'), 'state': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'),
'grandparent_title': helpers.get_xml_attr(session, 'grandparentTitle'), 'grandparent_title': helpers.get_xml_attr(session, 'grandparentTitle'),
'parent_title': helpers.get_xml_attr(session, 'parentTitle'), 'parent_title': helpers.get_xml_attr(session, 'parentTitle'),
@ -561,9 +581,11 @@ class PmsConnect(object):
'thumb': thumb, 'thumb': thumb,
'parent_thumb': helpers.get_xml_attr(session, 'parentThumb'), 'parent_thumb': helpers.get_xml_attr(session, 'parentThumb'),
'user': helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title'), 'user': helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title'),
'friendly_name': plex_watch.get_user_friendly_name( 'user_id': user_details['user_id'],
helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title')), 'friendly_name': user_details['friendly_name'],
'player': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'), 'player': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'title'),
'platform': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'),
'machine_id': machine_id,
'state': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'), 'state': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'),
'grandparent_title': helpers.get_xml_attr(session, 'grandparentTitle'), 'grandparent_title': helpers.get_xml_attr(session, 'grandparentTitle'),
'parent_title': helpers.get_xml_attr(session, 'parentTitle'), 'parent_title': helpers.get_xml_attr(session, 'parentTitle'),
@ -588,9 +610,11 @@ class PmsConnect(object):
'thumb': thumb, 'thumb': thumb,
'parent_thumb': helpers.get_xml_attr(session, 'parentThumb'), 'parent_thumb': helpers.get_xml_attr(session, 'parentThumb'),
'user': helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title'), 'user': helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title'),
'friendly_name': plex_watch.get_user_friendly_name( 'user_id': user_details['user_id'],
helpers.get_xml_attr(session.getElementsByTagName('User')[0], 'title')), 'friendly_name': user_details['friendly_name'],
'player': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'), 'player': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'title'),
'platform': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'platform'),
'machine_id': machine_id,
'state': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'), 'state': helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'state'),
'grandparent_title': helpers.get_xml_attr(session, 'grandparentTitle'), 'grandparent_title': helpers.get_xml_attr(session, 'grandparentTitle'),
'parent_title': helpers.get_xml_attr(session, 'parentTitle'), 'parent_title': helpers.get_xml_attr(session, 'parentTitle'),