Skip to content

Commit

Permalink
Merge pull request #2081 from croneter/python3-beta
Browse files Browse the repository at this point in the history
Bump Python3 stable
  • Loading branch information
croneter committed May 9, 2024
2 parents 8db9cde + 2926b26 commit f6c7bbc
Show file tree
Hide file tree
Showing 31 changed files with 781 additions and 103 deletions.
44 changes: 42 additions & 2 deletions addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="3.9.0" provider-name="croneter">
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="3.10.0" provider-name="croneter">
<requires>
<import addon="xbmc.python" version="3.0.0"/>
<import addon="script.module.requests" version="2.22.0" />
Expand All @@ -14,6 +14,16 @@
</extension>
<extension point="kodi.context.item">
<menu id="kodi.core.main">
<item library="context_watchlist_add.py">
<!-- Add to Plex Watchlist -->
<label>30402</label>
<visible>[[[String.IsEqual(ListItem.DBTYPE,movie) | String.IsEqual(ListItem.DBTYPE,tvshow) | String.IsEqual(ListItem.DBTYPE,season) | String.IsEqual(ListItem.DBTYPE,episode)] + !String.IsEmpty(ListItem.DBID)] + !String.IsEqual(ListItem.Property(LISTINGKEY),watchlist)]</visible>
</item>
<item library="context_watchlist_remove.py">
<!-- Remove from Plex Watchlist -->
<label>30403</label>
<visible>[[[String.IsEqual(ListItem.DBTYPE,movie) | String.IsEqual(ListItem.DBTYPE,tvshow)] + !String.IsEmpty(ListItem.DBID)] + String.IsEqual(ListItem.Property(LISTINGKEY),watchlist)]</visible>
</item>
<item library="context_extras.py">
<!-- Extras -->
<label>30235</label>
Expand Down Expand Up @@ -103,7 +113,37 @@
<summary lang="ko_KR">Plex를 Kodi에 기본 통합</summary>
<description lang="ko_KR">Kodi를 Plex Media Server에 연결합니다. 이 플러그인은 Plex로 모든 비디오를 관리하고 Kodi로는 관리하지 않는다고 가정합니다. Kodi 비디오 및 음악 데이터베이스에 이미 저장된 데이터가 손실 될 수 있습니다 (이 플러그인이 직접 변경하므로). 자신의 책임하에 사용하십시오!</description>
<disclaimer lang="ko_KR">자신의 책임하에 사용</disclaimer>
<news>version 3.9.0:
<news>version 3.10.0:
- WARNING: You will need to reset the Kodi database!
- Versions 3.9.1-3.9.6 for everyone

version 3.9.6 (beta only):
- Fix Base.check_db() got an unexpected keyword argument 'check_by_guid' #2074

version 3.9.5 (beta only):
- Fix sync crashing with "plex_guid is not defined" #2072

version 3.9.4 (beta only):
- WARNING: You will need to reset the Kodi database!
- Fix certain movie elements suddenly duplicating in library #2070

version 3.9.3 (beta only):
- Add Watchlist context menu commands (thanks @Spacetech) #2060
- Sync Plex Labels (thanks @Spacetech) #2058
- Fix nested folder navigation (thanks @Spacetech) #2063
- Reduce database locking (thanks @Spacetech) #2061

version 3.9.2 (beta only):
- Fix getVideoInfoTag error (thanks @Spacetech) #2052
- Automatically hide the skip button after some time (thanks @Spacetech) #2053
- Force a database reset, necessary due to #2041 #2054

version 3.9.1 (beta only):
- Add support for Plex Watchlist (thanks @Spacetech) #2041
- Use InfoTagVideo to set list item data (thanks @Spacetech) #2040
- New setting: Allow delaying background sync while playing videos (thanks @Spacetech) #2039

version 3.9.0:
- WARNING: You will need to reset the Kodi database!
- versions 3.8.4-3.8.8 for everyone

Expand Down
30 changes: 30 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
version 3.10.0:
- WARNING: You will need to reset the Kodi database!
- Versions 3.9.1-3.9.6 for everyone

version 3.9.6 (beta only):
- Fix Base.check_db() got an unexpected keyword argument 'check_by_guid' #2074

version 3.9.5 (beta only):
- Fix sync crashing with "plex_guid is not defined" #2072

version 3.9.4 (beta only):
- WARNING: You will need to reset the Kodi database!
- Fix certain movie elements suddenly duplicating in library #2070

version 3.9.3 (beta only):
- Add Watchlist context menu commands (thanks @Spacetech) #2060
- Sync Plex Labels (thanks @Spacetech) #2058
- Fix nested folder navigation (thanks @Spacetech) #2063
- Reduce database locking (thanks @Spacetech) #2061

version 3.9.2 (beta only):
- Fix getVideoInfoTag error (thanks @Spacetech) #2052
- Automatically hide the skip button after some time (thanks @Spacetech) #2053
- Force a database reset, necessary due to #2041 #2054

version 3.9.1 (beta only):
- Add support for Plex Watchlist (thanks @Spacetech) #2041
- Use InfoTagVideo to set list item data (thanks @Spacetech) #2040
- New setting: Allow delaying background sync while playing videos (thanks @Spacetech) #2039

version 3.9.0:
- WARNING: You will need to reset the Kodi database!
- versions 3.8.4-3.8.8 for everyone
Expand Down
28 changes: 28 additions & 0 deletions context_watchlist_add.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
"""
Grabs kodi_id and kodi_type for the Kodi item the context menu was called for
and sends a request to our main Python instance
"""
from urllib.parse import urlencode

from xbmc import sleep
from xbmcgui import Window

from resources.lib.contextmenu.common import kodi_item_from_listitem


def main():
kodi_id, kodi_type = kodi_item_from_listitem()
args = {
'kodi_id': kodi_id,
'kodi_type': kodi_type
}
window = Window(10000)
while window.getProperty('plexkodiconnect.command'):
sleep(20)
window.setProperty('plexkodiconnect.command',
'WATCHLIST_ADD?%s' % urlencode(args))


if __name__ == "__main__":
main()
28 changes: 28 additions & 0 deletions context_watchlist_remove.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
"""
Grabs kodi_id and kodi_type for the Kodi item the context menu was called for
and sends a request to our main Python instance
"""
from urllib.parse import urlencode

from xbmc import sleep
from xbmcgui import Window

from resources.lib.contextmenu.common import kodi_item_from_listitem


def main():
kodi_id, kodi_type = kodi_item_from_listitem()
args = {
'kodi_id': kodi_id,
'kodi_type': kodi_type
}
window = Window(10000)
while window.getProperty('plexkodiconnect.command'):
sleep(20)
window.setProperty('plexkodiconnect.command',
'WATCHLIST_REMOVE?%s' % urlencode(args))


if __name__ == "__main__":
main()
2 changes: 2 additions & 0 deletions default.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ def triage(mode, params, path, arguments, itemid):
entrypoint.show_section(params.get('section_index'))
elif mode == 'watchlater':
entrypoint.watchlater()
elif mode == 'watchlist':
entrypoint.watchlist(section_id=params.get('section_id'))
elif mode == 'channels':
entrypoint.browse_plex(key='/channels/all')
elif mode == 'search':
Expand Down
29 changes: 29 additions & 0 deletions resources/language/resource.language.en_gb/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,16 @@ msgctxt "#30401"
msgid "Plex options"
msgstr ""

# contextmenu entry
msgctxt "#30402"
msgid "Add to Plex Watchlist"
msgstr ""

# contextmenu entry
msgctxt "#30403"
msgid "Remove from Plex Watchlist"
msgstr ""

# contextmenu entry
msgctxt "#30405"
msgid "Add to Plex favorites"
Expand Down Expand Up @@ -878,6 +888,11 @@ msgctxt "#39026"
msgid "Enable constant background sync"
msgstr ""

# PKC Settings - Sync
msgctxt "#39027"
msgid "Delay background sync while media is playing"
msgstr ""

# Pop-up on initial sync
msgctxt "#39028"
msgid "CAUTION! If you choose \"Native\" mode , you might loose access to certain Plex features such as: Plex trailers and transcoding options. ALL Plex shares need to use direct paths (e.g. smb://myNAS/mymovie.mkv or \\\\myNAS/mymovie.mkv)!"
Expand Down Expand Up @@ -1231,6 +1246,10 @@ msgctxt "#39211"
msgid "Watch later"
msgstr ""

msgctxt "#39212"
msgid "Watchlist"
msgstr ""

# Error message pop-up if {0} cannot be contacted. {0} will be replaced by e.g. the PMS' name
msgctxt "#39213"
msgid "{0} offline"
Expand Down Expand Up @@ -1526,3 +1545,13 @@ msgstr ""
msgctxt "#39722"
msgid "Auto skip commercials"
msgstr ""

# PKC Settings - Playback
msgctxt "#39723"
msgid "Auto hide skip button"
msgstr ""

# PKC Settings - Playback
msgctxt "#39724"
msgid "Seconds until skip button is hidden"
msgstr ""
1 change: 1 addition & 0 deletions resources/lib/app/playstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class PlayState(object):
'playcount': None,
'external_player': False, # bool - xbmc.Player().isExternalPlayer()
'markers': [],
'markers_hidden': {},
'first_credits_marker': None,
'final_credits_marker': None
}
Expand Down
43 changes: 39 additions & 4 deletions resources/lib/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,12 @@ def show_main_menu(content_type=None):
directory_item(utils.lang(136), path)
# Plex Search "Search"
directory_item(utils.lang(137), "plugin://%s?mode=search" % v.ADDON_ID)
# Plex Watch later
# Plex Watch later and Watchlist
if content_type not in ('image', 'audio'):
directory_item(utils.lang(39211),
"plugin://%s?mode=watchlater" % v.ADDON_ID)
directory_item(utils.lang(39212),
"plugin://%s?mode=watchlist" % v.ADDON_ID)
# Plex Channels
directory_item(utils.lang(30173), "plugin://%s?mode=channels" % v.ADDON_ID)
# Plex user switch
Expand Down Expand Up @@ -203,7 +205,7 @@ def show_listing(xml, plex_type=None, section_id=None, synched=True, key=None):
return
api = API(xml[0])
# Determine content type for Kodi's Container.content
if key == '/hubs/home/continueWatching':
if key == '/hubs/home/continueWatching' or key == 'watchlist':
# Mix of movies and episodes
plex_type = v.PLEX_TYPE_VIDEO
elif key == '/hubs/home/recentlyAdded?type=2':
Expand Down Expand Up @@ -249,9 +251,19 @@ def show_listing(xml, plex_type=None, section_id=None, synched=True, key=None):
# Need to chain keys for navigation
widgets.KEY = key
# Process all items to show
all_items = mass_api(xml)
all_items = mass_api(xml, check_by_guid=key == "watchlist")

if key == "watchlist":
# filter out items that are not in the kodi db (items that will not be playable)
all_items = [item for item in all_items if item.kodi_id is not None]

# filter out items in the wrong section id when it's specified
if section_id is not None:
all_items = [item for item in all_items
if item.section_id == utils.cast(int, section_id)]

all_items = [widgets.generate_item(api) for api in all_items]
all_items = [widgets.prepare_listitem(item) for item in all_items]
all_items = [widgets.prepare_listitem(item, key) for item in all_items]
# fill that listing...
all_items = [widgets.create_listitem(item) for item in all_items]
xbmcplugin.addDirectoryItems(int(sys.argv[1]), all_items, len(all_items))
Expand Down Expand Up @@ -468,6 +480,29 @@ def watchlater():
show_listing(xml)


def watchlist(section_id=None):
"""
Listing for plex.tv Watchlist section (if signed in to plex.tv)
"""
_wait_for_auth()
if utils.window('plex_token') == '':
LOG.error('No watchlist - not signed in to plex.tv')
raise ListingException
if utils.window('plex_restricteduser') == 'true':
LOG.error('No watchlist - restricted user')
raise ListingException
app.init(entrypoint=True)
xml = DU().downloadUrl('https://metadata.provider.plex.tv/library/sections/watchlist/all',
authenticate=False,
headerOptions={'X-Plex-Token': utils.window('plex_token')})
try:
xml[0].attrib
except (TypeError, IndexError, AttributeError):
LOG.error('Could not download watch list list from plex.tv')
raise ListingException
show_listing(xml, None, section_id, False, "watchlist")


def browse_plex(key=None, plex_type=None, section_id=None, synched=True,
args=None, prompt=None, query=None):
"""
Expand Down
3 changes: 3 additions & 0 deletions resources/lib/itemtypes/movies.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ def add_update(self, xml, section_name=None, section_id=None,

self.kodidb.modify_streams(file_id, api.mediastreams(), api.runtime())
self.kodidb.modify_studios(kodi_id, v.KODI_TYPE_MOVIE, api.studios())
# Process tags: section, PMS labels, PMS collection tags
tags = [section_name]
tags.extend(api.labels())
self._process_collections(api, tags, kodi_id, section_id, children)
self.kodidb.modify_tags(kodi_id, v.KODI_TYPE_MOVIE, tags)
# Process playstate
Expand All @@ -168,6 +170,7 @@ def add_update(self, xml, section_name=None, section_id=None,
api.viewcount(),
api.lastplayed())
self.plexdb.add_movie(plex_id=plex_id,
plex_guid=api.plex_guid,
checksum=api.checksum(),
section_id=section_id,
kodi_id=kodi_id,
Expand Down
7 changes: 6 additions & 1 deletion resources/lib/itemtypes/tvshows.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,13 @@ def add_update(self, xml, section_name=None, section_id=None,
self.kodidb.modify_genres(kodi_id, v.KODI_TYPE_SHOW, api.genres())
# Process studios
self.kodidb.modify_studios(kodi_id, v.KODI_TYPE_SHOW, api.studios())
# Process tags: view, PMS collection tags
# Process tags: section, PMS labels, PMS collection tags
tags = [section_name]
tags.extend(api.labels())
tags.extend([i for _, i in api.collections()])
self.kodidb.modify_tags(kodi_id, v.KODI_TYPE_SHOW, tags)
self.plexdb.add_show(plex_id=plex_id,
plex_guid=api.plex_guid,
checksum=api.checksum(),
section_id=section_id,
kodi_id=kodi_id,
Expand Down Expand Up @@ -340,6 +342,7 @@ def add_update(self, xml, section_name=None, section_id=None,
kodi_id,
v.KODI_TYPE_SEASON)
self.plexdb.add_season(plex_id=plex_id,
plex_guid=api.plex_guid,
checksum=api.checksum(),
section_id=section_id,
show_id=show_id,
Expand Down Expand Up @@ -496,6 +499,7 @@ def add_update(self, xml, section_name=None, section_id=None,
api.viewcount(),
api.lastplayed())
self.plexdb.add_episode(plex_id=plex_id,
plex_guid=api.plex_guid,
checksum=api.checksum(),
section_id=section_id,
show_id=api.show_id(),
Expand Down Expand Up @@ -566,6 +570,7 @@ def add_update(self, xml, section_name=None, section_id=None,
api.viewcount(),
api.lastplayed())
self.plexdb.add_episode(plex_id=plex_id,
plex_guid=api.plex_guid,
checksum=api.checksum(),
section_id=section_id,
show_id=api.show_id(),
Expand Down

0 comments on commit f6c7bbc

Please sign in to comment.