umbrellaplug/umbrellaplug.github.io

[FEATURE] Set watched in Kodi library when watched in Umbrella

Closed this issue · 9 comments

Feature

Hello,

My problem is the following:

  • Whenever I play something directly from the library (strm), item gets automatically marked as watched
  • If I play from a playlist generated from addon, item does not get automatically marked as watched on library. I need to force a Trakt sync in order for it to get marked on library.

I would much appreciate it if you would consider implementing this feature on Umbrella because it is the only thing that is missing for it to be the perfect player for me.

Cheers!

Download the Trakt addon, this will then sync between your library and Umbrella. In settings of the trakt addon you will see sync. So then when new movies are added to library it will all sync.

@adamosborne83
Yes I have all that setup...

That's not really the problem. As I mentioned, if I force a Trakt sync, the item in the library will be marked as watched.

The idea of the feature is to do that automatically when play ends. This happens if the item is played directly from the library (using Umbrella as a player) but its not happening if it is played from an Umbrella list inside the addon.

@adamosborne83
Yes I have all that setup...

That's not really the problem. As I mentioned, if I force a Trakt sync, the item in the library will be marked as watched.

The idea of the feature is to do that automatically when play ends. This happens if the item is played directly from the library (using Umbrella as a player) but its not happening if it is played from an Umbrella list inside the addon.

But, what I'm saying is that the trakt addon does this.
Watch Ghosbusters in Umbrella, then the trakt addon will mark it as watched in library.

@adamosborne83

It will, but not when the play ends...

I have to force a Trakt sync for it to actually mark it as watched in kodi library

@adamosborne83

It will, but not when the play ends...

I have to force a Trakt sync for it to actually mark it as watched in kodi library

Kodi library should be marked as watched when completed, the playcount in the kodi database is increased whenever an item is watched.

Couple of things.

  1. Can you turn logging on and watch something and duplicate the not being marked as watched then attach the log here?
  2. Can you provide me the exact steps I would need to take to duplicate/ re-create the issue on my system so I can look into what may be happening?
  1. I actually thought that wasn't supposed to happen. I've now digged into the logs to find a little bit more, and maybe I found the issue:

umbrella.log

[2024-06-23 01:20:48] [ plugin.video.umbrella: DEBUG ]: Sending Episode to be marked as watched. IMDB: tt1266020 TVDB: 84912 Season: 4 Episode: 22 Title: Parks and Recreation Watch Percentage Used: 85 Current Percentage: 85.01763826244158

kodi.log

2024-06-23 01:20:48.577 T:13281    info <general>: metahandler: b'Loading sqlite3 as DB engine version: 3.39.4' (ENCODED)
2024-06-23 01:20:49.625 T:13281   error <general>: metahandler: b'************* Error inserting to cache table: UNIQUE constraint failed: episode_meta.imdb_id, episode_meta.tvdb_id, episode_meta.episode_id, episode_meta.title ' (ENCODED)
  1. The steps are very easy:
  • Open Ubrella
  • Search for a tv show that you have on your kody library
  • Play an episode
  • Upon ending, navigate to kody library, episode will not be marked as watched

Hello again,

I've been digging a little further on this, mainly by reading player.py code. It is my understanding that Umbrella is behaving as expected, in other words, Umbrella will mark items as watched on Kodi library only if the play action was invoked from the library item itself:

  1. This is the function where jsonrpc is invoked in order to increase playcount:
	def libForPlayback(self):
		if self.DBID is None: return
		try:
			if self.media_type == 'movie':
				rpc = '{"jsonrpc": "2.0", "method": "VideoLibrary.SetMovieDetails", "params": {"movieid": %s, "playcount": 1 }, "id": 1 }' % str(self.DBID)
			elif self.media_type == 'episode':
				rpc = '{"jsonrpc": "2.0", "method": "VideoLibrary.SetEpisodeDetails", "params": {"episodeid": %s, "playcount": 1 }, "id": 1 }' % str(self.DBID)
			control.jsonrpc(rpc)
		except: log_utils.error()

  1. However, DBID is set on the getMeta() function, but only if the action originated from videodb and not from plugin:
	def getMeta(self, meta):
		try:
			if not meta or ('videodb' in control.infoLabel('ListItem.FolderPath')): raise Exception()
	...
			if 'plugin' not in control.infoLabel('Container.PluginName'):
				self.DBID = meta.get('movieid')
	...
			if 'plugin' not in control.infoLabel('Container.PluginName'):
				self.DBID = meta.get('episodeid')
	...

I've then messed around a bit to check if I could implement the feature I'm requesting myself xD and... I did manage to do it, like this:

  1. On getMeta() I'm calling a function to try and get the DBID:
	def getMeta(self, meta):
		try:
			if not meta or ('videodb' in control.infoLabel('ListItem.FolderPath')): raise Exception()
...
			#try to get kody library DBID
			self.DBID = self.getDBID(meta)
			return (poster, thumb, season_poster, fanart, banner, clearart, clearlogo, discart, meta)
...
  1. getDBID() is basically a copy/paste from the code within getMeta() used to assert DBID when play originates from videodb:
	def getDBID(self, meta):
		try:
			if self.media_type == 'movie':
				meta = control.jsonrpc('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"filter":{"or": [{"field": "year", "operator": "is", "value": "%s"}, {"field": "year", "operator": "is", "value": "%s"}, {"field": "year", "operator": "is", "value": "%s"}]}, "properties" : ["title", "originaltitle", "uniqueid", "year", "premiered", "genre", "studio", "country", "runtime", "rating", "votes", "mpaa", "director", "writer", "cast", "plot", "plotoutline", "tagline", "thumbnail", "art", "file"]}, "id": 1}' % (self.year, str(int(self.year) + 1), str(int(self.year) - 1)))
				meta = jsloads(meta)['result']['movies']
				try:
					meta = [i for i in meta if (i.get('uniqueid', []).get('imdb', '') == self.imdb) or (i.get('uniqueid', []).get('unknown', '') == self.imdb)] # scraper now using "unknown"
				except:
					if self.debuglog:
						log_utils.log('Get Meta Failed in getMeta: %s' % str(meta), level=log_utils.LOGDEBUG)
					meta = None
				if meta: meta = meta[0]
				else: raise Exception()
				return meta.get('movieid')
			if self.media_type == 'episode':
				show_meta = control.jsonrpc('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"filter":{"or": [{"field": "year", "operator": "is", "value": "%s"}, {"field": "year", "operator": "is", "value": "%s"}, {"field": "year", "operator": "is", "value": "%s"}]}, "properties" : ["title", "originaltitle", "uniqueid", "mpaa", "year", "genre", "runtime", "thumbnail", "file"]}, "id": 1}' % (self.year, str(int(self.year)+1), str(int(self.year)-1)))
				show_meta = jsloads(show_meta)['result']['tvshows']
				show_meta = [i for i in show_meta if i['uniqueid']['imdb'] == self.imdb]
				show_meta = [i for i in show_meta if (i.get('uniqueid', []).get('imdb', '') == self.imdb) or (i.get('uniqueid', []).get('unknown', '') == self.imdb)] # scraper now using "unknown"
				if show_meta: show_meta = show_meta[0]
				else: raise Exception()
				tvshowid = show_meta['tvshowid']
				meta = control.jsonrpc('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params":{"tvshowid": %d, "filter":{"and": [{"field": "season", "operator": "is", "value": "%s"}, {"field": "episode", "operator": "is", "value": "%s"}]}, "properties": ["showtitle", "title", "season", "episode", "firstaired", "runtime", "rating", "director", "writer", "cast", "plot", "thumbnail", "art", "file"]}, "id": 1}' % (tvshowid, self.season, self.episode))
				meta = jsloads(meta)['result']['episodes']
				if meta: meta = meta[0]
				else: raise Exception()
				return meta.get('episodeid')
		except:
			log_utils.error()
			return ''

I'm getting ready to push an update and I've included some of your code for this in the update. Can you test a test version if I send you a link?

I want to make sure I implemented your changes correctly to get the dbid. Your season offset changes for "whose line is it anyways" have not been added so you will need to manually change that after the update.

Hello!

Yes, just send me the link, I'll test as soon as I can!