From 85e0909105525046511d4312e26944f5833e4186 Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 1 Aug 2019 12:45:42 +0200 Subject: [PATCH 01/13] Fix potential playlist sync issues with dot in playlist name --- resources/lib/playlists/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/playlists/common.py b/resources/lib/playlists/common.py index ce173475..76eceb89 100644 --- a/resources/lib/playlists/common.py +++ b/resources/lib/playlists/common.py @@ -105,7 +105,7 @@ class Playlist(object): raise RuntimeError('Path not in unicode: %s' % path) f = path_ops.path.basename(path) try: - self.kodi_filename, self.kodi_extension = f.split('.', 1) + self.kodi_filename, self.kodi_extension = f.rsplit('.', 1) except ValueError: LOG.error('Trying to set invalid path: %s', path) raise PlaylistError('Invalid path: %s' % path) From a83cf931507c83825b590cc85c9f3fddfd62da25 Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 1 Aug 2019 14:21:45 +0200 Subject: [PATCH 02/13] Separate function to wipe all synched Plex playlists --- resources/lib/plex_db/common.py | 12 +++++++---- resources/lib/utils.py | 37 ++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/resources/lib/plex_db/common.py b/resources/lib/plex_db/common.py index 70361feb..c2764cad 100644 --- a/resources/lib/plex_db/common.py +++ b/resources/lib/plex_db/common.py @@ -311,12 +311,16 @@ def initialize(): plexdb.cursor.execute(cmd) -def wipe(): +def wipe(table=None): """ - Completely resets the Plex database + Completely resets the Plex database. + If a table [unicode] name is provided, only that table will be dropped """ with PlexDBBase() as plexdb: - plexdb.cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table'") - tables = [i[0] for i in plexdb.cursor.fetchall()] + if table: + tables = [table] + else: + plexdb.cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table'") + tables = [i[0] for i in plexdb.cursor.fetchall()] for table in tables: plexdb.cursor.execute('DROP table IF EXISTS %s' % table) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index be8aadcc..b1f8ca83 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -539,6 +539,29 @@ def create_kodi_db_indicees(): conn.close() +def wipe_synched_playlists(): + """ + Deletes all synched playlist files on the Kodi side; resets the Plex table + listing all synched Plex playlists + """ + from . import plex_db + try: + with plex_db.PlexDB() as plexdb: + plexdb.cursor.execute('SELECT kodi_path FROM playlists') + playlist_paths = [x[0] for x in plexdb.cursor] + except OperationalError: + # Plex DB completely empty yet + playlist_paths = [] + for path in playlist_paths: + try: + path_ops.remove(path) + LOG.info('Removed playlist %s', path) + except (OSError, IOError): + LOG.warn('Could not remove playlist %s', path) + # Now wipe our database + plex_db.wipe(table='playlists') + + def wipe_database(reboot=True): """ Deletes all Plex playlists as well as video nodes, then clears Kodi as well @@ -550,8 +573,8 @@ def wipe_database(reboot=True): from . import kodi_db, plex_db # Clean up the playlists and video nodes delete_files() - # First get the paths to all synced playlists - playlist_paths = [] + # Wipe all synched playlists + wipe_synched_playlists() try: with plex_db.PlexDB() as plexdb: if plexdb.songs_have_been_synced(): @@ -560,22 +583,12 @@ def wipe_database(reboot=True): else: LOG.info('No music has been synced in the past - not wiping') music = False - plexdb.cursor.execute('SELECT kodi_path FROM playlists') - for entry in plexdb.cursor: - playlist_paths.append(entry[0]) except OperationalError: # Plex DB completely empty yet. Wipe existing Kodi music only if we # expect to sync Plex music music = settings('enableMusic') == 'true' kodi_db.wipe_dbs(music) plex_db.wipe() - # Delete all synced playlists - for path in playlist_paths: - try: - path_ops.remove(path) - LOG.debug('Removed playlist %s', path) - except (OSError, IOError): - LOG.warn('Could not remove playlist %s', path) LOG.info("Resetting all cached artwork.") # Remove all cached artwork From 53f77a7a97ad541cfc7251a2c90fa68942c84270 Mon Sep 17 00:00:00 2001 From: croneter Date: Sun, 28 Jul 2019 15:35:38 +0200 Subject: [PATCH 03/13] Add unicode representation to Playlist() class --- resources/lib/playlists/common.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/lib/playlists/common.py b/resources/lib/playlists/common.py index ce173475..43006d8a 100644 --- a/resources/lib/playlists/common.py +++ b/resources/lib/playlists/common.py @@ -63,7 +63,7 @@ class Playlist(object): self.kodi_type = None self.kodi_hash = None - def __repr__(self): + def __unicode__(self): return ("{{" "'plex_id': {self.plex_id}, " "'plex_name': '{self.plex_name}', " @@ -74,6 +74,9 @@ class Playlist(object): "'kodi_hash': '{self.kodi_hash}'" "}}").format(self=self) + def __repr__(self): + return self.__unicode__().encode('utf-8') + def __str__(self): return self.__repr__() From dca1bb683524a1ea86ed3fcab588edc785d20ae9 Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 1 Aug 2019 12:46:13 +0200 Subject: [PATCH 04/13] Remove obsolete check --- resources/lib/playlists/common.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/lib/playlists/common.py b/resources/lib/playlists/common.py index ce173475..a1e24e56 100644 --- a/resources/lib/playlists/common.py +++ b/resources/lib/playlists/common.py @@ -101,8 +101,6 @@ class Playlist(object): @kodi_path.setter def kodi_path(self, path): - if not isinstance(path, unicode): - raise RuntimeError('Path not in unicode: %s' % path) f = path_ops.path.basename(path) try: self.kodi_filename, self.kodi_extension = f.split('.', 1) From 26fa1ff909e2473306e07c252ec1b0a73b8e59fb Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 1 Aug 2019 13:56:50 +0200 Subject: [PATCH 05/13] Use file size and last modification time to compare Kodi playlist files instead of slow MD5 hash of file --- resources/lib/playlists/__init__.py | 11 ++++++----- resources/lib/playlists/common.py | 18 ++++++++++++++++++ resources/lib/playlists/kodi_pl.py | 4 ++-- resources/lib/utils.py | 18 ------------------ 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/resources/lib/playlists/__init__.py b/resources/lib/playlists/__init__.py index 54c90550..b3658ba0 100644 --- a/resources/lib/playlists/__init__.py +++ b/resources/lib/playlists/__init__.py @@ -14,7 +14,8 @@ from __future__ import absolute_import, division, unicode_literals from logging import getLogger -from .common import Playlist, PlaylistError, PlaylistObserver +from .common import Playlist, PlaylistError, PlaylistObserver, \ + kodi_playlist_hash from . import pms, db, kodi_pl, plex_pl from ..watchdog import events @@ -221,7 +222,7 @@ def _full_sync(): pass if not sync_kodi_playlist(path): continue - kodi_hash = utils.generate_file_md5(path) + kodi_hash = kodi_playlist_hash(path) playlist = db.get_playlist(path=path) if playlist and playlist.kodi_hash == kodi_hash: continue @@ -387,7 +388,7 @@ class PlaylistEventhandler(events.FileSystemEventHandler): def on_created(self, event): LOG.debug('on_created: %s', event.src_path) old_playlist = db.get_playlist(path=event.src_path) - kodi_hash = utils.generate_file_md5(event.src_path) + kodi_hash = kodi_playlist_hash(event.src_path) if old_playlist and old_playlist.kodi_hash == kodi_hash: LOG.debug('Playlist already in DB - skipping') return @@ -406,7 +407,7 @@ class PlaylistEventhandler(events.FileSystemEventHandler): def on_modified(self, event): LOG.debug('on_modified: %s', event.src_path) old_playlist = db.get_playlist(path=event.src_path) - kodi_hash = utils.generate_file_md5(event.src_path) + kodi_hash = kodi_playlist_hash(event.src_path) if old_playlist and old_playlist.kodi_hash == kodi_hash: LOG.debug('Nothing modified, playlist already in DB - skipping') return @@ -425,7 +426,7 @@ class PlaylistEventhandler(events.FileSystemEventHandler): def on_moved(self, event): LOG.debug('on_moved: %s to %s', event.src_path, event.dest_path) - kodi_hash = utils.generate_file_md5(event.dest_path) + kodi_hash = kodi_playlist_hash(event.dest_path) # First check whether we don't already have destination playlist in # our DB. Just in case.... old_playlist = db.get_playlist(path=event.dest_path) diff --git a/resources/lib/playlists/common.py b/resources/lib/playlists/common.py index ce173475..5b348cd4 100644 --- a/resources/lib/playlists/common.py +++ b/resources/lib/playlists/common.py @@ -4,6 +4,8 @@ from __future__ import absolute_import, division, unicode_literals from logging import getLogger import Queue import time +import os +import hashlib from ..watchdog import events from ..watchdog.observers import Observer @@ -121,6 +123,22 @@ class Playlist(object): self._kodi_path = path +def kodi_playlist_hash(path): + """ + Returns a md5 hash [unicode] using os.stat() st_size and st_mtime for the + playlist located at path [unicode] + (size of file in bytes and time of most recent content modification) + + There are probably way more efficient ways out there to do this + """ + stat = os.stat(path_ops.encode_path(path)) + # stat.st_size is of type long; stat.st_mtime is of type float - hash both + m = hashlib.md5() + m.update(repr(stat.st_size)) + m.update(repr(stat.st_mtime)) + return m.hexdigest().decode('utf-8') + + class PlaylistQueue(OrderedSetQueue): """ OrderedSetQueue that drops all directory events immediately diff --git a/resources/lib/playlists/kodi_pl.py b/resources/lib/playlists/kodi_pl.py index 147f935b..4b040c25 100644 --- a/resources/lib/playlists/kodi_pl.py +++ b/resources/lib/playlists/kodi_pl.py @@ -7,7 +7,7 @@ from __future__ import absolute_import, division, unicode_literals from logging import getLogger import re -from .common import Playlist, PlaylistError +from .common import Playlist, PlaylistError, kodi_playlist_hash from . import db, pms from ..plex_api import API @@ -71,7 +71,7 @@ def create(plex_id): except Exception: IGNORE_KODI_PLAYLIST_CHANGE.remove(playlist.kodi_path) raise - playlist.kodi_hash = utils.generate_file_md5(path) + playlist.kodi_hash = kodi_playlist_hash(path) db.update_playlist(playlist) LOG.debug('Created Kodi playlist based on Plex playlist: %s', playlist) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index be8aadcc..c84d5e25 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -17,7 +17,6 @@ import xml.etree.ElementTree as etree from . import defused_etree from xml.etree.ElementTree import ParseError from functools import wraps -import hashlib import re import gc try: @@ -931,23 +930,6 @@ class XmlKodiSetting(object): return element -def generate_file_md5(path): - """ - Generates the md5 hash value for the file located at path [unicode]. - The hash does not include the path and filename and is thus identical for - a file that was moved/changed name. - Returns a unique unicode containing only hexadecimal digits - """ - m = hashlib.md5() - with open(path_ops.encode_path(path), 'rb') as f: - while True: - piece = f.read(32768) - if not piece: - break - m.update(piece) - return m.hexdigest().decode('utf-8') - - def process_method_on_list(method_to_run, items): """ helper method that processes a method on each item with pooling if the From 7d8802467f7598e6b42faea517bca28d2524de8f Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 1 Aug 2019 14:22:44 +0200 Subject: [PATCH 06/13] Ensure playlists are freshly synched on PKC version bump --- resources/lib/migration.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/resources/lib/migration.py b/resources/lib/migration.py index d88ca2d4..14600572 100644 --- a/resources/lib/migration.py +++ b/resources/lib/migration.py @@ -57,4 +57,9 @@ def check_migration(): sections.clear_window_vars() sections.delete_videonode_files() + if not utils.compare_version(last_migration, '2.9.3'): + LOG.info('Migrating to version 2.9.2') + # Re-sync all playlists to Kodi + utils.wipe_synched_playlists() + utils.settings('last_migrated_PKC_version', value=v.ADDON_VERSION) From bcc97df2094832ee3940d45470ce9ca39290bba3 Mon Sep 17 00:00:00 2001 From: croneter Date: Fri, 2 Aug 2019 10:17:02 +0200 Subject: [PATCH 07/13] Less logging when comparing PKC versions --- resources/lib/utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index be8aadcc..e19c2beb 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -639,7 +639,6 @@ def compare_version(current, minimum): Input strings: e.g. "1.2.3"; always with Major, Minor and Patch! """ - LOG.info("current DB: %s minimum DB: %s", current, minimum) try: curr_major, curr_minor, curr_patch = current.split(".") except ValueError: From 33ed1bed83d54a516d929adb79bac00daaa4bdbb Mon Sep 17 00:00:00 2001 From: croneter Date: Fri, 2 Aug 2019 10:25:53 +0200 Subject: [PATCH 08/13] Sync playlists immediately after synching new/changed items and show pop-up info --- resources/lib/library_sync/full_sync.py | 27 +++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/resources/lib/library_sync/full_sync.py b/resources/lib/library_sync/full_sync.py index 09701700..d7e50f68 100644 --- a/resources/lib/library_sync/full_sync.py +++ b/resources/lib/library_sync/full_sync.py @@ -334,15 +334,27 @@ class FullSync(common.fullsync_mixin): plexdb.update_section_last_sync(section.section_id, self.current_sync) common.update_kodi_library(video=True, music=True) + + # Sync Plex playlists to Kodi and vice-versa + if common.PLAYLIST_SYNC_ENABLED: + if self.show_dialog: + if self.dialog: + self.dialog.close() + self.dialog = xbmcgui.DialogProgressBG() + # "Synching playlists" + self.dialog.create(utils.lang(39715)) + if not playlists.full_sync(): + return False + + # SYNC PLAYSTATE of ALL items (otherwise we won't pick up on items that + # were set to unwatched). Also mark all items on the PMS to be able + # to delete the ones still in Kodi + LOG.info('Start synching playstate and userdata for every item') # In order to not delete all your songs again if app.SYNC.enable_music: kinds.extend([ (v.PLEX_TYPE_SONG, v.PLEX_TYPE_ARTIST, itemtypes.Song, True), ]) - # SYNC PLAYSTATE of ALL items (otherwise we won't pick up on items that - # were set to unwatched). Also mark all items on the PMS to be able - # to delete the ones still in Kodi - LOG.info('Start synching playstate and userdata for every item') # Make sure we're not showing an item's title in the sync dialog self.title = '' self.threader.shutdown() @@ -428,13 +440,6 @@ class FullSync(common.fullsync_mixin): if self.isCanceled() or not self.full_library_sync(): self.successful = False return - if common.PLAYLIST_SYNC_ENABLED: - if self.dialog: - self.dialog.close() - self.dialog = xbmcgui.DialogProgressBG() - self.dialog.create(utils.lang(39715)) - if not playlists.full_sync(): - self.successful = False finally: common.update_kodi_library(video=True, music=True) if self.dialog: From bae923d34a8f85fabac2a989c26190f5900c8aa1 Mon Sep 17 00:00:00 2001 From: croneter Date: Fri, 2 Aug 2019 10:46:04 +0200 Subject: [PATCH 09/13] Fix Plex Companion casting from iOS and Android --- resources/lib/plex_companion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/plex_companion.py b/resources/lib/plex_companion.py index 516c78e9..dbdea11e 100644 --- a/resources/lib/plex_companion.py +++ b/resources/lib/plex_companion.py @@ -167,7 +167,7 @@ class PlexCompanion(backgroundthread.KillableThread): repeat=query.get('repeat'), offset=data.get('offset'), transient_token=data.get('token'), - key=key) + start_plex_id=key) @staticmethod def _process_streams(data): From 8560bf11a85eecc9c7536ba7ef997ea647c5a387 Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 1 Aug 2019 14:58:04 +0200 Subject: [PATCH 10/13] Beta version bump 2.9.2 --- README.md | 2 +- addon.xml | 15 +++++++++++++-- changelog.txt | 10 ++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a8a7cb27..d4b1bf3b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![stable version](https://img.shields.io/badge/stable_version-2.9.1-blue.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/stable/repository.plexkodiconnect/repository.plexkodiconnect-1.0.2.zip) -[![beta version](https://img.shields.io/badge/beta_version-2.9.1-red.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/beta/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.2.zip) +[![beta version](https://img.shields.io/badge/beta_version-2.9.2-red.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/beta/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.2.zip) [![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation) [![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq) diff --git a/addon.xml b/addon.xml index eb770717..45e8ffda 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -83,7 +83,18 @@ Natūralioji „Plex“ integracija į „Kodi“ Prijunkite „Kodi“ prie „Plex Medija Serverio“. Šiame papildinyje daroma prielaida, kad valdote visus savo vaizdo įrašus naudodami „Plex“ (ir nė vieno su „Kodi“). Galite prarasti jau saugomus „Kodi“ vaizdo įrašų ir muzikos duomenų bazių duomenis (kadangi šis papildinys juos tiesiogiai pakeičia). Naudokite savo pačių rizika! Naudokite savo pačių rizika - version 2.9.1: + version 2.9.2 (beta only): +- Fix Plex Companion casting from iOS and Android +- Faster sync of playlists +- Sync playlists immediately after synching new/changed items and show an info dialog +- Fix potential playlist sync issues if there is a dot in the playlist name +- Remove obsolete check if path is indeed in unicode +- Add unicode representation to Playlist() class +- Separate function to wipe all synched Plex playlists +- Less logging when comparing PKC versions + + +version 2.9.1: - Fix On Deck and Recently Added Episodes for shows not appending showname and season and episode number version 2.9.0: diff --git a/changelog.txt b/changelog.txt index e1583fd1..a4c596a8 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,13 @@ +version 2.9.2 (beta only): +- Fix Plex Companion casting from iOS and Android +- Faster sync of playlists +- Sync playlists immediately after synching new/changed items and show an info dialog +- Fix potential playlist sync issues if there is a dot in the playlist name +- Remove obsolete check if path is indeed in unicode +- Add unicode representation to Playlist() class +- Separate function to wipe all synched Plex playlists +- Less logging when comparing PKC versions + version 2.9.1: - Fix On Deck and Recently Added Episodes for shows not appending showname and season and episode number From 34e84cd037c731a952ab72d88d627faedd7918a5 Mon Sep 17 00:00:00 2001 From: croneter Date: Fri, 2 Aug 2019 11:26:22 +0200 Subject: [PATCH 11/13] Correctly detect whether we already synched a Kodi playlist --- resources/lib/playlists/plex_pl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/playlists/plex_pl.py b/resources/lib/playlists/plex_pl.py index 03c863a4..2b10af60 100644 --- a/resources/lib/playlists/plex_pl.py +++ b/resources/lib/playlists/plex_pl.py @@ -30,8 +30,8 @@ def create(playlist): if not plex_ids: LOG.warning('No Plex ids found for playlist %s', playlist) raise PlaylistError - IGNORE_PLEX_PLAYLIST_CHANGE.append(playlist.plex_id) pms.add_items(playlist, plex_ids) + IGNORE_PLEX_PLAYLIST_CHANGE.append(playlist.plex_id) db.update_playlist(playlist) LOG.debug('Done creating Plex playlist %s', playlist) From d88b62ccd9d755fb5ec84caf1da3121ca9fc5c1b Mon Sep 17 00:00:00 2001 From: croneter Date: Fri, 2 Aug 2019 11:34:07 +0200 Subject: [PATCH 12/13] Update changelog for version 2.9.2 --- addon.xml | 2 +- changelog.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index 45e8ffda..0f48df46 100644 --- a/addon.xml +++ b/addon.xml @@ -88,12 +88,12 @@ - Faster sync of playlists - Sync playlists immediately after synching new/changed items and show an info dialog - Fix potential playlist sync issues if there is a dot in the playlist name +- Correctly detect whether we already synched a Kodi playlist - Remove obsolete check if path is indeed in unicode - Add unicode representation to Playlist() class - Separate function to wipe all synched Plex playlists - Less logging when comparing PKC versions - version 2.9.1: - Fix On Deck and Recently Added Episodes for shows not appending showname and season and episode number diff --git a/changelog.txt b/changelog.txt index a4c596a8..e2bd9e72 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,6 +3,7 @@ version 2.9.2 (beta only): - Faster sync of playlists - Sync playlists immediately after synching new/changed items and show an info dialog - Fix potential playlist sync issues if there is a dot in the playlist name +- Correctly detect whether we already synched a Kodi playlist - Remove obsolete check if path is indeed in unicode - Add unicode representation to Playlist() class - Separate function to wipe all synched Plex playlists From 09989b814b2aa60784c60501f3f52335d3f2e528 Mon Sep 17 00:00:00 2001 From: croneter Date: Sat, 3 Aug 2019 10:43:14 +0200 Subject: [PATCH 13/13] Stable and beta version bump 2.9.3 --- README.md | 4 ++-- addon.xml | 7 +++++-- changelog.txt | 3 +++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d4b1bf3b..dc7eeeb7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![stable version](https://img.shields.io/badge/stable_version-2.9.1-blue.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/stable/repository.plexkodiconnect/repository.plexkodiconnect-1.0.2.zip) -[![beta version](https://img.shields.io/badge/beta_version-2.9.2-red.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/beta/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.2.zip) +[![stable version](https://img.shields.io/badge/stable_version-2.9.3-blue.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/stable/repository.plexkodiconnect/repository.plexkodiconnect-1.0.2.zip) +[![beta version](https://img.shields.io/badge/beta_version-2.9.3-red.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/beta/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.2.zip) [![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation) [![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq) diff --git a/addon.xml b/addon.xml index 0f48df46..9757c468 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -83,7 +83,10 @@ Natūralioji „Plex“ integracija į „Kodi“ Prijunkite „Kodi“ prie „Plex Medija Serverio“. Šiame papildinyje daroma prielaida, kad valdote visus savo vaizdo įrašus naudodami „Plex“ (ir nė vieno su „Kodi“). Galite prarasti jau saugomus „Kodi“ vaizdo įrašų ir muzikos duomenų bazių duomenis (kadangi šis papildinys juos tiesiogiai pakeičia). Naudokite savo pačių rizika! Naudokite savo pačių rizika - version 2.9.2 (beta only): + version 2.9.3: +- version 2.9.2 for everyone + +version 2.9.2 (beta only): - Fix Plex Companion casting from iOS and Android - Faster sync of playlists - Sync playlists immediately after synching new/changed items and show an info dialog diff --git a/changelog.txt b/changelog.txt index e2bd9e72..b57875d9 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +version 2.9.3: +- version 2.9.2 for everyone + version 2.9.2 (beta only): - Fix Plex Companion casting from iOS and Android - Faster sync of playlists