2016-03-31 15:39:00 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
#################################################################################################
|
|
|
|
|
|
|
|
import json
|
2016-07-24 08:59:48 +00:00
|
|
|
import logging
|
2016-03-31 15:39:00 +00:00
|
|
|
|
|
|
|
import xbmc
|
|
|
|
import xbmcgui
|
|
|
|
|
|
|
|
import downloadutils
|
|
|
|
import embydb_functions as embydb
|
|
|
|
import playbackutils as pbutils
|
2016-07-24 08:59:48 +00:00
|
|
|
from utils import window, settings, kodiSQL
|
2016-11-02 04:11:04 +00:00
|
|
|
from ga_client import log_error
|
2016-11-05 02:19:57 +00:00
|
|
|
from database import DatabaseConn
|
|
|
|
from contextlib import closing
|
2016-07-24 08:59:48 +00:00
|
|
|
|
|
|
|
#################################################################################################
|
|
|
|
|
|
|
|
log = logging.getLogger("EMBY."+__name__)
|
2016-03-31 15:39:00 +00:00
|
|
|
|
|
|
|
#################################################################################################
|
|
|
|
|
|
|
|
|
|
|
|
class KodiMonitor(xbmc.Monitor):
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
2016-09-27 02:50:58 +00:00
|
|
|
xbmc.Monitor.__init__(self)
|
|
|
|
|
2016-09-10 11:15:58 +00:00
|
|
|
self.download = downloadutils.DownloadUtils().downloadUrl
|
|
|
|
log.info("Kodi monitor started")
|
2016-03-31 15:39:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
def onScanStarted(self, library):
|
2016-09-10 11:15:58 +00:00
|
|
|
|
|
|
|
log.debug("Kodi library scan %s running", library)
|
2016-03-31 15:39:00 +00:00
|
|
|
if library == "video":
|
2016-06-18 03:03:28 +00:00
|
|
|
window('emby_kodiScan', value="true")
|
2016-09-10 11:15:58 +00:00
|
|
|
|
2016-03-31 15:39:00 +00:00
|
|
|
def onScanFinished(self, library):
|
2016-09-10 11:15:58 +00:00
|
|
|
|
|
|
|
log.debug("Kodi library scan %s finished", library)
|
2016-03-31 15:39:00 +00:00
|
|
|
if library == "video":
|
2016-06-18 03:03:28 +00:00
|
|
|
window('emby_kodiScan', clear=True)
|
2016-03-31 15:39:00 +00:00
|
|
|
|
|
|
|
def onSettingsChanged(self):
|
|
|
|
# Monitor emby settings
|
2016-09-10 11:15:58 +00:00
|
|
|
current_log_level = settings('logLevel')
|
|
|
|
if window('emby_logLevel') != current_log_level:
|
2016-03-31 15:39:00 +00:00
|
|
|
# The log level changed, set new prop
|
2016-09-10 11:15:58 +00:00
|
|
|
log.info("New log level: %s", current_log_level)
|
|
|
|
window('emby_logLevel', value=current_log_level)
|
2016-03-31 15:39:00 +00:00
|
|
|
|
2016-09-17 11:12:37 +00:00
|
|
|
current_context = "true" if settings('enableContext') == "true" else ""
|
|
|
|
if window('emby_context') != current_context:
|
|
|
|
log.info("New context setting: %s", current_context)
|
|
|
|
window('emby_context', value=current_context)
|
|
|
|
|
2016-11-02 04:11:04 +00:00
|
|
|
@log_error()
|
2016-03-31 15:39:00 +00:00
|
|
|
def onNotification(self, sender, method, data):
|
|
|
|
|
2016-09-10 11:15:58 +00:00
|
|
|
if method not in ('Playlist.OnAdd', 'Player.OnStop', 'Player.OnClear'):
|
|
|
|
log.info("Method: %s Data: %s", method, data)
|
|
|
|
|
2016-03-31 15:39:00 +00:00
|
|
|
if data:
|
2016-09-10 11:15:58 +00:00
|
|
|
data = json.loads(data, 'utf-8')
|
|
|
|
|
|
|
|
if method == 'Player.OnPlay':
|
|
|
|
self._on_play_(data)
|
|
|
|
|
|
|
|
elif method == 'VideoLibrary.OnUpdate':
|
|
|
|
self._video_update(data)
|
|
|
|
|
|
|
|
elif method == 'System.OnSleep':
|
2016-07-22 22:10:35 +00:00
|
|
|
# Connection is going to sleep
|
2016-07-24 08:59:48 +00:00
|
|
|
log.info("Marking the server as offline. System.OnSleep activated.")
|
2016-07-22 22:10:35 +00:00
|
|
|
window('emby_online', value="sleep")
|
2016-03-31 15:39:00 +00:00
|
|
|
|
2016-09-10 11:15:58 +00:00
|
|
|
elif method == 'System.OnWake':
|
|
|
|
self._system_wake()
|
|
|
|
|
|
|
|
elif method == 'GUI.OnScreensaverDeactivated':
|
|
|
|
self._screensaver_deactivated()
|
|
|
|
|
|
|
|
def _on_play_(self, data):
|
|
|
|
# Set up report progress for emby playback
|
|
|
|
try:
|
|
|
|
item = data['item']
|
|
|
|
kodi_id = item['id']
|
|
|
|
item_type = item['type']
|
|
|
|
except (KeyError, TypeError):
|
|
|
|
log.info("Item is invalid for playstate update")
|
|
|
|
else:
|
|
|
|
if ((settings('useDirectPaths') == "1" and not item_type == "song") or
|
|
|
|
(item_type == "song" and settings('enableMusic') == "true")):
|
|
|
|
# Set up properties for player
|
|
|
|
item_id = self._get_item_id(kodi_id, item_type)
|
|
|
|
if item_id:
|
|
|
|
url = "{server}/emby/Users/{UserId}/Items/%s?format=json" % item_id
|
|
|
|
result = self.download(url)
|
|
|
|
log.debug("Item: %s", result)
|
|
|
|
|
|
|
|
playurl = None
|
|
|
|
count = 0
|
|
|
|
while not playurl and count < 2:
|
|
|
|
try:
|
|
|
|
playurl = xbmc.Player().getPlayingFile()
|
|
|
|
except RuntimeError:
|
|
|
|
count += 1
|
|
|
|
xbmc.sleep(200)
|
|
|
|
else:
|
|
|
|
listitem = xbmcgui.ListItem()
|
|
|
|
playback = pbutils.PlaybackUtils(result)
|
|
|
|
|
|
|
|
if item_type == "song" and settings('streamMusic') == "true":
|
|
|
|
window('emby_%s.playmethod' % playurl, value="DirectStream")
|
|
|
|
else:
|
|
|
|
window('emby_%s.playmethod' % playurl, value="DirectPlay")
|
|
|
|
# Set properties for player.py
|
|
|
|
playback.setProperties(playurl, listitem)
|
|
|
|
|
|
|
|
def _video_update(self, data):
|
|
|
|
# Manually marking as watched/unwatched
|
|
|
|
try:
|
|
|
|
item = data['item']
|
|
|
|
kodi_id = item['id']
|
|
|
|
item_type = item['type']
|
|
|
|
except (KeyError, TypeError):
|
|
|
|
log.info("Item is invalid for playstate update")
|
|
|
|
else:
|
|
|
|
# Send notification to the server.
|
|
|
|
item_id = self._get_item_id(kodi_id, item_type)
|
|
|
|
if item_id:
|
|
|
|
# Stop from manually marking as watched unwatched, with actual playback.
|
|
|
|
if window('emby_skipWatched%s' % item_id) == "true":
|
|
|
|
# property is set in player.py
|
|
|
|
window('emby_skipWatched%s' % item_id, clear=True)
|
|
|
|
else:
|
|
|
|
# notify the server
|
|
|
|
url = "{server}/emby/Users/{UserId}/PlayedItems/%s?format=json" % item_id
|
|
|
|
if data.get('playcount') != 0:
|
|
|
|
self.download(url, action_type="POST")
|
|
|
|
log.info("Mark as watched for itemid: %s", item_id)
|
|
|
|
else:
|
|
|
|
self.download(url, action_type="DELETE")
|
|
|
|
log.info("Mark as unwatched for itemid: %s", item_id)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _system_wake(cls):
|
|
|
|
# Allow network to wake up
|
|
|
|
xbmc.sleep(10000)
|
|
|
|
window('emby_online', value="false")
|
|
|
|
window('emby_onWake', value="true")
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _screensaver_deactivated(cls):
|
|
|
|
|
|
|
|
if settings('dbSyncScreensaver') == "true":
|
|
|
|
xbmc.sleep(5000)
|
2016-06-18 03:03:28 +00:00
|
|
|
window('emby_onWake', value="true")
|
2016-03-31 15:39:00 +00:00
|
|
|
|
2016-09-10 11:15:58 +00:00
|
|
|
@classmethod
|
|
|
|
def _get_item_id(cls, kodi_id, item_type):
|
|
|
|
|
|
|
|
item_id = None
|
2016-04-29 05:48:09 +00:00
|
|
|
|
2016-11-05 02:19:57 +00:00
|
|
|
with DatabaseConn('emby') as conn:
|
|
|
|
with closing(conn.cursor()) as cursor:
|
|
|
|
emby_db = embydb.Embydb_Functions(cursor)
|
|
|
|
db_item = emby_db.getItem_byKodiId(kodi_id, item_type)
|
2016-04-29 05:48:09 +00:00
|
|
|
|
2016-09-10 11:15:58 +00:00
|
|
|
try:
|
|
|
|
item_id = db_item[0]
|
|
|
|
except TypeError:
|
|
|
|
log.info("Could not retrieve item Id")
|
2016-04-29 05:48:09 +00:00
|
|
|
|
2016-09-10 11:15:58 +00:00
|
|
|
return item_id
|