aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/game.controller.default/addon.xml4
-rw-r--r--addons/metadata.album.universal/addon.xml4
-rw-r--r--addons/metadata.album.universal/albumuniversal.xml36
-rw-r--r--addons/metadata.album.universal/changelog.txt10
-rw-r--r--addons/metadata.album.universal/resources/language/English/strings.po16
-rw-r--r--addons/metadata.album.universal/resources/settings.xml6
-rw-r--r--addons/metadata.artists.universal/addon.xml6
-rw-r--r--addons/metadata.artists.universal/artistuniversal.xml18
-rw-r--r--addons/metadata.artists.universal/changelog.txt9
-rw-r--r--addons/metadata.artists.universal/resources/language/English/strings.po20
-rw-r--r--addons/metadata.artists.universal/resources/settings.xml7
-rw-r--r--addons/metadata.common.allmusic.com/addon.xml4
-rw-r--r--addons/metadata.common.allmusic.com/allmusic.xml241
-rw-r--r--addons/metadata.common.fanart.tv/addon.xml2
-rw-r--r--addons/metadata.common.fanart.tv/fanarttv.xml601
-rw-r--r--addons/metadata.common.imdb.com/addon.xml2
-rw-r--r--addons/metadata.common.imdb.com/changelog.txt56
-rw-r--r--addons/metadata.common.imdb.com/imdb.xml187
-rw-r--r--addons/metadata.common.musicbrainz.org/addon.xml4
-rw-r--r--addons/metadata.common.musicbrainz.org/musicbrainz.xml13
-rw-r--r--addons/metadata.common.theaudiodb.com/addon.xml4
-rw-r--r--addons/metadata.common.theaudiodb.com/tadb.xml169
-rw-r--r--addons/metadata.common.themoviedb.org/addon.xml2
-rw-r--r--addons/metadata.common.themoviedb.org/tmdb.xml403
-rw-r--r--addons/metadata.tvdb.com/addon.xml2
-rw-r--r--addons/metadata.tvdb.com/changelog.txt6
-rw-r--r--addons/metadata.tvdb.com/tvdb.xml19
-rw-r--r--tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.h101
-rw-r--r--tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.m598
-rw-r--r--xbmc/cores/ExternalPlayer/ExternalPlayer.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp21
-rw-r--r--xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h1
-rw-r--r--xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp20
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h4
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp14
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFFmpeg.h7
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h2
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRBase.h2
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayer.cpp18
-rw-r--r--xbmc/cores/playercorefactory/PlayerCoreFactory.cpp4
-rw-r--r--xbmc/cores/playercorefactory/PlayerSelectionRule.cpp4
-rw-r--r--xbmc/input/InputManager.cpp2
-rw-r--r--xbmc/messaging/ThreadMessage.h1
-rw-r--r--xbmc/music/windows/GUIWindowMusicBase.cpp7
-rw-r--r--xbmc/network/EventClient.cpp10
-rw-r--r--xbmc/platform/linux/input/LibInputTouch.cpp8
-rw-r--r--xbmc/pvr/windows/GUIEPGGridContainer.cpp6
-rw-r--r--xbmc/pvr/windows/GUIEPGGridContainer.h1
-rw-r--r--xbmc/pvr/windows/GUIEPGGridContainerModel.cpp24
-rw-r--r--xbmc/pvr/windows/GUIEPGGridContainerModel.h6
-rw-r--r--xbmc/windowing/gbm/DRMUtils.cpp2
-rw-r--r--xbmc/windowing/gbm/GBMUtils.cpp14
52 files changed, 1744 insertions, 986 deletions
diff --git a/addons/game.controller.default/addon.xml b/addons/game.controller.default/addon.xml
index 3dcc9ba40a..86c67770d3 100644
--- a/addons/game.controller.default/addon.xml
+++ b/addons/game.controller.default/addon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="game.controller.default"
name="Default Controller"
- version="1.0.5"
+ version="1.0.6"
provider-name="Team Kodi">
<requires>
</requires>
@@ -9,7 +9,7 @@
<extension point="xbmc.addon.metadata">
<summary lang="en_GB">Default Controller</summary>
<description lang="en_GB">The default media center controller is based on the Xbox 360 controller.</description>
- <disclaimer>Image credit: Wikipedia (wikipedia.org)</disclaimer>
+ <disclaimer lang="en_GB">Image credit: Wikipedia (wikipedia.org)</disclaimer>
<platform>all</platform>
<assets>
<icon>resources/icon.png</icon>
diff --git a/addons/metadata.album.universal/addon.xml b/addons/metadata.album.universal/addon.xml
index d4b6afcb13..d84aae24ec 100644
--- a/addons/metadata.album.universal/addon.xml
+++ b/addons/metadata.album.universal/addon.xml
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="metadata.album.universal"
name="Universal Album Scraper"
- version="2.7.3"
+ version="3.1.1"
provider-name="Olympia, Team Kodi">
<requires>
<import addon="xbmc.metadata" version="2.1.0"/>
diff --git a/addons/metadata.album.universal/albumuniversal.xml b/addons/metadata.album.universal/albumuniversal.xml
index be1b5d9f92..c913d7e3d8 100644
--- a/addons/metadata.album.universal/albumuniversal.xml
+++ b/addons/metadata.album.universal/albumuniversal.xml
@@ -26,29 +26,11 @@
</CreateAlbumSearchUrl>
<GetAlbumSearchResults dest="8">
<RegExp input="$$5" output="&lt;results sorted=&quot;yes&quot;&gt;\1&lt;/results&gt;" dest="8">
- <RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\5-\4-T#\6&lt;/year&gt;&lt;artist&gt;\3&lt;/artist&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url cache=&quot;mb-\1-album.xml&quot;&gt;$INFO[mbsite]/ws/2/release/\1?inc=recordings+release-groups+artists+labels+ratings&lt;/url&gt;&lt;/entity&gt;" dest="5">
- <expression repeat="yes">id=&quot;([^&quot;]*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;/title&gt;&lt;status&gt;Official&lt;/status&gt;(?:&lt;packaging&gt;[^&lt;]*&lt;/packaging&gt;)?&lt;text-representation&gt;(?:&lt;language&gt;[^&lt;]*&lt;/language&gt;)*(?:&lt;script&gt;[^&lt;]*&lt;/script&gt;)*&lt;/text-representation&gt;&lt;artist-credit&gt;&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;([^&lt;]*)&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;(?:&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;[^&lt;]*&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;)*&lt;/artist-credit&gt;&lt;release-group\stype=&quot;Album&quot;\sid=&quot;[^&quot;]*&quot;&gt;(?:&lt;primary-type&gt;[^&lt;]*&lt;/primary-type&gt;)*(?:&lt;secondary-type-list&gt;(?:&lt;secondary-type&gt;[^&lt;]*&lt;/secondary-type&gt;)+&lt;/secondary-type-list&gt;)*&lt;/release-group&gt;(?:&lt;date&gt;(\d{4})[^&lt;]*&lt;/date&gt;)*(?:&lt;country&gt;)*([^&lt;]*)?.*?&lt;track-list\scount=&quot;(\d+)</expression>
- </RegExp>
- <RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\5-\4-T#\6&lt;/year&gt;&lt;artist&gt;\3&lt;/artist&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url cache=&quot;mb-\1-album.xml&quot;&gt;$INFO[mbsite]/ws/2/release/\1?inc=recordings+release-groups+artists+labels+ratings&lt;/url&gt;&lt;/entity&gt;" dest="5+">
- <expression repeat="yes">id=&quot;([^&quot;]*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;/title&gt;&lt;status&gt;Official&lt;/status&gt;(?:&lt;packaging&gt;[^&lt;]*&lt;/packaging&gt;)?&lt;text-representation&gt;(?:&lt;language&gt;[^&lt;]*&lt;/language&gt;)*(?:&lt;script&gt;[^&lt;]*&lt;/script&gt;)*&lt;/text-representation&gt;&lt;artist-credit&gt;&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;([^&lt;]*)&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;(?:&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;[^&lt;]*&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;)*&lt;/artist-credit&gt;&lt;release-group(?:\stype=&quot;[^&quot;]*&quot;)*\sid=&quot;[^&quot;]*&quot;&gt;(?:&lt;primary-type&gt;[^&lt;]*&lt;/primary-type&gt;)*(?:&lt;secondary-type-list&gt;(?:&lt;secondary-type&gt;[^&lt;]*&lt;/secondary-type&gt;)+&lt;/secondary-type-list&gt;)*&lt;/release-group&gt;(?:&lt;date&gt;(\d{4})[^&lt;]*&lt;/date&gt;)*(?:&lt;country&gt;)*([^&lt;]*)?.*?&lt;track-list\scount=&quot;(\d+)</expression>
- </RegExp>
- <RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\6-\5-T#\7&lt;/year&gt;&lt;artist&gt;\4&lt;/artist&gt;&lt;title&gt;\3&lt;/title&gt;&lt;relevance scale=&quot;100&quot;&gt;\2&lt;/relevance&gt;&lt;url cache=&quot;mb-\1-album.xml&quot;&gt;$INFO[mbsite]/ws/2/release/\1?inc=recordings+release-groups+artists+labels+ratings&lt;/url&gt;&lt;/entity&gt;" dest="5+">
- <expression repeat="yes">id=&quot;([^&quot;]*)&quot; ext:score=&quot;(\d*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;/title&gt;&lt;status&gt;Official&lt;/status&gt;(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;packaging&gt;[^&lt;]*&lt;/packaging&gt;)?&lt;text-representation&gt;(?:&lt;language&gt;[^&lt;]*&lt;/language&gt;)*(?:&lt;script&gt;[^&lt;]*&lt;/script&gt;)*&lt;/text-representation&gt;&lt;artist-credit&gt;&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;([^&lt;]*)&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;(?:&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;[^&lt;]*&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;)*&lt;/artist-credit&gt;&lt;release-group\sid=&quot;[^&quot;]*&quot;\stype=&quot;Album&quot;&gt;(?:&lt;primary-type&gt;[^&lt;]*&lt;/primary-type&gt;)*(?:&lt;secondary-type-list&gt;(?:&lt;secondary-type&gt;[^&lt;]*&lt;/secondary-type&gt;)+&lt;/secondary-type-list&gt;)*&lt;/release-group&gt;(?:&lt;date&gt;(\d{4})[^&lt;]*&lt;/date&gt;)*(?:&lt;country&gt;)*([^&lt;]*)?.*?&lt;track-list\scount=&quot;(\d+)</expression>
- </RegExp>
- <RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\6-\5-T#\7&lt;/year&gt;&lt;artist&gt;\4&lt;/artist&gt;&lt;title&gt;\3&lt;/title&gt;&lt;relevance scale=&quot;100&quot;&gt;\2&lt;/relevance&gt;&lt;url cache=&quot;mb-\1-album.xml&quot;&gt;$INFO[mbsite]/ws/2/release/\1?inc=recordings+release-groups+artists+labels+ratings&lt;/url&gt;&lt;/entity&gt;" dest="5+">
- <expression repeat="yes">id=&quot;([^&quot;]*)&quot; ext:score=&quot;(\d*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;/title&gt;&lt;status&gt;Official&lt;/status&gt;(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;packaging&gt;[^&lt;]*&lt;/packaging&gt;)?&lt;text-representation&gt;(?:&lt;language&gt;[^&lt;]*&lt;/language&gt;)*(?:&lt;script&gt;[^&lt;]*&lt;)*/script&gt;&lt;/text-representation&gt;&lt;artist-credit&gt;&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;([^&lt;]*)&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;(?:&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;[^&lt;]*&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;)*&lt;/artist-credit&gt;&lt;release-group\sid=&quot;[^&quot;]*&quot;(?:\stype=&quot;[^&quot;]*&quot;)*&gt;(?:&lt;primary-type&gt;[^&lt;]*&lt;/primary-type&gt;)*(?:&lt;secondary-type-list&gt;(?:&lt;secondary-type&gt;[^&lt;]*&lt;/secondary-type&gt;)+&lt;/secondary-type-list&gt;)*&lt;/release-group&gt;(?:&lt;date&gt;(\d{4})[^&lt;]*&lt;/date&gt;)*(?:&lt;country&gt;)*([^&lt;]*)?.*?&lt;track-list\scount=&quot;(\d+)</expression>
- </RegExp>
- <RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\5-\4-T#\6&lt;/year&gt;&lt;artist&gt;\3&lt;/artist&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url cache=&quot;mb-\1-album.xml&quot;&gt;$INFO[mbsite]/ws/2/release/\1?inc=recordings+release-groups+artists+labels+ratings&lt;/url&gt;&lt;/entity&gt;" dest="5+">
- <expression repeat="yes">id=&quot;([^&quot;]*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;/title&gt;&lt;status&gt;(?!Official)[^&lt;]*&lt;/status&gt;(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;packaging&gt;[^&lt;]*&lt;/packaging&gt;)?&lt;text-representation&gt;(?:&lt;language&gt;[^&lt;]*&lt;/language&gt;)*(?:&lt;script&gt;[^&lt;]*&lt;/script&gt;)*&lt;/text-representation&gt;&lt;artist-credit&gt;&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;([^&lt;]*)&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;(?:&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;[^&lt;]*&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;)*&lt;/artist-credit&gt;&lt;release-group\stype=&quot;Album&quot;\sid=&quot;[^&quot;]*&quot;&gt;(?:&lt;primary-type&gt;[^&lt;]*&lt;/primary-type&gt;)*(?:&lt;secondary-type-list&gt;(?:&lt;secondary-type&gt;[^&lt;]*&lt;/secondary-type&gt;)+&lt;/secondary-type-list&gt;)*&lt;/release-group&gt;(?:&lt;date&gt;(\d{4})[^&lt;]*&lt;/date&gt;)*(?:&lt;country&gt;)*([^&lt;]*)?.*?&lt;track-list\scount=&quot;(\d+)</expression>
- </RegExp>
- <RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\5-\4-T#\6&lt;/year&gt;&lt;artist&gt;\3&lt;/artist&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url cache=&quot;mb-\1-album.xml&quot;&gt;$INFO[mbsite]/ws/2/release/\1?inc=recordings+release-groups+artists+labels+ratings&lt;/url&gt;&lt;/entity&gt;" dest="5+">
- <expression repeat="yes">id=&quot;([^&quot;]*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;/title&gt;&lt;status&gt;(?!Official)[^&lt;]*&lt;/status&gt;(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;packaging&gt;[^&lt;]*&lt;/packaging&gt;)?&lt;text-representation&gt;(?:&lt;language&gt;[^&lt;]*&lt;/language&gt;)*(?:&lt;script&gt;[^&lt;]*&lt;/script&gt;)*&lt;/text-representation&gt;&lt;artist-credit&gt;&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;([^&lt;]*)&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;(?:&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;[^&lt;]*&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;)*&lt;/artist-credit&gt;&lt;release-group(?:\stype=&quot;[^&quot;]*&quot;)*\sid=&quot;[^&quot;]*&quot;&gt;(?:&lt;primary-type&gt;[^&lt;]*&lt;/primary-type&gt;)*(?:&lt;secondary-type-list&gt;(?:&lt;secondary-type&gt;[^&lt;]*&lt;/secondary-type&gt;)+&lt;/secondary-type-list&gt;)*&lt;/release-group&gt;(?:&lt;date&gt;(\d{4})[^&lt;]*&lt;/date&gt;)*(?:&lt;country&gt;)*([^&lt;]*)?.*?&lt;track-list\scount=&quot;(\d+)</expression>
- </RegExp>
- <RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\6-\5-T#\7&lt;/year&gt;&lt;artist&gt;\4&lt;/artist&gt;&lt;title&gt;\3&lt;/title&gt;&lt;relevance scale=&quot;100&quot;&gt;\2&lt;/relevance&gt;&lt;url cache=&quot;mb-\1-album.xml&quot;&gt;$INFO[mbsite]/ws/2/release/\1?inc=recordings+release-groups+artists+labels+ratings&lt;/url&gt;&lt;/entity&gt;" dest="5+">
- <expression repeat="yes">id=&quot;([^&quot;]*)&quot; ext:score=&quot;(\d*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;/title&gt;&lt;status&gt;(?!Official)[^&lt;]*&lt;/status&gt;(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;packaging&gt;[^&lt;]*&lt;/packaging&gt;)?&lt;text-representation&gt;(?:&lt;language&gt;[^&lt;]*&lt;/language&gt;)*(?:&lt;script&gt;[^&lt;]*&lt;/script&gt;)*&lt;/text-representation&gt;&lt;artist-credit&gt;&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;([^&lt;]*)&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;(?:&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;[^&lt;]*&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;)*&lt;/artist-credit&gt;&lt;release-group\sid=&quot;[^&quot;]*&quot;\stype=&quot;Album&quot;&gt;(?:&lt;primary-type&gt;[^&lt;]*&lt;/primary-type&gt;)*(?:&lt;secondary-type-list&gt;(?:&lt;secondary-type&gt;[^&lt;]*&lt;/secondary-type&gt;)+&lt;/secondary-type-list&gt;)*&lt;/release-group&gt;(?:&lt;date&gt;(\d{4})[^&lt;]*&lt;/date&gt;)*(?:&lt;country&gt;)*([^&lt;]*)?.*?&lt;track-list\scount=&quot;(\d+)</expression>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\6-\5-T#\7&lt;/year&gt;&lt;artist&gt;\4&lt;/artist&gt;&lt;title&gt;\3&lt;/title&gt;&lt;relevance scale=&quot;100&quot;&gt;\2&lt;/relevance&gt;&lt;url cache=&quot;mb-\1-album.xml&quot;&gt;$INFO[mbsite]/ws/2/release/\1?inc=recordings+release-groups+artists+labels+ratings&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">release\sid=&quot;([^&quot;]*)&quot;[^:]*:score=&quot;(\d*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;/title&gt;&lt;status&gt;Official&lt;/status&gt;(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;packaging&gt;[^&lt;]*&lt;/packaging&gt;)*&lt;text-representation&gt;(?:&lt;language&gt;[^&lt;]*&lt;/language&gt;)*(?:&lt;script&gt;[^&lt;]*&lt;/script&gt;)*&lt;/text-representation&gt;&lt;artist-credit&gt;&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;([^&lt;]*)&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;(?:&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;[^&lt;]*&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;)*&lt;/artist-credit&gt;&lt;release-group\sid=&quot;[^&quot;]*&quot;\stype=&quot;Album&quot;\stype-id=&quot;[^&quot;]*&quot;&gt;&lt;title&gt;[^&lt;]*&lt;/title&gt;(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;primary-type\sid=&quot;[^&quot;]*&quot;&gt;[^&lt;]*&lt;/primary-type&gt;)*(?:&lt;secondary-type-list&gt;(?:&lt;secondary-type\sid=&quot;[^&quot;]*&quot;&gt;[^&lt;]*&lt;/secondary-type&gt;)+&lt;/secondary-type-list&gt;)*&lt;/release-group&gt;(?:&lt;date&gt;(\d{4})[^&lt;]*&lt;/date&gt;)*(?:&lt;country&gt;)*([^&lt;]*)?.*?&lt;track-list\scount=&quot;(\d+).*?&lt;/release&gt;</expression>
</RegExp>
<RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\6-\5-T#\7&lt;/year&gt;&lt;artist&gt;\4&lt;/artist&gt;&lt;title&gt;\3&lt;/title&gt;&lt;relevance scale=&quot;100&quot;&gt;\2&lt;/relevance&gt;&lt;url cache=&quot;mb-\1-album.xml&quot;&gt;$INFO[mbsite]/ws/2/release/\1?inc=recordings+release-groups+artists+labels+ratings&lt;/url&gt;&lt;/entity&gt;" dest="5+">
- <expression repeat="yes">id=&quot;([^&quot;]*)&quot; ext:score=&quot;(\d*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;/title&gt;&lt;status&gt;(?!Official)[^&lt;]*&lt;/status&gt;(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;packaging&gt;[^&lt;]*&lt;/packaging&gt;)?&lt;text-representation&gt;(?:&lt;language&gt;[^&lt;]*&lt;/language&gt;)*(?:&lt;script&gt;[^&lt;]*&lt;/script&gt;)*&lt;/text-representation&gt;&lt;artist-credit&gt;&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;([^&lt;]*)&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;(?:&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;[^&lt;]*&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;)*&lt;/artist-credit&gt;&lt;release-group\sid=&quot;[^&quot;]*&quot;(?:\stype=&quot;[^&quot;]*&quot;)*&gt;(?:&lt;primary-type&gt;[^&lt;]*&lt;/primary-type&gt;)*(?:&lt;secondary-type-list&gt;(?:&lt;secondary-type&gt;[^&lt;]*&lt;/secondary-type&gt;)+&lt;/secondary-type-list&gt;)*&lt;/release-group&gt;(?:&lt;date&gt;(\d{4})[^&lt;]*&lt;/date&gt;)*(?:&lt;country&gt;)*([^&lt;]*)?.*?&lt;track-list\scount=&quot;(\d+)</expression>
+ <expression repeat="yes">release\sid=&quot;([^&quot;]*)&quot;[^:]*:score=&quot;(\d*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;/title&gt;&lt;status&gt;Official&lt;/status&gt;(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;packaging&gt;[^&lt;]*&lt;/packaging&gt;)*&lt;text-representation&gt;(?:&lt;language&gt;[^&lt;]*&lt;/language&gt;)*(?:&lt;script&gt;[^&lt;]*&lt;/script&gt;)*&lt;/text-representation&gt;&lt;artist-credit&gt;&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;([^&lt;]*)&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;(?:&lt;name-credit(?:&gt;)*(?:\sjoinphrase=&quot;[^&quot;]*&quot;&gt;)*(?:&lt;name&gt;[^&lt;]*&lt;/name)*(?:&gt;)*&lt;artist\sid=&quot;[^&quot;]*&quot;&gt;&lt;name&gt;[^&lt;]*&lt;/name&gt;(?:&lt;sort-name&gt;[^&lt;]*&lt;/sort-name&gt;)*(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;alias-list&gt;(?:&lt;alias[^&lt;]*&lt;/alias&gt;)*&lt;/alias-list&gt;)*&lt;/artist&gt;&lt;/name-credit&gt;)*&lt;/artist-credit&gt;&lt;release-group\sid=&quot;[^&quot;]*&quot;\stype=&quot;[^&quot;]*&quot;\stype-id=&quot;[^&quot;]*&quot;&gt;&lt;title&gt;[^&lt;]*&lt;/title&gt;(?:&lt;disambiguation&gt;[^&lt;]*&lt;/disambiguation&gt;)*(?:&lt;primary-type\sid=&quot;[^&quot;]*&quot;&gt;[^&lt;]*&lt;/primary-type&gt;)*(?:&lt;secondary-type-list&gt;(?:&lt;secondary-type\sid=&quot;[^&quot;]*&quot;&gt;[^&lt;]*&lt;/secondary-type&gt;)+&lt;/secondary-type-list&gt;)*&lt;/release-group&gt;(?:&lt;date&gt;(\d{4})[^&lt;]*&lt;/date&gt;)*(?:&lt;country&gt;)*([^&lt;]*)?.*?&lt;track-list\scount=&quot;(\d+).*?&lt;/release&gt;</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
@@ -140,9 +122,21 @@
<RegExp conditional="fanarttvalbumthumbs" input="$$4" output="&lt;chain function=&quot;GetFanartTvAlbumThumbsByMBID&quot;&gt;\1&lt;/chain&gt;" dest="5+">
<expression noclean="1">(.+)</expression>
</RegExp>
+ <RegExp conditional="fanarttvalbumdiscart" input="$$4" output="&lt;chain function=&quot;GetFanartTvAlbumDiscartByMBID&quot;&gt;\1&lt;/chain&gt;" dest="5+">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
<RegExp conditional="tadbalbumthumbs" input="$$4" output="&lt;chain function=&quot;GetTADBAlbumThumbsByMBID&quot;&gt;\1&lt;/chain&gt;" dest="5+">
<expression noclean="1">(.+)</expression>
</RegExp>
+ <RegExp conditional="tadbalbumdiscart" input="$$4" output="&lt;chain function=&quot;GetTADBAlbumDiscartByMBID&quot;&gt;\1&lt;/chain&gt;" dest="5+">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <RegExp conditional="tadbalbumback" input="$$4" output="&lt;chain function=&quot;GetTADBAlbumBackByMBID&quot;&gt;\1&lt;/chain&gt;" dest="5+">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <RegExp conditional="tadbalbumspine" input="$$4" output="&lt;chain function=&quot;GetTADBAlbumSpineByMBID&quot;&gt;\1&lt;/chain&gt;" dest="5+">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
<RegExp conditional="allmusicalbumthumbs" input="$$4" output="&lt;url function=&quot;GetAMGAlbumThumbs&quot; cache=&quot;mb-\1-rg.xml&quot;&gt;$INFO[mbsite]/ws/2/release-group/\1?inc=url-rels&lt;/url&gt;" dest="5+">
<expression noclean="1">(.+)</expression>
</RegExp>
diff --git a/addons/metadata.album.universal/changelog.txt b/addons/metadata.album.universal/changelog.txt
index a1c379dd43..6ac78241fa 100644
--- a/addons/metadata.album.universal/changelog.txt
+++ b/addons/metadata.album.universal/changelog.txt
@@ -1,3 +1,13 @@
+[B]3.1.1[/B]
+Fixed: further fixes to search results
+
+[B]3.1.0[/B]
+Added: scraping extra artwork from theaudiobdb.com
+
+[B]3.0.0[/B]
+Fixed: albums won't be found on MusicBrainz
+Added: scraping discart from fanart.tv
+
[B]2.7.3[/B]
Fixed: albums without year on MusicBrainz won't be found
diff --git a/addons/metadata.album.universal/resources/language/English/strings.po b/addons/metadata.album.universal/resources/language/English/strings.po
index 95dc7344a8..2567910cc1 100644
--- a/addons/metadata.album.universal/resources/language/English/strings.po
+++ b/addons/metadata.album.universal/resources/language/English/strings.po
@@ -66,4 +66,20 @@ msgstr ""
msgctxt "#30012"
msgid "MusicBrainz Mirror"
+msgstr ""
+
+msgctxt "#30013"
+msgid "Grab Album Discart from fanart.tv"
+msgstr ""
+
+msgctxt "#30014"
+msgid "Grab Album Back Cover from theaudiodb.com"
+msgstr ""
+
+msgctxt "#30015"
+msgid "Grab Album Discart from theaudiodb.com"
+msgstr ""
+
+msgctxt "#30016"
+msgid "Grab Album Spine from theaudiodb.com"
msgstr "" \ No newline at end of file
diff --git a/addons/metadata.album.universal/resources/settings.xml b/addons/metadata.album.universal/resources/settings.xml
index 05467b8903..f52de9b10a 100644
--- a/addons/metadata.album.universal/resources/settings.xml
+++ b/addons/metadata.album.universal/resources/settings.xml
@@ -16,9 +16,13 @@
<setting label="30000" type="bool" id="fanarttvalbumthumbs" default="true"/>
<setting label="30010" type="bool" id="tadbalbumthumbs" default="true"/>
<setting label="30008" type="bool" id="allmusicalbumthumbs" default="false"/>
+ <setting label="30013" type="bool" id="fanarttvalbumdiscart" default="false"/>
+ <setting label="30015" type="bool" id="tadbalbumdiscart" default="false"/>
+ <setting label="30014" type="bool" id="tadbalbumback" default="false"/>
+ <setting label="30016" type="bool" id="tadbalbumspine" default="false"/>
</category>
<category label="30011">
- <setting label="30012" type="text" id="mbsite" default="http://musicbrainz.org"/>
+ <setting label="30012" type="text" id="mbsite" default="https://musicbrainz.org"/>
</category>
</settings>
diff --git a/addons/metadata.artists.universal/addon.xml b/addons/metadata.artists.universal/addon.xml
index 972f78d80d..0f9ab23270 100644
--- a/addons/metadata.artists.universal/addon.xml
+++ b/addons/metadata.artists.universal/addon.xml
@@ -1,14 +1,14 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="metadata.artists.universal"
name="Universal Artist Scraper"
- version="4.1.4"
+ version="4.2.1"
provider-name="Olympia, Team Kodi">
<requires>
<import addon="xbmc.metadata" version="2.1.0"/>
<import addon="metadata.common.allmusic.com" version="3.1.0"/>
<import addon="metadata.common.fanart.tv" version="3.1.0"/>
<import addon="metadata.common.musicbrainz.org" version="2.1.0"/>
- <import addon="metadata.common.theaudiodb.com" version="1.8.1"/>
+ <import addon="metadata.common.theaudiodb.com" version="2.0.0"/>
</requires>
<extension point="xbmc.metadata.scraper.artists"
language="en"
diff --git a/addons/metadata.artists.universal/artistuniversal.xml b/addons/metadata.artists.universal/artistuniversal.xml
index b1d1c605f5..6131998bbc 100644
--- a/addons/metadata.artists.universal/artistuniversal.xml
+++ b/addons/metadata.artists.universal/artistuniversal.xml
@@ -52,6 +52,9 @@
<RegExp input="$$1" output="&lt;musicBrainzArtistID&gt;$$8&lt;/musicBrainzArtistID&gt;&lt;name&gt;\1&lt;/name&gt;" dest="5">
<expression noclean="1">&lt;artist.*?&lt;name&gt;([^&lt;]*)</expression>
</RegExp>
+ <RegExp input="$$1" output="&lt;sortname&gt;\1&lt;/sortname&gt;" dest="5+">
+ <expression noclean="1">&lt;artist.*?&lt;sort-name&gt;([^&lt;]*)</expression>
+ </RegExp>
<RegExp input="$$1" output="&lt;type&gt;\1&lt;/type&gt;" dest="5+">
<expression noclean="1">&lt;artist.*?\stype=&quot;([Person|Group|Orchestra|Choir|Character|Other])&quot;</expression>
</RegExp>
@@ -67,9 +70,24 @@
<RegExp input="$$8" conditional="fanarttvartistcl" output="&lt;chain function=&quot;GetFanartTvArtistClearlogoByMBID&quot;&gt;\1&lt;/chain&gt;" dest="5+">
<expression noclean="1">(.+)</expression>
</RegExp>
+ <RegExp input="$$8" conditional="fanarttvartistbanner" output="&lt;chain function=&quot;GetFanartTvArtistBannerByMBID&quot;&gt;\1&lt;/chain&gt;" dest="5+">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
<RegExp input="$$8" conditional="tadbthumbs" output="&lt;chain function=&quot;GetTADBArtistThumbsByMBID&quot;&gt;$$8&lt;/chain&gt;" dest="5+">
<expression noclean="1">(.+)</expression>
</RegExp>
+ <RegExp input="$$8" conditional="tadbartistclearlogo" output="&lt;chain function=&quot;GetTADBArtistClearlogoByMBID&quot;&gt;$$8&lt;/chain&gt;" dest="5+">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <RegExp input="$$8" conditional="tadbartistclearart" output="&lt;chain function=&quot;GetTADBArtistClearartByMBID&quot;&gt;$$8&lt;/chain&gt;" dest="5+">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <RegExp input="$$8" conditional="tadbartistlandscape" output="&lt;chain function=&quot;GetTADBArtistLandscapeByMBID&quot;&gt;$$8&lt;/chain&gt;" dest="5+">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <RegExp input="$$8" conditional="tadbartistbanner" output="&lt;chain function=&quot;GetTADBArtistBannerByMBID&quot;&gt;$$8&lt;/chain&gt;" dest="5+">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
<RegExp input="$$8" conditional="fanarttvfanart" output="&lt;chain function=&quot;GetFanartTvArtistFanartsByMBID&quot;&gt;\1&lt;/chain&gt;" dest="5+">
<expression noclean="1">(.+)</expression>
</RegExp>
diff --git a/addons/metadata.artists.universal/changelog.txt b/addons/metadata.artists.universal/changelog.txt
index d08f2917dc..b29163f255 100644
--- a/addons/metadata.artists.universal/changelog.txt
+++ b/addons/metadata.artists.universal/changelog.txt
@@ -1,3 +1,12 @@
+[B]4.2.1[/B]
+fixed: dependency error
+
+[B]4.2.0[/B]
+added: scraping extra artwork from theaudiodb.com
+
+[B]4.1.5[/B]
+added: artist sort name from Musicbrainz and artist banner from fanart.tv
+
[B]4.1.4[/B]
changed: include some other valid MB artist types in the previous fix
diff --git a/addons/metadata.artists.universal/resources/language/English/strings.po b/addons/metadata.artists.universal/resources/language/English/strings.po
index 4a1e97a38a..9571041015 100644
--- a/addons/metadata.artists.universal/resources/language/English/strings.po
+++ b/addons/metadata.artists.universal/resources/language/English/strings.po
@@ -124,4 +124,24 @@ msgstr ""
msgctxt "#30027"
msgid "Enable Artist Clearlogo from fanart.tv"
+msgstr ""
+
+msgctxt "#30028"
+msgid "Enable Artist Banner from fanart.tv"
+msgstr ""
+
+msgctxt "#30029"
+msgid "Enable Artist Clearlogo from theaudiodb.com"
+msgstr ""
+
+msgctxt "#30030"
+msgid "Enable Artist Clearart from theaudiodb.com"
+msgstr ""
+
+msgctxt "#30031"
+msgid "Enable Artist Landscape from theaudiodb.com"
+msgstr ""
+
+msgctxt "#30032"
+msgid "Enable Artist Banner from theaudiodb.com"
msgstr "" \ No newline at end of file
diff --git a/addons/metadata.artists.universal/resources/settings.xml b/addons/metadata.artists.universal/resources/settings.xml
index 6a021a430d..84f7fb1e84 100644
--- a/addons/metadata.artists.universal/resources/settings.xml
+++ b/addons/metadata.artists.universal/resources/settings.xml
@@ -33,10 +33,15 @@
<setting label="30004" type="bool" id="fanarttvfanart" default="true"/>
<setting label="30023" type="bool" id="tadbfanart" default="true"/>
<setting label="30027" type="bool" id="fanarttvartistcl" default="false"/>
+ <setting label="30029" type="bool" id="tadbartistclearlogo" default="false"/>
+ <setting label="30030" type="bool" id="tadbartistclearart" default="false"/>
+ <setting label="30031" type="bool" id="tadbartistlandscape" default="false"/>
+ <setting label="30028" type="bool" id="fanarttvartistbanner" default="false"/>
+ <setting label="30032" type="bool" id="tadbartistbanner" default="false"/>
</category>
<category label="30025">
- <setting label="30026" type="text" id="mbsite" default="http://musicbrainz.org"/>
+ <setting label="30026" type="text" id="mbsite" default="https://musicbrainz.org"/>
</category>
</settings>
diff --git a/addons/metadata.common.allmusic.com/addon.xml b/addons/metadata.common.allmusic.com/addon.xml
index 2c2bf34bf8..3099cb809c 100644
--- a/addons/metadata.common.allmusic.com/addon.xml
+++ b/addons/metadata.common.allmusic.com/addon.xml
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="metadata.common.allmusic.com"
name="AllMusic Scraper Library"
- version="3.1.1"
+ version="3.2.0"
provider-name="Team Kodi">
<requires>
<import addon="xbmc.metadata" version="2.1.0"/>
diff --git a/addons/metadata.common.allmusic.com/allmusic.xml b/addons/metadata.common.allmusic.com/allmusic.xml
index 20e9ee38ed..e431cf5051 100644
--- a/addons/metadata.common.allmusic.com/allmusic.xml
+++ b/addons/metadata.common.allmusic.com/allmusic.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scraperfunctions>
<GetAMGDiscographyByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist-discography.html&quot; function=&quot;ParseAMGDiscography&quot;&gt;http://www.allmusic.com/artist/\1/discography&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist-discography.html&quot; function=&quot;ParseAMGDiscography&quot;&gt;https://www.allmusic.com/artist/\1/discography&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression clear="yes" noclean="1"/>
</RegExp>
</GetAMGDiscographyByAMGID>
@@ -17,54 +17,8 @@
</RegExp>
</ParseAMGDiscography>
- <GetAMGBiographyByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGBiography&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
- <expression noclean="1"/>
- </RegExp>
- </GetAMGBiographyByAMGID>
- <ParseAMGBiography dest="5" clearbuffers="no">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="" output="" dest="2">
- <expression />
- </RegExp>
- <RegExp input="$$1" output="\1" dest="11">
- <expression clear="yes">&quot; itemprop=&quot;description&quot;&gt;(.*?)div class=&quot;advertisement leaderboard&quot;&gt;</expression>
- </RegExp>
- <RegExp input="$$11" output="$$12" dest="2">
- <RegExp input="$INFO[biogfbsource]" output="&lt;chain function=&quot;GetLastFMFallbackBiographyByMBID&quot;&gt;$$8&lt;/chain&gt;" dest="12">
- <expression>last.fm</expression>
- </RegExp>
- <RegExp input="$INFO[biogfbsource]" output="&lt;chain function=&quot;GetTADBFMFallbackBiographyByMBID&quot;&gt;$$8&lt;/chain&gt;" dest="12">
- <expression>TheAudioDb.com</expression>
- </RegExp>
- <expression>^$</expression>
- </RegExp>
- <RegExp input="$$11" output="&lt;biography&gt;\1&lt;/biography&gt;" dest="2">
- <expression>(.+)</expression>
- </RegExp>
- <expression noclean="1"/>
- </RegExp>
- </ParseAMGBiography>
-
- <GetAMGFallbackBiographyByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGFallbackBiography&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
- <expression noclean="1"/>
- </RegExp>
- </GetAMGFallbackBiographyByAMGID>
- <ParseAMGFallbackBiography dest="5" clearbuffers="no">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="" output="" dest="2">
- <expression />
- </RegExp>
- <RegExp input="$$1" output="&lt;biography&gt;\1&lt;/biography&gt;" dest="2">
- <expression clear="yes">&quot; itemprop=&quot;description&quot;&gt;(.*?)div class=&quot;advertisement leaderboard&quot;&gt;</expression>
- </RegExp>
- <expression noclean="1"/>
- </RegExp>
- </ParseAMGFallbackBiography>
-
<GetAMGArtistLifeSpanByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistLifeSpan&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistLifeSpan&quot;&gt;https://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGArtistLifeSpanByAMGID>
@@ -76,17 +30,17 @@
<RegExp input="" output="" dest="11">
<expression />
</RegExp>
- <RegExp input="$$1" output="&lt;born&gt;\1 \2&lt;/born&gt;" dest="11+">
- <expression trim="1,2">&lt;h4&gt;\s*Born\s*&lt;/h4&gt;\s*&lt;div&gt;(.*?\d{4})\s*([^&lt;]*)?</expression>
+ <RegExp input="$$1" output="&lt;born&gt;\1 \3&lt;/born&gt;" dest="11+">
+ <expression trim="1,2">&lt;h4&gt;\s.+Born.*?birthdate/[^&quot;]+&quot;&gt;([^&lt;]*)(.*?"/birthplace/[^&quot;]+&quot;&gt;([^&lt;]*))?</expression>
</RegExp>
- <RegExp input="$$1" output="&lt;died&gt;\1 \2&lt;/died&gt;" dest="11+">
- <expression trim="1,2">&lt;h4&gt;\s*Died\s*&lt;/h4&gt;\s*&lt;div&gt;(.*?\d{4})\s*([^&lt;]*)?</expression>
+ <RegExp input="$$1" output="&lt;died&gt;\1 \3&lt;/died&gt;" dest="11+">
+ <expression trim="1,2">&lt;h4&gt;\s.+Died.*?deathdate/[^&quot;]+&quot;&gt;([^&lt;]*)(.*?&quot;/deathplace/[^&quot;]+&quot;&gt;([^&lt;]*))?</expression>
</RegExp>
<RegExp input="$$1" output="&lt;formed&gt;\1&lt;/formed&gt;" dest="11+">
- <expression trim="1,2">&lt;h4&gt;\s*Formed\s*&lt;/h4&gt;\s*&lt;div&gt;(.*?\d{4})\s*([^&lt;]*)?</expression>
+ <expression trim="1,2">&lt;h4&gt;\s.+Formed.*?birthdate/[^&quot;]+&quot;&gt;([^&lt;]*)</expression>
</RegExp>
<RegExp input="$$1" output="&lt;disbanded&gt;\1&lt;/disbanded&gt;" dest="11+">
- <expression trim="1,2">&lt;h4&gt;\s*Disbanded\s*&lt;/h4&gt;\s*&lt;div&gt;(.*?\d{4})\s*([^&lt;]*)?</expression>
+ <expression trim="1,2">&lt;h4&gt;\s.+Disbanded.*?deathdate/[^&quot;]+[^&quot;]+&quot;&gt;([^&lt;]*)</expression>
</RegExp>
<RegExp input="$$11" output="$$12" dest="2">
<RegExp input="$INFO[lifespanfbsource]" output="&lt;chain function=&quot;GetMBFallbackLafeSpanByMBID&quot;&gt;$$8&lt;/chain&gt;" dest="12">
@@ -105,7 +59,7 @@
</ParseAMGArtistLifeSpan>
<GetAMGFallbackArtistLifeSpanByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGFallbackArtistLifeSpan&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGFallbackArtistLifeSpan&quot;&gt;https://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGFallbackArtistLifeSpanByAMGID>
@@ -131,7 +85,7 @@
</ParseAMGFallbackArtistLifeSpan>
<GetAMGArtistYearsActiveByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistYearsActive&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistYearsActive&quot;&gt;https://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGArtistYearsActiveByAMGID>
@@ -148,7 +102,7 @@
</ParseAMGArtistYearsActive>
<GetAMGArtistGenresByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistGenres&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistGenres&quot;&gt;https://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGArtistGenresByAMGID>
@@ -164,7 +118,7 @@
<expression noclean="1">&lt;h4&gt;Genre&lt;/h4&gt;\s*&lt;div&gt;(.*?)&lt;/div&gt;</expression>
</RegExp>
<RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="11">
- <expression repeat="yes" noclean="1">&lt;a\shref=&quot;http://www.allmusic.com/genre/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
+ <expression repeat="yes" noclean="1">&lt;a\shref=&quot;https://www.allmusic.com/genre/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
</RegExp>
<RegExp input="$$11" output="$$12" dest="2">
<RegExp input="$INFO[genresfbsource]" output="&lt;chain function=&quot;GetLastFMFallbackArtistGenresByMBID&quot;&gt;$$8&lt;/chain&gt;" dest="12">
@@ -183,7 +137,7 @@
</ParseAMGArtistGenres>
<GetAMGFallbackArtistGenresByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGFallbackArtistGenres&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGFallbackArtistGenres&quot;&gt;https://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGFallbackArtistGenresByAMGID>
@@ -199,14 +153,14 @@
<expression noclean="1">&lt;h4&gt;Genre&lt;/h4&gt;\s*&lt;div&gt;(.*?)&lt;/div&gt;</expression>
</RegExp>
<RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="2">
- <expression repeat="yes" noclean="1">&lt;a\shref=&quot;http://www.allmusic.com/genre/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
+ <expression repeat="yes" noclean="1">&lt;a\shref=&quot;https://www.allmusic.com/genre/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseAMGFallbackArtistGenres>
<GetAMGArtistStylesByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistStyles&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistStyles&quot;&gt;https://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGArtistStylesByAMGID>
@@ -222,7 +176,7 @@
<expression noclean="1">&lt;h4&gt;Styles&lt;/h4&gt;\s*&lt;div&gt;(.*?)&lt;/div&gt;</expression>
</RegExp>
<RegExp input="$$7" output="&lt;style&gt;\1&lt;/style&gt;" dest="11">
- <expression repeat="yes" noclean="1">&lt;a\shref=&quot;http://www.allmusic.com/style/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
+ <expression repeat="yes" noclean="1">&lt;a\shref=&quot;https://www.allmusic.com/style/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
</RegExp>
<RegExp input="$$11" output="$$12" dest="2">
<RegExp input="$INFO[stylesfbsource]" output="&lt;chain function=&quot;GetLastFMFallbackArtistStylesByMBID&quot;&gt;$$8&lt;/chain&gt;" dest="12">
@@ -241,7 +195,7 @@
</ParseAMGArtistStyles>
<GetAMGFallbackArtistStylesByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGFallbackArtistStyles&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGFallbackArtistStyles&quot;&gt;https://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGFallbackArtistStylesByAMGID>
@@ -257,14 +211,14 @@
<expression noclean="1">&lt;h4&gt;Styles&lt;/h4&gt;\s*&lt;div&gt;(.*?)&lt;/div&gt;</expression>
</RegExp>
<RegExp input="$$7" output="&lt;style&gt;\1&lt;/style&gt;" dest="2">
- <expression repeat="yes" noclean="1">&lt;a\shref=&quot;http://www.allmusic.com/style/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
+ <expression repeat="yes" noclean="1">&lt;a\shref=&quot;https://www.allmusic.com/style/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseAMGFallbackArtistStyles>
<GetAMGArtistMoodsByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistMoods&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistMoods&quot;&gt;https://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGArtistMoodsByAMGID>
@@ -296,7 +250,7 @@
</ParseAMGArtistMoods>
<GetAMGFallbackArtistMoodsByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGFallbackArtistMoods&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGFallbackArtistMoods&quot;&gt;https://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGFallbackArtistMoodsByAMGID>
@@ -318,74 +272,9 @@
</RegExp>
</ParseAMGFallbackArtistMoods>
- <GetAMGArtistThumbsByAMGID dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGArtistThumbs&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
- <expression noclean="1"/>
- </RegExp>
- </GetAMGArtistThumbsByAMGID>
- <ParseAMGArtistThumbs dest="5" clearbuffers="no">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="" output="" dest="2">
- <expression />
- </RegExp>
- <RegExp input="" output="" dest="4">
- <expression />
- </RegExp>
- <RegExp input="$$1" output="\1" dest="4">
- <expression noclean="1">&lt;h\d&gt;Photo\sGallery&lt;/h\d&gt;(.*?)&lt;h2\sclass=&quot;artist-name&quot;</expression>
- </RegExp>
- <RegExp input="$$4" output="&lt;thumb&gt;http://cps-static.rovicorp.com/3/JPG_1080/\1&lt;/thumb&gt;" dest="2">
- <expression repeat="yes" noclean="1">&lt;img src=&quot;http://cps-static.rovicorp.com/3/JPG_[^/]*/([^&quot;]*)</expression>
- </RegExp>
- <expression noclean="1"/>
- </RegExp>
- </ParseAMGArtistThumbs>
-
-
- <GetAMGAlbumReviewByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumReview&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
- <expression noclean="1"/>
- </RegExp>
- </GetAMGAlbumReviewByAMGID>
- <ParseAMGAlbumReview dest="5">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;review&gt;\1&lt;/review&gt;" dest="2">
- <expression>&lt;span itemprop=&quot;description&quot;&gt;([^&lt;]*)</expression>
- </RegExp>
- <expression noclean="1" />
- </RegExp>
- </ParseAMGAlbumReview>
-
- <GetAMGAlbumTitleByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumTitle&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
- <expression noclean="1"/>
- </RegExp>
- </GetAMGAlbumTitleByAMGID>
- <ParseAMGAlbumTitle dest="5">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="2">
- <expression trim="1" noclean="1">&lt;div class=&quot;album-title&quot;&gt;([^&lt;]*)</expression>
- </RegExp>
- <expression noclean="1" />
- </RegExp>
- </ParseAMGAlbumTitle>
-
- <GetAMGAlbumArtistByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumArtist&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
- <expression noclean="1"/>
- </RegExp>
- </GetAMGAlbumArtistByAMGID>
- <ParseAMGAlbumArtist dest="5">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;artist&gt;\1&lt;/artist&gt;" dest="2">
- <expression noclean="1">&lt;div class=&quot;album-artist&quot;&gt;[^&gt;]*&gt;([^&lt;]*)</expression>
- </RegExp>
- <expression noclean="1" />
- </RegExp>
- </ParseAMGAlbumArtist>
<GetAMGAlbumRatingByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumRating&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumRating&quot;&gt;https://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGAlbumRatingByAMGID>
@@ -398,59 +287,42 @@
</RegExp>
</ParseAMGAlbumRating>
- <GetAMGAlbumDateByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumDate&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
- <expression noclean="1"/>
- </RegExp>
- </GetAMGAlbumDateByAMGID>
- <ParseAMGAlbumDate dest="5">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;releasedate&gt;\1&lt;/releasedate&gt;" dest="2">
- <expression noclean="1">&lt;dd class=&quot;release-date&quot;&gt;([^&lt;]*)</expression>
- </RegExp>
- <RegExp input="$$1" output="&lt;year&gt;\2&lt;/year&gt;" dest="2+">
- <expression trim="1" noclean="1">&lt;dd class=&quot;release-date&quot;&gt;([^,]*,)?([^&lt;]*)</expression>
- </RegExp>
- <expression noclean="1" />
- </RegExp>
- </ParseAMGAlbumDate>
-
<GetAMGAlbumGenresByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumGenres&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumGenres&quot;&gt;https://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGAlbumGenresByAMGID>
<ParseAMGAlbumGenres dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="6">
- <expression noclean="1">&lt;h4&gt;Genre&lt;/h4&gt;\s*&lt;div&gt;(.*?)&lt;/div&gt;</expression>
+ <expression noclean="1">class=&quot;genre&quot;&gt;(.*?)&lt;/div&gt;</expression>
</RegExp>
<RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="2">
- <expression repeat="yes" noclean="1">&lt;a\shref=&quot;http://www.allmusic.com/genre/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
+ <expression repeat="yes" noclean="1">&lt;a\shref=&quot;https://www.allmusic.com/genre/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseAMGAlbumGenres>
<GetAMGAlbumStylesByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumStyles&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumStyles&quot;&gt;https://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGAlbumStylesByAMGID>
<ParseAMGAlbumStyles dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="7">
- <expression noclean="1">&lt;h4&gt;Styles&lt;/h4&gt;\s*&lt;div&gt;(.*?)&lt;/div&gt;</expression>
+ <expression noclean="1">class=&quot;styles&quot;&gt;(.*?)&lt;/div&gt;</expression>
</RegExp>
<RegExp input="$$7" output="&lt;style&gt;\1&lt;/style&gt;" dest="2">
- <expression repeat="yes" noclean="1">&lt;a\shref=&quot;http://www.allmusic.com/style/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
+ <expression repeat="yes" noclean="1">&lt;a\shref=&quot;https://www.allmusic.com/style/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseAMGAlbumStyles>
<GetAMGAlbumMoodsByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumMoods&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumMoods&quot;&gt;https://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGAlbumMoodsByAMGID>
@@ -460,84 +332,41 @@
<expression trim="1" noclean="1">&gt;\s*&lt;h4&gt;Album\sMoods&lt;/h4&gt;(.*?)&lt;/section&gt;</expression>
</RegExp>
<RegExp input="$$8" output="&lt;mood&gt;\1&lt;/mood&gt;" dest="2">
- <expression repeat="yes" noclean="1">&lt;a\shref=&quot;http://www.allmusic.com/mood/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
+ <expression repeat="yes" noclean="1">&lt;a\shref=&quot;https://www.allmusic.com/mood/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseAMGAlbumMoods>
<GetAMGAlbumThemesByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumThemes&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumThemes&quot;&gt;https://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGAlbumThemesByAMGID>
<ParseAMGAlbumThemes dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="4">
- <expression trim="1" noclean="1">&gt;\s*&lt;h4&gt;Themes&lt;/h4&gt;(.*?)&lt;/ul&gt;</expression>
+ <expression trim="1" noclean="1">&lt;section\sclass=&quot;themes&quot;&gt;(.*?)&lt;/section&gt;</expression>
</RegExp>
<RegExp input="$$4" output="&lt;theme&gt;\1&lt;/theme&gt;" dest="2">
- <expression repeat="yes" noclean="1">&lt;a\shref=&quot;http://www.allmusic.com/theme/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
+ <expression repeat="yes" noclean="1">&lt;a\shref=&quot;https://www.allmusic.com/theme/[^&quot;]*&quot;&gt;([^&lt;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseAMGAlbumThemes>
- <GetAMGAlbumTracksByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumTracks&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
- <expression noclean="1"/>
- </RegExp>
- </GetAMGAlbumTracksByAMGID>
- <ParseAMGAlbumTracks dest="5">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;track&gt;&lt;position&gt;\1&lt;/position&gt;&lt;title&gt;\2&lt;/title&gt;&lt;duration&gt;\3&lt;/duration&gt;&lt;/track&gt;" dest="2">
- <expression repeat="yes" trim="1" noclean="1,2,3">&lt;td class=&quot;tracknum&quot;&gt;([0-9]*).*?&lt;div class=&quot;title&quot;&gt;[^&gt;]*&gt;([^&lt;]*).*?&lt;td class=&quot;time&quot;&gt;([^&lt;]*)</expression>
- </RegExp>
- <expression noclean="1" />
- </RegExp>
- </ParseAMGAlbumTracks>
-
<GetAMGAlbumThumbsByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumThumbs&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGAlbumThumbs&quot;&gt;https://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
</RegExp>
</GetAMGAlbumThumbsByAMGID>
<ParseAMGAlbumThumbs dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;thumb&gt;http://cps-static.rovicorp.com/3/JPG_500/\1&lt;/thumb&gt;" dest="2">
- <expression noclean="1">&quot;http://cps-static.rovicorp.com/3/JPG_[^/]*/([^&quot;]*)</expression>
+ <RegExp input="$$1" output="&lt;thumb&gt;https://cdn-s3.allmusic.com/release-covers/500/\1&lt;/thumb&gt;" dest="2">
+ <expression noclean="1">&lt;img src=&quot;https://cdn-s3.allmusic.com/release-covers/500/([^&quot;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseAMGAlbumThumbs>
-
- <GetAMGFakeBiographyByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-artist.html&quot; function=&quot;ParseAMGFakeBiography&quot;&gt;http://www.allmusic.com/artist/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
- <expression noclean="1"/>
- </RegExp>
- </GetAMGFakeBiographyByAMGID>
- <ParseAMGFakeBiography dest="5">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;biography&gt;Fetching artist biography from allmusic.com is not possible due to copyright reasons.&lt;/biography&gt;" dest="2">
- <expression noclean="1" />
- </RegExp>
- <expression noclean="1"/>
- </RegExp>
- </ParseAMGFakeBiography>
-
- <GetAMGFakeAlbumReviewByAMGID dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;am-\1-album.html&quot; function=&quot;ParseAMGFakeAlbumReview&quot;&gt;http://www.allmusic.com/album/\1&lt;/url&gt;&lt;/details&gt;" dest="5">
- <expression noclean="1"/>
- </RegExp>
- </GetAMGFakeAlbumReviewByAMGID>
- <ParseAMGFakeAlbumReview dest="5">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;review&gt;Fetching album review from allmusic.com is not possible due to copyright reasons.&lt;/review&gt;" dest="2">
- <expression noclean="1"/>
- </RegExp>
- <expression noclean="1" />
- </RegExp>
- </ParseAMGFakeAlbumReview>
-
</scraperfunctions>
diff --git a/addons/metadata.common.fanart.tv/addon.xml b/addons/metadata.common.fanart.tv/addon.xml
index 1a01b98ca4..45caf8c534 100644
--- a/addons/metadata.common.fanart.tv/addon.xml
+++ b/addons/metadata.common.fanart.tv/addon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="metadata.common.fanart.tv"
name="fanart.tv Scraper Library"
- version="3.1.5"
+ version="3.5.0"
provider-name="Team Kodi">
<requires>
<import addon="xbmc.metadata" version="2.1.0"/>
diff --git a/addons/metadata.common.fanart.tv/fanarttv.xml b/addons/metadata.common.fanart.tv/fanarttv.xml
index ecf02d7e86..6dffe1d0ff 100644
--- a/addons/metadata.common.fanart.tv/fanarttv.xml
+++ b/addons/metadata.common.fanart.tv/fanarttv.xml
@@ -16,13 +16,59 @@
<RegExp input="$$1" output="\1" dest="16">
<expression noclean="1">&quot;artistthumb&quot;:\s\[(.*?)\}\s*\]</expression>
</RegExp>
- <RegExp input="$$16" output="&lt;thumb preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
<expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseFanartTvArtistThumbs>
+ <GetFanartTvArtistClearlogoByMBID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseFanartTvArtistClearlogo&quot; cache=&quot;fanarttv-artistimages-\1.json&quot;&gt;https://webservice.fanart.tv/v3/music/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvArtistClearlogoByMBID>
+ <ParseFanartTvArtistClearlogo dest="5" clearbuffers="no">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;hdmusiclogo&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearlogo&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvArtistClearlogo>
+
+ <GetFanartTvArtistBannerByMBID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseFanartTvArtistBanner&quot; cache=&quot;fanarttv-artistimages-\1.json&quot;&gt;https://webservice.fanart.tv/v3/music/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvArtistBannerByMBID>
+ <ParseFanartTvArtistBanner dest="5" clearbuffers="no">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;musicbanner&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;banner&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvArtistBanner>
+
<GetFanartTvArtistFanartsByMBID dest="5" clearbuffers="no">
<RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseFanartTvArtistFanarts&quot; cache=&quot;fanarttv-artistimages-\1.json&quot;&gt;https://webservice.fanart.tv/v3/music/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
@@ -75,6 +121,29 @@
</RegExp>
</ParseFanartTvAlbumThumbs>
+ <GetFanartTvAlbumDiscartByMBID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseFanartTvAlbumDiscart&quot; cache=&quot;fanarttv-albumimages-\1.json&quot;&gt;https://webservice.fanart.tv/v3/music/albums/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvAlbumDiscartByMBID>
+ <ParseFanartTvAlbumDiscart dest="5" clearbuffers="no">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;cdart&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;discart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvAlbumDiscart>
+
<GetFanartTvFanartByIdChain dest="4">
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
<RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvFanart&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/movies/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
@@ -107,15 +176,18 @@
</RegExp>
</ParseFanartTvFanart>
- <GetFanartTvThumbsByIdChain dest="4">
+ <GetFanartTvThumbsByIdChain clearbuffers="no" dest="4"> <!-- Expected chaining format= tmdb_id::language-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvThumbs&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/movies/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="\2" dest="11">
+ <expression>(.+)::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvMoviePoster&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/movies/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression>(.+)::(.+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</GetFanartTvThumbsByIdChain>
- <ParseFanartTvThumbs dest="5">
+ <ParseFanartTvMoviePoster dest="5">
<RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="" output="" dest="13">
<expression />
@@ -126,11 +198,524 @@
<RegExp input="$$1" output="\1" dest="16">
<expression noclean="1">&quot;movieposter&quot;:\s\[(.*?)\}\s*\]</expression>
</RegExp>
- <RegExp input="$$16" output="&lt;thumb preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$11&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;00&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvMoviePoster>
+
+ <GetFanartTvMovieClearlogoByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvMovieClearlogo&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/movies/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvMovieClearlogoByIdChain>
+ <ParseFanartTvMovieClearlogo dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;hdmovielogo&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearlogo&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearlogo&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearlogo&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;00&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvMovieClearlogo>
+
+ <GetFanartTvMovieClearartByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvMovieClearart&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/movies/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvMovieClearartByIdChain>
+ <ParseFanartTvMovieClearart dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;hdmovieclearart&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;00&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvMovieClearart>
+
+ <GetFanartTvMoviebannerByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvMoviebanner&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/movies/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvMoviebannerByIdChain>
+ <ParseFanartTvMoviebanner dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;moviebanner&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;banner&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;banner&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;banner&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;00&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvMoviebanner>
+
+ <GetFanartTvMovieLandscapeByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvMovieLandscape&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/movies/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvMovieLandscapeByIdChain>
+ <ParseFanartTvMovieLandscape dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;moviethumb&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;landscape&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;landscape&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;landscape&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;00&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvMovieLandscape>
+
+ <GetFanartTvMovieDiscartByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvMovieDiscart&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/movies/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvMovieDiscartByIdChain>
+ <ParseFanartTvMovieDiscart dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;moviedisc&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;discart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;discart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;discart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;00&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvMovieDiscart>
+
+ <GetFanartTvTvShowPosterByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvTvShowPoster&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/tv/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvTvShowPosterByIdChain>
+ <ParseFanartTvTvShowPoster dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;tvposter&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;!$$18|!en&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvTvShowPoster>
+
+ <GetFanartTvTvShowBannerByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvTvShowBanner&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/tv/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvTvShowBannerByIdChain>
+ <ParseFanartTvTvShowBanner dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;tvbanner&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;banner&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;banner&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;banner&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;!$$18|!en&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvTvShowBanner>
+
+ <GetFanartTvTvShowLandscapeByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvTvShowLandscape&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/tv/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvTvShowLandscapeByIdChain>
+ <ParseFanartTvTvShowLandscape dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;tvthumb&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;landscape&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;landscape&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;landscape&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;!$$18|!en&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvTvShowLandscape>
+
+ <GetFanartTvTvShowClearlogoByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvTvShowClearlogo&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/tv/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvTvShowClearlogoByIdChain>
+ <ParseFanartTvTvShowClearlogo dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;hdtvlogo&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearlogo&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearlogo&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearlogo&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;!$$18|!en&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvTvShowClearlogo>
+
+ <GetFanartTvTvShowClearartByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvTvShowClearart&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/tv/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvTvShowClearartByIdChain>
+ <ParseFanartTvTvShowClearart dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;hdclearart&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;clearart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;!$$18|!en&quot;</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvTvShowClearart>
+
+ <GetFanartTvTvShowFanartByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvTvShowFanart&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/tv/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression />
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvTvShowFanartByIdChain>
+ <ParseFanartTvTvShowFanart dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;&lt;fanart&gt;\1&lt;/fanart&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;showbackground&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvTvShowFanart>
+
+ <GetFanartTvTvShowCharacterartByIdChain dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvTvShowCharacterart&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/tv/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression />
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvTvShowCharacterartByIdChain>
+ <ParseFanartTvTvShowCharacterart dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;characterart&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;characterart&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
<expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
- </ParseFanartTvThumbs>
-
+ </ParseFanartTvTvShowCharacterart>
+
+ <GetFanartTvTvShowSeasonposterByIdChain clearbuffers="no" dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvTvShowSeasonposter&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/tv/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvTvShowSeasonposterByIdChain>
+ <ParseFanartTvTvShowSeasonposter dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;seasonposter&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;poster&quot; type=&quot;season&quot; season=&quot;\3&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;,\s*&quot;likes[^,]*,\s*&quot;season&quot;:\s&quot;([0-9,]+)</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;poster&quot; type=&quot;season&quot; season=&quot;\3&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;,\s*&quot;likes[^,]*,\s*&quot;season&quot;:\s&quot;([0-9,]+)</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;poster&quot; type=&quot;season&quot; season=&quot;\3&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;!$$18|!en&quot;,\s*&quot;likes[^,]*,\s*&quot;season&quot;:\s&quot;([0-9,]+)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvTvShowSeasonposter>
+
+ <GetFanartTvTvShowSeasonbannerByIdChain clearbuffers="no" dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvTvShowSeasonbanner&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/tv/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvTvShowSeasonbannerByIdChain>
+ <ParseFanartTvTvShowSeasonbanner dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;seasonbanner&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;banner&quot; type=&quot;season&quot; season=&quot;\3&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;,\s*&quot;likes[^,]*,\s*&quot;season&quot;:\s&quot;([0-9,]+)</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;banner&quot; type=&quot;season&quot; season=&quot;\3&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;,\s*&quot;likes[^,]*,\s*&quot;season&quot;:\s&quot;([0-9,]+)</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;banner&quot; type=&quot;season&quot; season=&quot;\3&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;!$$18|!en&quot;,\s*&quot;likes[^,]*,\s*&quot;season&quot;:\s&quot;([0-9,]+)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvTvShowSeasonbanner>
+
+ <GetFanartTvTvShowSeasonLandscapeByIdChain clearbuffers="no" dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="18">
+ <expression encode="1">.+::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseFanartTvTvShowSeasonLandscape&quot; cache=&quot;fanarttv-\1.json&quot;&gt;https://webservice.fanart.tv/v3/tv/\1?api_key=ed4b784f97227358b31ca4dd966a04f1&lt;/url&gt;" dest="5">
+ <expression encode="1">(.+)::.+</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </GetFanartTvTvShowSeasonLandscapeByIdChain>
+ <ParseFanartTvTvShowSeasonLandscape dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="16">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression noclean="1">&quot;seasonthumb&quot;:\s\[(.*?)\}\s*\]</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;landscape&quot; type=&quot;season&quot; season=&quot;\3&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;$$18&quot;,\s*&quot;likes[^,]*,\s*&quot;season&quot;:\s&quot;([0-9,]+)</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;landscape&quot; type=&quot;season&quot; season=&quot;\3&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;en&quot;,\s*&quot;likes[^,]*,\s*&quot;season&quot;:\s&quot;([0-9,]+)</expression>
+ </RegExp>
+ <RegExp input="$$16" output="&lt;thumb aspect=&quot;landscape&quot; type=&quot;season&quot; season=&quot;\3&quot; preview=&quot;https://\1/preview/\2&quot;&gt;https://\1/fanart/\2&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;id&quot;:\s&quot;\d*&quot;,\s*&quot;url&quot;:\s&quot;https://([^/]*)/fanart/([^&quot;]*)&quot;,\s*&quot;lang&quot;:\s&quot;!$$18|!en&quot;,\s*&quot;likes[^,]*,\s*&quot;season&quot;:\s&quot;([0-9,]+)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseFanartTvTvShowSeasonLandscape>
+
</scraperfunctions>
diff --git a/addons/metadata.common.imdb.com/addon.xml b/addons/metadata.common.imdb.com/addon.xml
index b5763c2f0c..2391d124af 100644
--- a/addons/metadata.common.imdb.com/addon.xml
+++ b/addons/metadata.common.imdb.com/addon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="metadata.common.imdb.com"
name="IMDB Scraper Library"
- version="2.9.3"
+ version="3.1.0"
provider-name="Team Kodi">
<requires>
<import addon="xbmc.metadata" version="2.1.0"/>
diff --git a/addons/metadata.common.imdb.com/changelog.txt b/addons/metadata.common.imdb.com/changelog.txt
index b4543c7c86..be2a0c4eda 100644
--- a/addons/metadata.common.imdb.com/changelog.txt
+++ b/addons/metadata.common.imdb.com/changelog.txt
@@ -1,3 +1,51 @@
+[B]3.1.0[/B]
+- fixed: re-write most regular expressions following IMDb site layout changes
+
+[B]3.0.8[/B]
+- changed: another change to IMDb outline
+
+[B]3.0.7[/B]
+- changed: removed one of the IMDb outline catch
+
+[B]3.0.6[/B]
+- fixed: try to limit world wide English to over ride proper USA title
+
+[B]3.0.5[/B]
+- fixed: IMDb cast and outline following IMDb layout changes
+
+[B]3.0.4[/B]
+- fixed: IMDb plot after IMDb layout changes
+
+[B]3.0.3[/B]
+- fixed: World-wide English title won't scraped correctly
+
+[B]3.0.2[/B]
+- Use TV certification in the absence of MPAA ones
+
+[B]3.0.1[/B]
+- fixed: USA Title won't scraped correctly under some circumstances, plot outline quirks, IMDB Posters
+
+[B]3.0.0[/B]
+- fixed: IMDb plot outline under some circumstances
+
+[B]2.9.9[/B]
+- fixed: Thumb for IMDb cast
+
+[B]2.9.8[/B]
+- fixed: IMDb outline for some movies
+
+[B]2.9.7[/B]
+- changed: attempt to scrape generic local title from IMDb if multiple are available
+
+[B]2.9.6[/B]
+- fixed: movie title issues after IMDb layout changes
+
+[B]2.9.5[/B]
+- fixed: IMDb Full credits after IMDb layout changes
+
+[B]2.9.4[/B]
+- fixed: USA certification rating due to IMDb changes
+
[B]2.9.3[/B]
- fixed: always get USA rating regardless of the country set
@@ -55,7 +103,7 @@
- fixed: MetaCritic Score
[B]2.7.3[/B]
-- fixed: orginal title won't scrape in some cases
+- fixed: original title won't scrape in some cases
[B]2.7.2[/B]
- changed: make sure to parse the intended page
@@ -115,7 +163,7 @@
- fixed: fetching directors and writers due to site changes
[B]2.1.3[/B]
-- fixed: make sure IMDb rating is geting fetched in every region
+- fixed: make sure IMDb rating is getting fetched in every region
[B]2.1.2[/B]
- fixed: IMDb rating after another site change
@@ -145,10 +193,10 @@
- reverted: fixchars removed from cast parsing, leads to Dharma Beta2 hanging, will be added back once next Beta is out
[B]2.0.2[/B]
-- fixed: some more cast won't get scraped under certain circumtances
+- fixed: some more cast won't get scraped under certain circumstances
[B]2.0.1[/B]
-- fixed: cast won't get scraped under certain circumtances
+- fixed: cast won't get scraped under certain circumstances
[B]2.0.0[/B]
- changed: adapted new IMDb layout
diff --git a/addons/metadata.common.imdb.com/imdb.xml b/addons/metadata.common.imdb.com/imdb.xml
index b5a5b35efb..0797bad7a1 100644
--- a/addons/metadata.common.imdb.com/imdb.xml
+++ b/addons/metadata.common.imdb.com/imdb.xml
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<scraperfunctions>
<GetIMDBGenresById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBGenres&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBGenres&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBGenresById>
@@ -15,21 +15,21 @@
</ParseIMDBGenres>
<GetIMDBRatingById dest="5"> <!-- Compatibility function for Pre-Krypton versions-->
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBRating&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBRating&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBRatingById>
<ParseIMDBRating dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="2">
- <expression>&lt;span\sitemprop=&quot;ratingValue&quot;&gt;([0-9.]+).*?ratingCount&quot;&gt;([0-9,]+)&lt;</expression>
+ <RegExp input="$$1" output="&lt;rating&gt;\2&lt;/rating&gt;&lt;votes&gt;\1&lt;/votes&gt;" dest="2">
+ <expression>&quot;ratingCount&quot;:\s([0-9,]+),\s*&quot;bestRating&quot;:\s&quot;[^&quot;]*&quot;,\s*&quot;worstRating&quot;:\s&quot;[^&quot;]*&quot;,\s*&quot;ratingValue&quot;:\s&quot;([0-9.]+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBRating>
<GetIMDBRatingsById dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;\1-main.html&quot; function=&quot;ParseIMDBRatings&quot;&gt;http://akas.imdb.com/title/\1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;\1-main.html&quot; function=&quot;ParseIMDBRatings&quot;&gt;http://www.imdb.com/title/\1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1">^(tt\d+)</expression>
</RegExp>
<RegExp input="$$1" output="default=&quot;true&quot;" dest="3">
@@ -38,15 +38,15 @@
</GetIMDBRatingsById>
<ParseIMDBRatings dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;ratings&gt;&lt;rating name=&quot;imdb&quot; $$3&gt;&lt;value&gt;\1&lt;/value&gt;&lt;votes&gt;\2&lt;/votes&gt;&lt;/rating&gt;&lt;/ratings&gt;" dest="2">
- <expression>&lt;span\sitemprop=&quot;ratingValue&quot;&gt;([0-9.]+).*?ratingCount&quot;&gt;([0-9,]+)&lt;</expression>
+ <RegExp input="$$1" output="&lt;ratings&gt;&lt;rating name=&quot;imdb&quot; $$3&gt;&lt;value&gt;\2&lt;/value&gt;&lt;votes&gt;\1&lt;/votes&gt;&lt;/rating&gt;&lt;/ratings&gt;" dest="2">
+ <expression>&quot;ratingCount&quot;:\s([0-9,]+),\s*&quot;bestRating&quot;:\s&quot;[^&quot;]*&quot;,\s*&quot;worstRating&quot;:\s&quot;[^&quot;]*&quot;,\s*&quot;ratingValue&quot;:\s&quot;([0-9.]+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBRatings>
<GetIMDBTOP250ById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBTOP250&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBTOP250&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBTOP250ById>
@@ -60,21 +60,21 @@
</ParseIMDBTOP250>
<GetIMDBStudioById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBStudio&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBStudio&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBStudioById>
<ParseIMDBStudio dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="2">
- <expression>&quot;/company/[^&gt;]+&gt;[^&lt;]*&lt;[^&gt;]*&gt;([^&lt;]+)&lt;/span&gt;</expression>
+ <expression>&quot;/company/[^&quot;]+&quot;\s*&gt;([^&lt;]+)&lt;/a&gt;</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBStudio>
<GetIMDBCountryById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBCountry&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBCountry&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBCountryById>
@@ -84,34 +84,34 @@
<expression clear="yes" noclean="1">Country:[^&gt;]+&gt;(.*?)&lt;/div&gt;</expression>
</RegExp>
<RegExp input="$$6" output="&lt;country&gt;\1&lt;/country&gt;" dest="2">
- <expression repeat="yes">itemprop='url'&gt;([^&lt;]+)</expression>
+ <expression repeat="yes">&gt;([^&lt;]+)&lt;/a&gt;</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBCountry>
<GetMetaCriticRatingById dest="5"> <!-- Compatibility function for Pre-Krypton versions-->
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-criticreviews.html&quot; function=&quot;ParseMetaCriticRating&quot;&gt;http://akas.imdb.com/title/$$1/criticreviews|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-criticreviews.html&quot; function=&quot;ParseMetaCriticRating&quot;&gt;http://www.imdb.com/title/$$1/criticreviews|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetMetaCriticRatingById>
<ParseMetaCriticRating dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="6">
- <expression noclean="1">(&lt;div class=&quot;metascore_block&quot;.*)</expression>
+ <expression clear="yes" noclean="1">&lt;div\sclass=&quot;metacriticScore\sscore_mixed\stitleReviewBarSubItem&quot;(.*?)&lt;span\sclass=&quot;ghostText&quot;</expression>
</RegExp>
<RegExp input="$$6" output="&lt;rating max=&quot;100&quot;&gt;\1&lt;/value&gt;" dest="2">
- <expression clear="yes">&lt;span itemprop=&quot;ratingValue&quot;&gt;(\d+)&lt;/span&gt;</expression>
+ <expression clear="yes">&lt;span&gt;(\d+)&lt;/span&gt;</expression>
</RegExp>
<RegExp input="$$6" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="2+">
- <expression>&lt;span itemprop=&quot;ratingCount&quot;&gt;(\d+)&lt;/span&gt;</expression>
+ <expression>&gt;(\d+)\suser&lt;/a&gt;</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseMetaCriticRating>
<GetMetaCriticRatingsById dest="5" clearbuffers="no">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;\1-criticreviews.html&quot; function=&quot;ParseMetaCriticRatings&quot;&gt;http://akas.imdb.com/title/\1/criticreviews|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;\1-criticreviews.html&quot; function=&quot;ParseMetaCriticRatings&quot;&gt;http://www.imdb.com/title/\1/criticreviews|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1">(tt\d+)</expression>
</RegExp>
<RegExp input="$$1" output="default=&quot;true&quot;" dest="3">
@@ -122,13 +122,13 @@
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$4" output="&lt;ratings&gt;&lt;rating name=&quot;metacritic&quot; max=&quot;100&quot; $$3&gt;\1&lt;/rating&gt;&lt;/ratings&gt;" dest="2">
<RegExp input="$$1" output="\1" dest="6">
- <expression clear="yes" noclean="1">(&lt;div class=&quot;metascore_block&quot;.*)</expression>
+ <expression clear="yes" noclean="1">&lt;div\sclass=&quot;metacriticScore\sscore_mixed\stitleReviewBarSubItem&quot;(.*?)&lt;span\sclass=&quot;ghostText&quot;</expression>
</RegExp>
<RegExp input="$$6" output="&lt;value&gt;\1&lt;/value&gt;" dest="4">
- <expression clear="yes">&lt;span itemprop=&quot;ratingValue&quot;&gt;(\d+)&lt;/span&gt;</expression>
+ <expression clear="yes">&lt;span&gt;(\d+)&lt;/span&gt;</expression>
</RegExp>
<RegExp input="$$6" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="4+">
- <expression>&lt;span itemprop=&quot;ratingCount&quot;&gt;(\d+)&lt;/span&gt;</expression>
+ <expression>&gt;(\d+)\suser&lt;/a&gt;</expression>
</RegExp>
<expression noclean="1" clear="yes"/>
</RegExp>
@@ -137,21 +137,21 @@
</ParseMetaCriticRatings>
<GetIMDBPlotById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBPlot&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBPlot&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBPlotById>
<ParseIMDBPlot dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="2">
- <expression fixchars="1" trim="1">&lt;h2&gt;Storyline&lt;/h2&gt;\s+&lt;div\sclass=&quot;inline\scanwrap&quot;\sitemprop=&quot;description&quot;&gt;\s+&lt;p&gt;(.*?)&lt;[^a/]</expression>
+ <expression fixchars="1" trim="1">&lt;h2&gt;Storyline&lt;/h2&gt;\s+&lt;div\sclass=&quot;inline\scanwrap&quot;&gt;\s+&lt;p&gt;\s+&lt;span&gt;(.*?)&lt;/span&gt;</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBPlot>
<GetIMDBTaglineById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBTagline&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBTagline&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBTaglineById>
@@ -165,38 +165,47 @@
</ParseIMDBTagline>
<GetIMDBOutlineById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBOutline&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBOutline&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBOutlineById>
<ParseIMDBOutline dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="2">
- <expression fixchars="1" trim="1">itemprop=&quot;description&quot;&gt;(.+?)&lt;/div&gt;</expression>
+ <expression fixchars="1" trim="1">&lt;div class=&quot;summary_text&quot;&gt;(.+?)&lt;div\sclass</expression>
</RegExp>
<RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="2">
- <expression fixchars="1" trim="1">itemprop=&quot;description&quot;&gt;(.+?)See\sfull\ssummary</expression>
+ <expression fixchars="1" trim="1">&lt;div class=&quot;summary_text&quot;&gt;(.+?)&lt;a\shref=&quot;(.+?)=tt_ov_pl&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="2">
+ <expression fixchars="1" trim="1">&lt;div class=&quot;summary_text&quot;&gt;(.+?)&lt;a\shref=&quot;[^&quot;]*&quot;\s*&gt;Add\sa\sPlot</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBOutline>
<GetIMDBOutlineToPlotById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBOutlineToPlot&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBOutlineToPlot&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBOutlineToPlotById>
<ParseIMDBOutlineToPlot dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="2">
- <expression fixchars="1" trim="1">itemprop=&quot;description&quot;&gt;([^&lt;]+)&lt;</expression>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="2">
+ <expression fixchars="1" trim="1">&lt;div class=&quot;summary_text&quot;&gt;(.+?)&lt;div\sclass</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="2">
+ <expression fixchars="1" trim="1">&lt;div class=&quot;summary_text&quot;&gt;(.+?)&lt;a\shref=&quot;(.+?)=tt_ov_pl&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="2">
+ <expression fixchars="1" trim="1">&lt;div class=&quot;summary_text&quot;&gt;(.+?)&lt;a\shref=&quot;[^&quot;]*&quot;\s*&gt;Add\sa\sPlot</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBOutlineToPlot>
<GetIMDBCastById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBCast&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBCast&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBCastById>
@@ -206,10 +215,10 @@
<expression noclean="1">&lt;table\sclass=&quot;cast_list&quot;&gt;(.*?)&lt;/table&gt;</expression>
</RegExp>
<RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\2\3SX1024_SY1024_.jpg&lt;/thumb&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\5&lt;/role&gt;&lt;/actor&gt;" dest="7">
- <expression repeat="yes" clear="yes" trim="3,4" noclean="1,2">&lt;img[^a]*alt=&quot;([^&quot;]*)&quot;[^&quot;]*&quot;[^&quot;]*&quot;[^s]*src=&quot;(?:[^&quot;]*\.[^&quot;]*&quot;class=&quot;loadlate\shidden\s&quot;\sloadlate=&quot;([^&quot;]*)(_V._))[^&gt;]*.*?ter&quot;&gt;[^&gt;]*&gt;\n\s*(&lt;[^&gt;]*&gt;)?([^&lt;\(]*)?</expression>
+ <expression repeat="yes" clear="yes" trim="3,4" noclean="1,2">&lt;img[^a]*alt=&quot;([^&quot;]*)&quot;[^&quot;]*&quot;[^&quot;]*&quot;[^s]*src=&quot;(?:[^&quot;]*\.[^&quot;]*&quot;\sclass=&quot;loadlate\shidden\s&quot;\sloadlate=&quot;([^&quot;]*)(_V..?_))[^&gt;]*.*?ter&quot;&gt;[^&gt;]*&gt;(&lt;[^&gt;]*&gt;)?([^&lt;\(]*)?</expression>
</RegExp>
<RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;&lt;/thumb&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;/actor&gt;" dest="7+">
- <expression repeat="yes" trim="1,2,3" fixchars="3" noclean="1,2">&lt;img[^a]*alt=&quot;([^&quot;]*)&quot;[^&quot;]*&quot;[^&quot;]*&quot;[^s]*src=&quot;(?:[^&quot;]*\.[^&quot;]*\.png)&quot;\sclass=&quot;.*?&quot;\s/&gt;*.*?ter&quot;&gt;[^&gt;]*&gt;\n\s*(&lt;[^&gt;]*&gt;)?([^&lt;\(]*)?</expression>
+ <expression repeat="yes" trim="1,2,3" fixchars="3" noclean="1,2">&lt;img[^a]*alt=&quot;([^&quot;]*)&quot;[^&quot;]*&quot;[^&quot;]*&quot;[^s]*src=&quot;(?:[^&quot;]*\.[^&quot;]*\.png)&quot;\sclass=&quot;.*?&quot;\s/&gt;*.*?ter&quot;&gt;[^&gt;]*&gt;(&lt;[^&gt;]*&gt;)?([^&lt;\(]*)?</expression>
</RegExp>
<RegExp input="$$7" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;\2&lt;/actor&gt;" dest="2+">
<expression repeat="yes" clear="yes" noclean="1,2,3">&lt;actor&gt;&lt;thumb&gt;(?:(http.*?)|_SX[0-9]+_SY[0-9]+_)?&lt;/thumb&gt;(.*?)&lt;/actor&gt;</expression>
@@ -219,7 +228,7 @@
</ParseIMDBCast>
<GetIMDBDirectorsById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBDirectors&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBDirectors&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBDirectorsById>
@@ -229,14 +238,14 @@
<expression clear="yes" noclean="1">Director(?:s)?:.*?&lt;/h4&gt;(.*?)&lt;div class</expression>
</RegExp>
<RegExp input="$$6" output="&lt;director&gt;\1&lt;/director&gt;" dest="2">
- <expression repeat="yes" fixchars="1" clear="yes">href=&quot;/name[^&gt;]*&gt;[^&lt;]*&lt;[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ <expression repeat="yes" fixchars="yes" clear="yes">href=&quot;/name[^&gt;]*&gt;([^&lt;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBDirectors>
<GetIMDBWritersById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBWriters&quot;&gt;http://akas.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBWriters&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBWritersById>
@@ -246,41 +255,44 @@
<expression clear="yes" noclean="1">Writer(?:s)?:.*?&lt;/h4&gt;(.*?)&lt;div class</expression>
</RegExp>
<RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="2">
- <expression repeat="yes" fixchars="1" clear="yes">href=&quot;/name[^&gt;]*&gt;[^&lt;]*&lt;[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ <expression repeat="yes" fixchars="yes" clear="yes">href=&quot;/name[^&gt;]*&gt;([^&lt;]*)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBWriters>
<GetIMDBFullCastById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-combined.html&quot; function=&quot;ParseIMDBFullCast&quot;&gt;http://akas.imdb.com/title/$$1/combined|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-reference.html&quot; function=&quot;ParseIMDBFullCast&quot;&gt;http://www.imdb.com/title/$$1/reference|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBFullCastById>
<ParseIMDBFullCast dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="6">
- <expression noclean="1">&lt;table class=&quot;cast&quot;&gt;(.*?)&lt;/table&gt;</expression>
+ <expression noclean="1">&lt;table\sclass=&quot;cast_list&quot;&gt;(.*?)&lt;/table&gt;</expression>
</RegExp>
- <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\1_SX1024_SY1024_\2&lt;/thumb&gt;&lt;name&gt;\3&lt;/name&gt;&lt;role&gt;\5&lt;/role&gt;&lt;/actor&gt;" dest="7">
- <expression repeat="yes" clear="yes" fixchars="3,5" trim="3,5" noclean="1,2">&lt;img src="(?:([^&quot;]*\.)[^&quot;]*(\.jpg))?[^&gt;]*[^&quot;]*&quot;nm&quot;&gt;&lt;a href=&quot;[^&quot;]*[^&gt;]*&gt;([^&lt;]*)&lt;[^&quot;]*&quot;ddd&quot;&gt;([^&lt;]&lt;)?[^&quot;]*&quot;char&quot;&gt;(.*?)&lt;/td&gt;</expression>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\2\3SX1024_SY1024_.jpg&lt;/thumb&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\5&lt;/role&gt;&lt;/actor&gt;" dest="7">
+ <expression repeat="yes" clear="yes" trim="3,4" noclean="1,2">&lt;img[^a]*alt=&quot;([^&quot;]*)&quot;[^&quot;]*&quot;[^&quot;]*&quot;[^s]*src=&quot;(?:[^&quot;]*\.[^&quot;]*&quot;\sclass=&quot;loadlate\shidden\s&quot;\sloadlate=&quot;([^&quot;]*)(_V..?_))[^&gt;]*.*?ter&quot;&gt;[^&gt;]*&gt;\n\s*(&lt;[^&gt;]*&gt;)?([^&lt;\(]*)?</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;&lt;/thumb&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;/actor&gt;" dest="7+">
+ <expression repeat="yes" trim="1,2,3" fixchars="3" noclean="1,2">&lt;img[^a]*alt=&quot;([^&quot;]*)&quot;[^&quot;]*&quot;[^&quot;]*&quot;[^s]*src=&quot;(?:[^&quot;]*\.[^&quot;]*\.png)&quot;\sclass=&quot;.*?&quot;\s/&gt;*.*?ter&quot;&gt;[^&gt;]*&gt;\n\s*(&lt;[^&gt;]*&gt;)?([^&lt;\(]*)?</expression>
</RegExp>
<RegExp input="$$7" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;\2&lt;/actor&gt;" dest="2+">
- <expression repeat="yes" clear="yes" noclean="1,2,3">&lt;actor&gt;&lt;thumb&gt;(?:(http.*?)|_SX[0-9]+_SY[0-9]+_)&lt;/thumb&gt;(.*?)&lt;/actor&gt;</expression>
+ <expression repeat="yes" clear="yes" noclean="1,2,3">&lt;actor&gt;&lt;thumb&gt;(?:(http.*?)|_SX[0-9]+_SY[0-9]+_)?&lt;/thumb&gt;(.*?)&lt;/actor&gt;</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBFullCast>
<GetIMDBFullDirectorsById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-combined.html&quot; function=&quot;ParseIMDBFullDirectors&quot;&gt;http://akas.imdb.com/title/$$1/combined|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-reference.html&quot; function=&quot;ParseIMDBFullDirectors&quot;&gt;http://www.imdb.com/title/$$1/reference|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBFullDirectorsById>
<ParseIMDBFullDirectors dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="6">
- <expression clear="yes" noclean="1">Director(?:s)?:.*?&lt;/h5&gt;[^&gt;]*&gt;(.*?)&lt;/div</expression>
+ <expression clear="yes" noclean="1">Director(?:s)?:.*?ipl-inline-list[^&gt;]*&gt;(.*?)&lt;/div</expression>
</RegExp>
<RegExp input="$$6" output="&lt;director&gt;\1&lt;/director&gt;" dest="2">
<expression repeat="yes" fixchars="1">&lt;a href=&quot;/name/[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
@@ -290,14 +302,14 @@
</ParseIMDBFullDirectors>
<GetIMDBFullWritersById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-combined.html&quot; function=&quot;ParseIMDBFullWriters&quot;&gt;http://akas.imdb.com/title/$$1/combined|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-reference.html&quot; function=&quot;ParseIMDBFullWriters&quot;&gt;http://www.imdb.com/title/$$1/reference|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBFullWritersById>
<ParseIMDBFullWriters dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="6">
- <expression noclean="1">Writing\scredits(.*?)name="</expression>
+ <expression noclean="1">Writer(?:s)?:.*?ipl-inline-list[^&gt;]*&gt;(.*?)&lt;/div</expression>
</RegExp>
<RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="2">
<expression repeat="yes" fixchars="1">&lt;a href=&quot;/name/[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
@@ -307,30 +319,30 @@
</ParseIMDBFullWriters>
<GetIMDBThumbsById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-posters.html&quot; function=&quot;ParseIMDBThumbs&quot;&gt;http://akas.imdb.com/title/$$1/posters|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-main.html&quot; function=&quot;ParseIMDBThumbs&quot;&gt;http://www.imdb.com/title/$$1/|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBThumbsById>
<ParseIMDBThumbs dest="5">
<RegExp input="$$6" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="\1_SX1024_SY1024_\2" dest="4">
- <expression noclean="1,2">&lt;a\sname=&quot;poster&quot;.*?src=&quot;(.*?)_S.*?(.jpg)&quot;.*?&lt;/a&gt;</expression>
- </RegExp>
- <RegExp input="$$4" output="&lt;thumb aspect=&quot;poster&quot;&gt;\1&lt;/thumb&gt;" dest="6">
- <expression noclean="1">(.*?_SX[0-9]+_SY[0-9]+_.jpg)</expression>
+ <RegExp input="$$1" output="&lt;thumb aspect=&quot;poster&quot;&gt;\1\2.jpg&lt;/thumb&gt;" dest="6">
+ <expression noclean="1">Poster&quot;\s*src=&quot;(.*?)(_V._)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseIMDBThumbs>
<GetIMDBUSACert dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-combined.html&quot; function=&quot;ParseIMDBUSACert&quot;&gt;http://akas.imdb.com/title/$$1/combined|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-reference.html&quot; function=&quot;ParseIMDBUSACert&quot;&gt;http://www.imdb.com/title/$$1/reference|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBUSACert>
<ParseIMDBUSACert dest="5">
<RegExp input="$$1" output="&lt;details&gt;&lt;mpaa&gt;$INFO[certprefix]\1&lt;/mpaa&gt;&lt;/details&gt;" dest="5">
- <expression>&gt;\s*USA:(P?G|PG-13|R|NC-17)&lt;/a&gt;</expression>
+ <expression>&gt;\s*United\sStates:(TV-(Y7?|P?G|14|MA))&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;details&gt;&lt;mpaa&gt;$INFO[certprefix]\1&lt;/mpaa&gt;&lt;/details&gt;" dest="5">
+ <expression>&gt;\s*United\sStates:(P?G|PG-13|R|NC-17)&lt;/a&gt;</expression>
</RegExp>
<RegExp input="$$1" output="&lt;details&gt;&lt;mpaa&gt;$INFO[certprefix]\1&lt;/mpaa&gt;&lt;/details&gt;" dest="5">
<expression>MPAA&lt;/a&gt;:&lt;/h5&gt;&lt;div\sclass=&quot;info-content&quot;&gt;Rated\s(P?G|PG-13|R|NC-17)</expression>
@@ -338,14 +350,14 @@
</ParseIMDBUSACert>
<GetIMDBCountryCert dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-combined.html&quot; function=&quot;ParseIMDBCountryCert&quot;&gt;http://akas.imdb.com/title/$$1/combined|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-reference.html&quot; function=&quot;ParseIMDBCountryCert&quot;&gt;http://www.imdb.com/title/$$1/reference|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
<RegExp input="$INFO[imdbcertcountry]" output="$$2" dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-combined.html&quot; function=&quot;ParseIMDBUSACert&quot;&gt;http://akas.imdb.com/title/$$1/combined|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="2">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-reference.html&quot; function=&quot;ParseIMDBUSACert&quot;&gt;http://www.imdb.com/title/$$1/reference|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="2">
<expression noclean="1"/>
</RegExp>
- <expression>USA</expression>
+ <expression>United States</expression>
</RegExp>
</GetIMDBCountryCert>
<ParseIMDBCountryCert dest="5">
@@ -355,81 +367,57 @@
</ParseIMDBCountryCert>
<GetIMDBAKATitlesById dest="5">
- <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-combined.html&quot; function=&quot;ParseIMDBAKATitles&quot;&gt;http://akas.imdb.com/title/$$1/combined|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url cache=&quot;$$1-releaseinfo.html&quot; function=&quot;ParseIMDBAKATitles&quot;&gt;http://www.imdb.com/title/$$1/releaseinfo|accept-language=en-us&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1" />
</RegExp>
</GetIMDBAKATitlesById>
<ParseIMDBAKATitles dest="5">
<RegExp input="$$2" output="&lt;details&gt;&lt;title&gt;\1&lt;/title&gt;&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="\1" dest="2">
- <expression fixchars="1">&lt;h1&gt;([^&lt;]*)</expression>
+ <RegExp input="$$1" output="\2" dest="2">
+ <expression>'og:title'\scontent=&quot;(IMDb\s-\s)?(?:&amp;#x22;)?([^&quot;]*?)(?:&amp;#x22;)? \([^\(]*?([0-9]{4})(?:–\s)?\)</expression>
</RegExp>
<RegExp input="$$10" output="\1" dest="4">
- <RegExp input="$$1" output="\2" dest="9">
- <expression fixchars="2">&lt;meta\sname=&quot;title&quot;\scontent=&quot;(IMDb\s-\s)?(?:&amp;#x22;)?([^&quot;]*?)(?:&amp;#x22;)? \([^\(]*?([0-9]{4})(?:–\s)?\)</expression>
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;td&gt;\(original\stitle\)[^&gt;]+&gt;[^&gt;]+&gt;([^&lt;]+)</expression>
</RegExp>
<RegExp input="$$1" output="\1" dest="9">
- <expression fixchars="1">class=&quot;originalTitle&quot;&gt;([^&lt;]*)</expression>
+ <expression>class="originalTitle"&gt;([^&lt;]*)</expression>
</RegExp>
<RegExp input="$$9" output="\1" dest="10">
<expression />
</RegExp>
<RegExp input="$$1" output="\1" dest="11">
- <expression fixchars="1" clear="yes">&gt;\s*?&quot;([^&lt;]+)&quot;[^&lt;]+[&lt;em&gt;]?[^&quot;]+Hong Kong\s[&lt;em&gt;][^&quot;]+English</expression>
- </RegExp>
- <RegExp input="$$11" output="\1" dest="10">
- <expression>(.+)</expression>
- </RegExp>
- <RegExp input="$$1" output="\1" dest="11">
- <expression fixchars="1" clear="yes">&gt;\s*?&quot;([^&lt;]+)&quot;[^&lt;]+[&lt;em&gt;]?[^&quot;]+((Canada)\s(&lt;em&gt;)?\((English|imdb))</expression>
- </RegExp>
- <RegExp input="$$11" output="\1" dest="10">
- <expression>(.+)</expression>
- </RegExp>
- <RegExp input="$$1" output="\1" dest="11">
- <expression fixchars="1" clear="yes">&gt;\s*?&quot;([^&lt;]+)&quot;[^&lt;]+[&lt;em&gt;]?[^&quot;]+(UK(&lt;em&gt;)?&lt;br&gt;)</expression>
+ <expression>'og:title'\scontent=&quot;(IMDb\s-\s)?(?:&amp;#x22;)?([^&quot;]*?)(?:&amp;#x22;)? \([^\(]*?([0-9]{4})(?:–\s)?\)</expression>
</RegExp>
<RegExp input="$$11" output="\1" dest="10">
<expression>(.+)</expression>
</RegExp>
<RegExp input="$$1" output="\1" dest="11">
- <expression fixchars="1" clear="yes">&gt;\s*?&quot;([^&lt;]+)&quot;[^&quot;]+International\s(&lt;em&gt;)?\(English\stitle\)(&lt;/em&gt;)?(,|&lt;)( |b)</expression>
+ <expression clear="yes">&lt;td&gt;Hong Kong\s\(English[^&gt;]+&gt;[^&gt;]+&gt;([^&lt;]+)</expression>
</RegExp>
<RegExp input="$$11" output="\1" dest="10">
<expression>(.+)</expression>
</RegExp>
<RegExp input="$$1" output="\1" dest="11">
- <expression fixchars="1" clear="yes">&gt;\s*?&quot;([^&lt;]+)&quot;[^&quot;]+International\s(&lt;em&gt;)?\(English\stitle\)(&lt;/em&gt;)? (&lt;em&gt;)?\(imdb</expression>
+ <expression clear="yes">&lt;td&gt;Canada\s\(English[^&gt;]+&gt;[^&gt;]+&gt;([^&lt;]+)</expression>
</RegExp>
<RegExp input="$$11" output="\1" dest="10">
<expression>(.+)</expression>
</RegExp>
- <RegExp input="$$1" output="\1" dest="12">
- <expression fixchars="1" clear="yes">&lt;a\shref=&quot;/country/[^&gt;]+&gt;(UK&lt;/a&gt;&lt;/div&gt;)</expression>
- </RegExp>
- <RegExp input="$$12" output="$$9" dest="10">
- <expression>(.+)</expression>
- </RegExp>
- <RegExp input="$$1" output="\1" dest="12">
- <expression clear="yes">&lt;a\shref=&quot;/country/[^&gt;]+&gt;(USA&lt;/a&gt;&lt;/div&gt;)</expression>
- </RegExp>
- <RegExp input="$$12" output="$$9" dest="10">
- <expression>(.+)</expression>
- </RegExp>
<RegExp input="$$1" output="\1" dest="11">
- <expression fixchars="1" clear="yes">&gt;\s*?&quot;([^&lt;]+)&quot;[^&lt;]+[&lt;em&gt;]?[^&quot;]+(USA(&lt;em&gt;)?&lt;br&gt;)</expression>
+ <expression clear="yes">&lt;td&gt;UK&lt;[^&gt;]+&gt;[^&gt;]+&gt;([^&lt;]+)</expression>
</RegExp>
<RegExp input="$$11" output="\1" dest="10">
<expression>(.+)</expression>
</RegExp>
<RegExp input="$$1" output="\1" dest="11">
- <expression fixchars="1" clear="yes">&gt;\s*?&quot;([^&lt;]+)&quot;[^&lt;]+[&lt;em&gt;]?[^&quot;]+((USA)\s(&lt;em&gt;)?\((English|imdb))</expression>
+ <expression clear="yes">&lt;td&gt;World-wide\s\(English\stitle\)&lt;[^&gt;]+&gt;[^&gt;]+&gt;([^&lt;]+)</expression>
</RegExp>
<RegExp input="$$11" output="\1" dest="10">
<expression>(.+)</expression>
</RegExp>
<RegExp input="$$1" output="\1" dest="11">
- <expression fixchars="1" clear="yes">&gt;\s*?&quot;([^&lt;]+)&quot;[^&lt;]+[&lt;em&gt;]?[^&quot;]+((USA)\s(&lt;em&gt;)?\((new\stitle))</expression>
+ <expression clear="yes">&lt;td&gt;USA&lt;[^&gt;]+&gt;[^&gt;]+&gt;([^&lt;]+)</expression>
</RegExp>
<RegExp input="$$11" output="\1" dest="10">
<expression>(.+)</expression>
@@ -440,23 +428,14 @@
<expression>(.+)</expression>
</RegExp>
<RegExp input="$$1" output="\1" dest="4">
- <expression fixchars="1">&gt;\s*?&quot;([^&lt;]+)&quot;[^&lt;]+[&lt;em&gt;]?[^&quot;]+$INFO[imdbakatitles]</expression>
- </RegExp>
- <RegExp input="$$4" output="\1" dest="2">
- <expression>(.+)</expression>
+ <expression>&lt;td&gt;$INFO[imdbakatitles][^&gt;]+&gt;[^&gt;]+&gt;([^&lt;]+)</expression>
</RegExp>
<RegExp input="$$1" output="\1" dest="4">
- <expression fixchars="1">&gt;\s*?&quot;([^&lt;]+)&quot;[^&lt;]+[&lt;em&gt;]?[^&quot;]+$INFO[imdbakatitles]\s(&lt;em&gt;)?\((imdb\sdisplay)</expression>
+ <expression>&lt;td&gt;$INFO[imdbakatitles]&lt;[^&gt;]+&gt;[^&gt;]+&gt;([^&lt;]+)</expression>
</RegExp>
<RegExp input="$$4" output="\1" dest="2">
<expression>(.+)</expression>
</RegExp>
- <RegExp input="$$1" output="\1" dest="5">
- <expression>&lt;a\shref=&quot;/country/[^&gt;]+&gt;($INFO[imdbakatitles])</expression>
- </RegExp>
- <RegExp input="$$5" output="$$9" dest="4">
- <expression>($INFO[imdbakatitles])</expression>
- </RegExp>
<RegExp input="$INFO[imdbakatitles]" output="$$9" dest="4">
<expression>Keep Original</expression>
</RegExp>
diff --git a/addons/metadata.common.musicbrainz.org/addon.xml b/addons/metadata.common.musicbrainz.org/addon.xml
index b73d251fc1..70d133adc2 100644
--- a/addons/metadata.common.musicbrainz.org/addon.xml
+++ b/addons/metadata.common.musicbrainz.org/addon.xml
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="metadata.common.musicbrainz.org"
name="MusicBrainz Scraper Library"
- version="2.1.2"
+ version="2.2.0"
provider-name="Team Kodi">
<requires>
<import addon="xbmc.metadata" version="2.1.0"/>
diff --git a/addons/metadata.common.musicbrainz.org/musicbrainz.xml b/addons/metadata.common.musicbrainz.org/musicbrainz.xml
index 3aba73676a..bdc4221676 100644
--- a/addons/metadata.common.musicbrainz.org/musicbrainz.xml
+++ b/addons/metadata.common.musicbrainz.org/musicbrainz.xml
@@ -91,19 +91,19 @@
</GetMBAlbumTitleByMBID>
<ParseMBAlbumTitle dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;musicBrainzAlbumID&gt;\1&lt;/musicBrainzAlbumID&gt;&lt;title&gt;\2&lt;/title&gt;" dest="2">
+ <RegExp input="$$1" output="&lt;musicbrainzalbumid&gt;\1&lt;/musicbrainzalbumid&gt;&lt;title&gt;\2&lt;/title&gt;" dest="2">
<expression noclean="1">&lt;release id=&quot;([^&quot;]*)&quot;&gt;&lt;title&gt;([^&lt;]*)&lt;</expression>
</RegExp>
- <!--MBID - release group-->
+ <!--MBID - release group-->
<RegExp input="$$1" output="&lt;musicbrainzreleasegroupid&gt;\1&lt;/musicbrainzreleasegroupid&gt;" dest="2+">
<expression noclean="1">&lt;release-group\stype=&quot;[^&quot;]*&quot;\sid=&quot;([^&quot;]*)&quot;</expression>
</RegExp>
<RegExp input="$$1" output="&lt;musicbrainzreleasegroupid&gt;\1&lt;/musicbrainzreleasegroupid&gt;" dest="2+">
<expression noclean="1">&lt;release-group\stype=&quot;[^&quot;]*&quot;\stype-id=&quot;[^&quot;]*&quot;\sid=&quot;([^&quot;]*)&quot;</expression>
- </RegExp>
+ </RegExp>
<RegExp input="$$1" output="&lt;musicbrainzreleasegroupid&gt;\1&lt;/musicbrainzreleasegroupid&gt;" dest="2+">
<expression noclean="1">&lt;release-group\sid=&quot;([^&quot;]*)&quot;\stype=&quot;[^&quot;]*&quot;</expression>
- </RegExp>
+ </RegExp>
<RegExp input="$$1" output="&lt;musicbrainzreleasegroupid&gt;\1&lt;/musicbrainzreleasegroupid&gt;" dest="2+">
<expression noclean="1">&lt;release-group\sid=&quot;([^&quot;]*)&quot;\stype-id=&quot;[^&quot;]*&quot;</expression>
</RegExp>
@@ -112,7 +112,10 @@
</RegExp>
<RegExp input="$$1" output="&lt;musicbrainzreleasegroupid&gt;\1&lt;/musicbrainzreleasegroupid&gt;" dest="2+">
<expression noclean="1">&lt;release-group\stype-id=&quot;[^&quot;]*&quot;\stype=&quot;[^&quot;]*&quot;\sid=&quot;([^&quot;]*)&quot;</expression>
- </RegExp>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;scrapedmbid&gt;\1&lt;/scrapedmbid&gt;" dest="2+">
+ <expression noclean="1" />
+ </RegExp>
<expression noclean="1">(.+)</expression>
</RegExp>
</ParseMBAlbumTitle>
diff --git a/addons/metadata.common.theaudiodb.com/addon.xml b/addons/metadata.common.theaudiodb.com/addon.xml
index b25f09b14c..0969e65f2b 100644
--- a/addons/metadata.common.theaudiodb.com/addon.xml
+++ b/addons/metadata.common.theaudiodb.com/addon.xml
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="metadata.common.theaudiodb.com"
name="TheAudioDb Scraper Library"
- version="1.9.1"
+ version="2.0.0"
provider-name="Team Kodi">
<requires>
<import addon="xbmc.metadata" version="2.1.0"/>
diff --git a/addons/metadata.common.theaudiodb.com/tadb.xml b/addons/metadata.common.theaudiodb.com/tadb.xml
index 5538b21f4e..60912060a7 100644
--- a/addons/metadata.common.theaudiodb.com/tadb.xml
+++ b/addons/metadata.common.theaudiodb.com/tadb.xml
@@ -50,6 +50,118 @@
</RegExp>
</ParseTADBArtistFanarts>
+ <GetTADBArtistClearlogoByID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBArtistClearlogo&quot; cache=&quot;tadb-\1-artist.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/artist.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1" />
+ </RegExp>
+ </GetTADBArtistClearlogoByID>
+ <GetTADBArtistClearlogoByMBID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBArtistClearlogo&quot; cache=&quot;tadb-\1-artist.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/artist-mb.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTADBArtistClearlogoByMBID>
+ <ParseTADBArtistClearlogo dest="5" clearbuffers="no">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="14">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb aspect=&quot;clearlogo&quot; preview=&quot;\1/preview&quot;&gt;\1&lt;/thumb&gt;" dest="14">
+ <expression repeat="yes">strArtistLogo\d?&quot;:&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$14" output="\1" dest="13">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseTADBArtistClearlogo>
+
+ <GetTADBArtistClearartByID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBArtistClearart&quot; cache=&quot;tadb-\1-artist.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/artist.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1" />
+ </RegExp>
+ </GetTADBArtistClearartByID>
+ <GetTADBArtistClearartByMBID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBArtistClearart&quot; cache=&quot;tadb-\1-artist.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/artist-mb.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTADBArtistClearartByMBID>
+ <ParseTADBArtistClearart dest="5" clearbuffers="no">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="14">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb aspect=&quot;clearart&quot; preview=&quot;\1/preview&quot;&gt;\1&lt;/thumb&gt;" dest="14">
+ <expression repeat="yes">strArtistClearart\d?&quot;:&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$14" output="\1" dest="13">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseTADBArtistClearart>
+
+ <GetTADBArtistLandscapeByID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBArtistLandscape&quot; cache=&quot;tadb-\1-artist.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/artist.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1" />
+ </RegExp>
+ </GetTADBArtistLandscapeByID>
+ <GetTADBArtistLandscapeByMBID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBArtistLandscape&quot; cache=&quot;tadb-\1-artist.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/artist-mb.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTADBArtistLandscapeByMBID>
+ <ParseTADBArtistLandscape dest="5" clearbuffers="no">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="14">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb aspect=&quot;landscape&quot; preview=&quot;\1/preview&quot;&gt;\1&lt;/thumb&gt;" dest="14">
+ <expression repeat="yes">strArtistWideThumb\d?&quot;:&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$14" output="\1" dest="13">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseTADBArtistLandscape>
+
+ <GetTADBArtistBannerByID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBArtistBanner&quot; cache=&quot;tadb-\1-artist.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/artist.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1" />
+ </RegExp>
+ </GetTADBArtistBannerByID>
+ <GetTADBArtistBannerByMBID dest="5" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBArtistBanner&quot; cache=&quot;tadb-\1-artist.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/artist-mb.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTADBArtistBannerByMBID>
+ <ParseTADBArtistBanner dest="5" clearbuffers="no">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="" output="" dest="13">
+ <expression />
+ </RegExp>
+ <RegExp input="" output="" dest="14">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb aspect=&quot;banner&quot; preview=&quot;\1/preview&quot;&gt;\1&lt;/thumb&gt;" dest="14">
+ <expression repeat="yes">strArtistBanner\d?&quot;:&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$14" output="\1" dest="13">
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseTADBArtistBanner>
+
<GetTADBBiographyByID dest="5" clearbuffers="no">
<RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBBiography&quot; cache=&quot;tadb-\1-artist.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/artist.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
<expression noclean="1"/>
@@ -575,4 +687,61 @@
</RegExp>
</ParseTADBAlbumThumbs>
+ <GetTADBAlbumBackByID dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBAlbumBack&quot; cache=&quot;tadb-\1-album.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/album.php?m=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTADBAlbumBackByID>
+ <GetTADBAlbumBackByMBID dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBAlbumBack&quot; cache=&quot;tadb-\1-album.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/album-mb.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTADBAlbumBackByMBID>
+ <ParseTADBAlbumBack dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb aspect=&quot;back&quot; preview=&quot;\1/preview&quot;&gt;\1&lt;/thumb&gt;" dest="2">
+ <expression repeat="yes">strAlbumThumbBack\d?&quot;:&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseTADBAlbumBack>
+
+ <GetTADBAlbumDiscartByID dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBAlbumDiscart&quot; cache=&quot;tadb-\1-album.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/album.php?m=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTADBAlbumDiscartByID>
+ <GetTADBAlbumDiscartByMBID dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBAlbumDiscart&quot; cache=&quot;tadb-\1-album.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/album-mb.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTADBAlbumDiscartByMBID>
+ <ParseTADBAlbumDiscart dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb aspect=&quot;discart&quot; preview=&quot;\1/preview&quot;&gt;\1&lt;/thumb&gt;" dest="2">
+ <expression repeat="yes">strAlbumCDart\d?&quot;:&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseTADBAlbumDiscart>
+
+ <GetTADBAlbumSpineByID dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBAlbumSpine&quot; cache=&quot;tadb-\1-album.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/album.php?m=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTADBAlbumSpineByID>
+ <GetTADBAlbumSpineByMBID dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;ParseTADBAlbumSpine&quot; cache=&quot;tadb-\1-album.json&quot;&gt;http://www.theaudiodb.com/api/v1/json/58424d43204d6564696120/album-mb.php?i=\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTADBAlbumSpineByMBID>
+ <ParseTADBAlbumSpine dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb aspect=&quot;spine&quot; preview=&quot;\1/preview&quot;&gt;\1&lt;/thumb&gt;" dest="2">
+ <expression repeat="yes">strAlbumSpine\d?&quot;:&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1" />
+ </RegExp>
+ </ParseTADBAlbumSpine>
+
</scraperfunctions>
diff --git a/addons/metadata.common.themoviedb.org/addon.xml b/addons/metadata.common.themoviedb.org/addon.xml
index 0f5b905349..8000a309f4 100644
--- a/addons/metadata.common.themoviedb.org/addon.xml
+++ b/addons/metadata.common.themoviedb.org/addon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="metadata.common.themoviedb.org"
name="The Movie Database Scraper Library"
- version="2.17.6"
+ version="3.1.7"
provider-name="Team Kodi">
<requires>
<import addon="xbmc.metadata" version="2.1.0"/>
diff --git a/addons/metadata.common.themoviedb.org/tmdb.xml b/addons/metadata.common.themoviedb.org/tmdb.xml
index ed637830c8..722fa466b4 100644
--- a/addons/metadata.common.themoviedb.org/tmdb.xml
+++ b/addons/metadata.common.themoviedb.org/tmdb.xml
@@ -1,88 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<scraperfunctions>
- <GetTMDBCertificationsByIdChain dest="4">
+ <GetTMDBCertificationsByIdChain clearbuffers="no" dest="4"> <!-- Expected chaining format= tmdb_id::certification_country::certification_prefix-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBCertifications&quot; cache=&quot;tmdb-cert-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/releases?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[tmdbcertcountry]&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="\1" dest="16">
+ <expression>.+::(.+)::(.+)?</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="17">
+ <expression>.+::.+::(.+)?</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBCertifications&quot; cache=&quot;tmdb-cert-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/releases?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="5">
+ <expression>(.+)::(.+)::(.+)?</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</GetTMDBCertificationsByIdChain>
<ParseTMDBCertifications dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;mpaa&gt;$INFO[certprefix]\1&lt;/mpaa&gt;" dest="2">
- <expression fixchars="1">certification&quot;:&quot;([^&quot;]*)&quot;,&quot;[^&quot;]*&quot;:&quot;$INFO[tmdbcertcountry]&quot;(.*?),&quot;</expression>
+ <RegExp input="$$1" output="\1" dest="15">
+ <expression fixchars="1">certification&quot;:&quot;([^&quot;]*)&quot;,&quot;[^&quot;]*&quot;:&quot;$$16&quot;(.*?),&quot;</expression>
+ </RegExp>
+ <RegExp input="$$15" output="&lt;mpaa&gt;$$17 \1&lt;/mpaa&gt;" dest="2">
+ <expression>(.+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseTMDBCertifications>
- <GetTMDBTitleByIdChain dest="4">
+ <GetTMDBTitleByIdChain clearbuffers="no" dest="4"> <!-- Expected chaining format= tmdb_id::language-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBTitle&quot; cache=&quot;tmdb-$INFO[language]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[language]&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="\1::\2" dest="16">
+ <expression>(.+)::(.+)</expression>
</RegExp>
- <expression noclean="1" />
- </RegExp>
- </GetTMDBTitleByIdChain>
- <GetTMDBLangTitleByIdChain dest="4">
- <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBTitle&quot; cache=&quot;tmdb-$INFO[tmdbtitlelanguage]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[tmdbtitlelanguage]&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBTitle&quot; cache=&quot;tmdb-\2-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=\2&lt;/url&gt;" dest="5">
+ <expression>(.+)::(.+)</expression>
</RegExp>
- <RegExp input="$INFO[tmdbtitlelanguage]" output="$$2" dest="5">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBTitle&quot; cache=&quot;tmdb-$INFO[tmdbsearchlanguage]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[tmdbsearchlanguage]&lt;/url&gt;" dest="2">
- <expression/>
+ <RegExp input="$$1" output="$$2" dest="5">
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBTitle&quot; cache=&quot;tmdb-en-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=en&lt;/url&gt;" dest="2">
+ <expression>(.+)::</expression>
</RegExp>
- <expression>Keep Original</expression>
+ <expression>(.+)::Keep Original</expression>
</RegExp>
<expression noclean="1"/>
</RegExp>
- </GetTMDBLangTitleByIdChain>
+ </GetTMDBTitleByIdChain>
<ParseTMDBTitle dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="2">
<expression fixchars="1">&quot;title&quot;:&quot;([^&quot;]*)</expression>
</RegExp>
- <RegExp input="$INFO[tmdbtitlelanguage]" output="$$3" dest="2">
+ <RegExp input="$$16" output="$$3" dest="2">
<RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="3">
<expression fixchars="1">&quot;original_title&quot;:&quot;([^&quot;]*)</expression>
</RegExp>
- <expression>Keep Original</expression>
+ <expression>(.+)::Keep Original</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseTMDBTitle>
- <GetTMDBPlotByIdChain clearbuffers="no" dest="4">
+ <GetTMDBPlotByIdChain clearbuffers="no" dest="4"> <!-- Expected chaining format= tmdb_id::language-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
<RegExp input="$$1" output="\1" dest="8">
- <expression clear="yes" noclean="1" />
+ <expression encode="1">(.+)::.+</expression>
</RegExp>
- <RegExp input="$$8" output="&lt;url function=&quot;ParseTMDBPlot&quot; cache=&quot;tmdb-$INFO[language]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[language]&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBPlot&quot; cache=&quot;tmdb-\2-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=\2&lt;/url&gt;" dest="5">
+ <expression>(.+)::(.+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</GetTMDBPlotByIdChain>
- <GetTMDBLangPlotByIdChain clearbuffers="no" dest="4">
- <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="\1" dest="8">
- <expression clear="yes" noclean="1" />
- </RegExp>
- <RegExp input="$$8" output="&lt;url function=&quot;ParseTMDBPlot&quot; cache=&quot;tmdb-$INFO[tmdbplotlanguage]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[tmdbplotlanguage]&lt;/url&gt;" dest="5">
- <expression />
- </RegExp>
- <expression noclean="1" />
- </RegExp>
- </GetTMDBLangPlotByIdChain>
<ParseTMDBPlot dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="9">
<expression clear="yes" fixchars="1">&quot;overview&quot;:&quot;(.*?)&quot;,&quot;</expression>
</RegExp>
- <RegExp input="$$9" output="&lt;url function=&quot;ParseFallbackTMDBPlot&quot; cache=&quot;tmdb-en-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=en&lt;/url&gt;" dest="2">
+ <RegExp input="$$9" output="&lt;url function=&quot;ParseFallbackTMDBPlot&quot; cache=&quot;tmdb-en-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=en&lt;/url&gt;" dest="2">
<expression>^$</expression>
</RegExp>
<RegExp input="$$9" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="2">
@@ -100,34 +93,23 @@
</RegExp>
</ParseFallbackTMDBPlot>
- <GetTMDBTaglineByIdChain clearbuffers="no" dest="4">
+ <GetTMDBTaglineByIdChain clearbuffers="no" dest="4"> <!-- Expected chaining format= tmdb_id::language-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
<RegExp input="$$1" output="\1" dest="8">
- <expression clear="yes" noclean="1" />
+ <expression>(.+)::.+</expression>
</RegExp>
- <RegExp input="$$8" output="&lt;url function=&quot;ParseTMDBTagline&quot; cache=&quot;tmdb-$INFO[language]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[language]&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBTagline&quot; cache=&quot;tmdb-\2-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=\2&lt;/url&gt;" dest="5">
+ <expression>(.+)::(.+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</GetTMDBTaglineByIdChain>
- <GetTMDBLangTaglineByIdChain clearbuffers="no" dest="4">
- <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="\1" dest="8">
- <expression clear="yes" noclean="1" />
- </RegExp>
- <RegExp input="$$8" output="&lt;url function=&quot;ParseTMDBTagline&quot; cache=&quot;tmdb-$INFO[tmdbtaglinelanguage]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[tmdbtaglinelanguage]&lt;/url&gt;" dest="5">
- <expression />
- </RegExp>
- <expression noclean="1" />
- </RegExp>
- </GetTMDBLangTaglineByIdChain>
<ParseTMDBTagline dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="9">
- <expression clear="yes" fixchars="1">&quot;tagline&quot;:&quot;([^&quot;]*)</expression>
+ <expression clear="yes" fixchars="1">&quot;tagline&quot;:&quot;(.*?)&quot;,&quot;</expression>
</RegExp>
- <RegExp input="$$9" output="&lt;url function=&quot;ParseFallbackTMDBTagline&quot; cache=&quot;tmdb-en-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=en&lt;/url&gt;" dest="2">
+ <RegExp input="$$9" output="&lt;url function=&quot;ParseFallbackTMDBTagline&quot; cache=&quot;tmdb-en-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=en&lt;/url&gt;" dest="2">
<expression>^$</expression>
</RegExp>
<RegExp input="$$9" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="2">
@@ -139,18 +121,18 @@
<ParseFallbackTMDBTagline dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="2">
- <expression clear="yes" fixchars="1">&quot;tagline&quot;:&quot;([^&quot;]*)</expression>
+ <expression clear="yes" fixchars="1">&quot;tagline&quot;:&quot;(.*?)&quot;,&quot;</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</ParseFallbackTMDBTagline>
- <GetTMDBTagsByIdChain clearbuffers="no" dest="4">
+ <GetTMDBTagsByIdChain clearbuffers="no" dest="4"> <!-- Expected chaining format= tmdb_id-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
<RegExp input="$$1" output="\1" dest="8">
<expression clear="yes" noclean="1" />
</RegExp>
- <RegExp input="$$8" output="&lt;url function=&quot;ParseTMDBTags&quot; &gt;https://api.tmdb.org/3/movie/\1/keywords?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="5">
+ <RegExp input="$$8" output="&lt;url function=&quot;ParseTMDBTags&quot; &gt;https://api.tmdb.org/3/movie/\1/keywords?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="5">
<expression />
</RegExp>
<expression noclean="1" />
@@ -165,57 +147,114 @@
</RegExp>
</ParseTMDBTags>
- <GetTMDBSetByIdChain clearbuffers="no" dest="4">
+ <GetTMDBSetByIdChain clearbuffers="no" dest="4"> <!-- Expected chaining format= tmdb_id::language-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
<RegExp input="$$1" output="\1" dest="8">
- <expression clear="yes" noclean="1" />
+ <expression>(.+)::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\2" dest="10">
+ <expression>(.+)::(.+)</expression>
</RegExp>
- <RegExp input="$$8" output="&lt;url function=&quot;ParseTMDBSet&quot; cache=&quot;tmdb-$INFO[language]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[language]&lt;/url&gt;" dest="5">
+ <RegExp input="$$8" output="&lt;url function=&quot;GetTMDBSetID&quot; cache=&quot;tmdb-$$10-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=$$10&lt;/url&gt;" dest="5">
<expression />
</RegExp>
<expression noclean="1" />
</RegExp>
</GetTMDBSetByIdChain>
- <GetTMDBLangSetByIdChain clearbuffers="no" dest="4">
- <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="\1" dest="8">
- <expression clear="yes" noclean="1" />
+ <GetTMDBSetID dest="5" clearbuffers="no">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression clear="yes" noclean="1">&quot;belongs_to_collection&quot;:\{&quot;id&quot;:([0-9]+),&quot;name&quot;:&quot;([^&quot;]*)</expression>
</RegExp>
- <RegExp input="$$8" output="&lt;url function=&quot;ParseTMDBSet&quot; cache=&quot;tmdb-$INFO[tmdbsetlanguage]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[tmdbsetlanguage]&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$9" output="&lt;url function=&quot;ParseTMDBBaseImageURL&quot; cache=&quot;tmdb-config.json&quot;&gt;https://api.tmdb.org/3/configuration?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="2">
+ <expression>(.+)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;url function=&quot;ParseTMDBSetOutline&quot; cache=&quot;tmdbset-$$10-\1.json&quot;&gt;https://api.tmdb.org/3/collection/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=$$10&amp;amp;append_to_response=images&amp;amp;include_image_language=$$10,en,null&lt;/url&gt;" dest="2+">
+ <expression>(.+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
- </GetTMDBLangSetByIdChain>
- <ParseTMDBSet dest="5">
+ </GetTMDBSetID>
+ <ParseTMDBSetOutline dest="5" clearbuffers="no">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="\1" dest="9">
- <expression clear="yes" noclean="1">&quot;belongs_to_collection&quot;:\{&quot;id&quot;:[0-9]+,&quot;name&quot;:&quot;([^&quot;]*)</expression>
+ <RegExp input="$$4" output="&lt;set&gt;\1&lt;/set&gt;$$13$$14" dest="2">
+ <RegExp input="$$1" output="\1" dest="11">
+ <expression noclean="1">&quot;id&quot;:[0-9]+,&quot;name&quot;:&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$11" output="&lt;name&gt;\1&lt;/name&gt;" dest="4">
+ <expression>(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&quot;id&quot;:([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression fixchars="1">&quot;id&quot;:[0-9]+,&quot;name&quot;:&quot;[^&quot;]*&quot;,&quot;overview&quot;:&quot;(.*?)&quot;,&quot;</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;overview&gt;\1&lt;/overview&gt;" dest="4+">
+ <expression>(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression clear="yes" noclean="1">&quot;posters&quot;:\[\{([^\]]*)</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb aspect=&quot;set&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" clear="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)[^:]*:[^:]*:&quot;$$10</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb aspect=&quot;set&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)[^:]*:[^:]*:&quot;en</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb aspect=&quot;set&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)[^:]*:[^:]*:null</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression clear="yes" noclean="1">&quot;backdrops&quot;:\[\{([^\]]*)</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb aspect=&quot;setfanart&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="14">
+ <expression clear="yes" repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1" />
</RegExp>
- <RegExp input="$$9" output="&lt;url function=&quot;ParseFallbackTMDBSet&quot; cache=&quot;tmdb-en-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=en&lt;/url&gt;" dest="2">
+ <RegExp input="$$9" output="&lt;url function=&quot;ParseFallbackTMDBSetOutline&quot; cache=&quot;tmdbset-en-$$6.json&quot;&gt;https://api.tmdb.org/3/collection/$$6?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=en&amp;amp;append_to_response=images&amp;amp;include_image_language=$$10,en,null&lt;/url&gt;" dest="2">
<expression>^$</expression>
</RegExp>
- <RegExp input="$$9" output="&lt;set&gt;\1&lt;/set&gt;" dest="2">
- <expression>(.+)</expression>
- </RegExp>
<expression noclean="1" />
</RegExp>
- </ParseTMDBSet>
- <ParseFallbackTMDBSet dest="5">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="&lt;set&gt;\1&lt;/set&gt;" dest="2">
- <expression noclean="1">&quot;belongs_to_collection&quot;:\{&quot;id&quot;:[0-9]+,&quot;name&quot;:&quot;([^&quot;]*)</expression>
+ </ParseTMDBSetOutline>
+ <ParseFallbackTMDBSetOutline dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;&lt;set&gt;\1&lt;/set&gt;$$13$$14&lt;/details&gt;" dest="5">
+ <RegExp input="$$11" output="&lt;name&gt;\1&lt;/name&gt;" dest="2">
+ <expression>(.+)</expression>
</RegExp>
+ <RegExp input="$$1" output="&lt;overview&gt;\1&lt;/overview&gt;" dest="2+">
+ <expression noclean="1">&quot;id&quot;:[0-9]+,&quot;name&quot;:&quot;[^&quot;]*&quot;,&quot;overview&quot;:&quot;(.*?)&quot;,&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression clear="yes" noclean="1">&quot;posters&quot;:\[\{([^\]]*)</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb aspect=&quot;set&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="13">
+ <expression repeat="yes" clear="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)[^:]*:[^:]*:&quot;$$10</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb aspect=&quot;set&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)[^:]*:[^:]*:&quot;en</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb aspect=&quot;set&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="13+">
+ <expression repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)[^:]*:[^:]*:null</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression clear="yes" noclean="1">&quot;backdrops&quot;:\[\{([^\]]*)</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb aspect=&quot;setfanart&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="14">
+ <expression clear="yes" repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)</expression>
+ </RegExp>
<expression noclean="1" />
</RegExp>
- </ParseFallbackTMDBSet>
+ </ParseFallbackTMDBSetOutline>
- <GetTMDBCastByIdChain dest="4">
+ <GetTMDBCastByIdChain dest="4"> <!-- Expected chaining format= tmdb_id-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBBaseImageURL&quot; cache=&quot;tmdb-config.json&quot;&gt;https://api.tmdb.org/3/configuration?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBBaseImageURL&quot; cache=&quot;tmdb-config.json&quot;&gt;https://api.tmdb.org/3/configuration?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="5">
<expression />
</RegExp>
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBCast&quot; cache=&quot;tmdb-cast-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/casts?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="5+">
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBCast&quot; cache=&quot;tmdb-cast-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/casts?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="5+">
<expression />
</RegExp>
<expression noclean="1" />
@@ -236,9 +275,9 @@
</RegExp>
</ParseTMDBCast>
- <GetTMDBDirectorsByIdChain dest="4">
+ <GetTMDBDirectorsByIdChain dest="4"> <!-- Expected chaining format= tmdb_id-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBDirectors&quot; cache=&quot;tmdb-cast-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/casts?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBDirectors&quot; cache=&quot;tmdb-cast-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/casts?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="5">
<expression />
</RegExp>
<expression noclean="1" />
@@ -256,9 +295,9 @@
</RegExp>
</ParseTMDBDirectors>
- <GetTMDBWitersByIdChain dest="4">
+ <GetTMDBWitersByIdChain dest="4"> <!-- Expected chaining format= tmdb_id-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBWriters&quot; cache=&quot;tmdb-cast-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/casts?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBWriters&quot; cache=&quot;tmdb-cast-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/casts?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="5">
<expression />
</RegExp>
<expression noclean="1" />
@@ -276,22 +315,14 @@
</RegExp>
</ParseTMDBWriters>
- <GetTMDBGenresByIdChain dest="4">
+ <GetTMDBGenresByIdChain dest="4"> <!-- Expected chaining format= tmdb_id::language-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBGenres&quot; cache=&quot;tmdb-$INFO[language]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[language]&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBGenres&quot; cache=&quot;tmdb-\2-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=\2&lt;/url&gt;" dest="5">
+ <expression>(.+)::(.+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</GetTMDBGenresByIdChain>
- <GetTMDBLangGenresByIdChain dest="4">
- <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBGenres&quot; cache=&quot;tmdb-$INFO[tmdbgenreslanguage]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[tmdbgenreslanguage]&lt;/url&gt;" dest="5">
- <expression />
- </RegExp>
- <expression noclean="1" />
- </RegExp>
- </GetTMDBLangGenresByIdChain>
<ParseTMDBGenres dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="7">
@@ -306,8 +337,14 @@
<GetTMDBRatingByIdChain dest="4"> <!-- Compatibility function for Pre-Krypton versions-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBRating&quot; cache=&quot;tmdb-$INFO[language]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[language]&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="\2" dest="11">
+ <expression>(.+)::(..)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\2" dest="11">
+ <expression>(.+)::([^\|]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBRating&quot; cache=&quot;tmdb-$$11-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=$$11&lt;/url&gt;" dest="5">
+ <expression>^(.+)::</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
@@ -324,9 +361,15 @@
</RegExp>
</ParseTMDBRating>
- <GetTMDBRatingsByIdChain dest="4" clearbuffers="no">
+ <GetTMDBRatingsByIdChain dest="4" clearbuffers="no"> <!-- Expected chaining format= tmdb_id::language_for_caching-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBRatings&quot; cache=&quot;tmdb-$INFO[language]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[language]&lt;/url&gt;" dest="5">
+ <RegExp input="$$1" output="\2" dest="11">
+ <expression>(.+)::(..)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\2" dest="11">
+ <expression>(.+)::([^\|]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBRatings&quot; cache=&quot;tmdb-$$11-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=$$11&lt;/url&gt;" dest="5">
<expression noclean="1">^((tt)?\d+)</expression>
</RegExp>
<RegExp input="$$1" output="default=&quot;true&quot;" dest="3">
@@ -347,10 +390,10 @@
</RegExp>
</ParseTMDBRatings>
- <GetTMDBStudioByIdChain dest="4">
+ <GetTMDBStudioByIdChain dest="4"> <!-- Expected chaining format= tmdb_id::language_for_caching-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBStudio&quot; cache=&quot;tmdb-en-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=en&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBStudio&quot; cache=&quot;tmdb-\2-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=\2&lt;/url&gt;" dest="5">
+ <expression>(.+)::(.+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
@@ -367,10 +410,10 @@
</RegExp>
</ParseTMDBStudio>
- <GetTMDBCountryByIdChain dest="4">
+ <GetTMDBCountryByIdChain dest="4"> <!-- Expected chaining format= tmdb_id::language_for_caching-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBCountry&quot; cache=&quot;tmdb-en-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=en&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBCountry&quot; cache=&quot;tmdb-\2-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=\2&lt;/url&gt;" dest="5">
+ <expression>(.+)::(.+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
@@ -387,22 +430,14 @@
</RegExp>
</ParseTMDBCountry>
- <GetTMDBTrailerByIdChain dest="4">
+ <GetTMDBTrailerByIdChain dest="4"> <!-- Expected chaining format= tmdb_id::language-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBTrailer&quot; cache=&quot;tmdb-trailer-$INFO[language]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/trailers?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[language]&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBTrailer&quot; cache=&quot;tmdb-trailer-\2-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/trailers?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=\2&lt;/url&gt;" dest="5">
+ <expression>(.+)::(.+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
</GetTMDBTrailerByIdChain>
- <GetTMDBLangTrailerByIdChain dest="4">
- <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBTrailer&quot; cache=&quot;tmdb-trailer-$INFO[tmdbtrailerlanguage]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/trailers?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[tmdbtrailerlanguage]&lt;/url&gt;" dest="5">
- <expression />
- </RegExp>
- <expression noclean="1" />
- </RegExp>
- </GetTMDBLangTrailerByIdChain>
<ParseTMDBTrailer dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="8">
@@ -414,7 +449,7 @@
<RegExp input="$$7" output="&lt;trailer&gt;plugin://plugin.video.youtube/?action=play_video&amp;amp;videoid=\1&lt;/trailer&gt;" dest="9">
<expression noclean="1">&quot;source&quot;:&quot;([^&quot;]*)</expression>
</RegExp>
- <RegExp input="$$9" output="&lt;url function=&quot;ParseTMDBEnTrailer&quot; cache=&quot;tmdb-trailer-en-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8/trailers?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=en&lt;/url&gt;" dest="2">
+ <RegExp input="$$9" output="&lt;url function=&quot;ParseTMDBEnTrailer&quot; cache=&quot;tmdb-trailer-en-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8/trailers?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=en&lt;/url&gt;" dest="2">
<expression>^$</expression>
</RegExp>
<RegExp input="$$9" output="$$9" dest="2">
@@ -434,7 +469,7 @@
<RegExp input="$$7" output="&lt;trailer&gt;plugin://plugin.video.youtube/?action=play_video&amp;amp;videoid=\1&lt;/trailer&gt;" dest="9">
<expression noclean="1">&quot;source&quot;:&quot;([^&quot;]*)</expression>
</RegExp>
- <RegExp input="$$9" output="&lt;url function=&quot;ParseTMDBAllTrailer&quot; cache=&quot;tmdb-trailer-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8/trailers?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="5">
+ <RegExp input="$$9" output="&lt;url function=&quot;ParseTMDBAllTrailer&quot; cache=&quot;tmdb-trailer-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8/trailers?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="2">
<expression>^$</expression>
</RegExp>
<RegExp input="$$9" output="$$9" dest="2">
@@ -455,14 +490,17 @@
</RegExp>
</ParseTMDBAllTrailer>
- <GetTMDBFanartByIdChain dest="4">
+ <GetTMDBFanartByIdChain dest="4"> <!-- Expected chaining format= tmdb_id::poster_language-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBBaseImageURL&quot; cache=&quot;tmdb-config.json&quot;&gt;https://api.tmdb.org/3/configuration?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="\2" dest="11">
+ <expression>(.+)::(.+)</expression>
</RegExp>
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBFanart&quot; cache=&quot;tmdb-images-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/images?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="5+">
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBBaseImageURL&quot; cache=&quot;tmdb-config.json&quot;&gt;https://api.tmdb.org/3/configuration?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="5">
<expression />
</RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBFanart&quot; cache=&quot;tmdb-images-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/images?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=$$11&amp;amp;include_image_language=$$11,en,null&lt;/url&gt;" dest="5+">
+ <expression>(.+)::(.+)</expression>
+ </RegExp>
<expression noclean="1" />
</RegExp>
</GetTMDBFanartByIdChain>
@@ -478,116 +516,66 @@
</RegExp>
</ParseTMDBFanart>
- <GetTMDBThumbsByIdChain dest="4">
+ <GetTMDBThumbsByIdChain clearbuffers="no" dest="4"> <!-- Expected chaining format= tmdb_id::language-->
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBBaseImageURL&quot; cache=&quot;tmdb-config.json&quot;&gt;https://api.tmdb.org/3/configuration?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="\2" dest="11">
+ <expression>(.+)::(.+)</expression>
</RegExp>
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBThumbs&quot; cache=&quot;tmdb-images-$INFO[language]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/images?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[language]&lt;/url&gt;" dest="5+">
- <expression />
+ <RegExp input="$$1" output="\1" dest="13">
+ <expression>(.+)::(.+)</expression>
</RegExp>
- <expression noclean="1" />
- </RegExp>
- </GetTMDBThumbsByIdChain>
- <GetTMDBLangThumbsByIdChain dest="4">
- <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBBaseImageURL&quot; cache=&quot;tmdb-config.json&quot;&gt;https://api.tmdb.org/3/configuration?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBBaseImageURL&quot; cache=&quot;tmdb-config.json&quot;&gt;https://api.tmdb.org/3/configuration?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="5">
<expression />
</RegExp>
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBLangThumbs&quot; cache=&quot;tmdb-images-$INFO[tmdbthumblanguage]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/images?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[tmdbthumblanguage]&lt;/url&gt;" dest="5+">
- <expression />
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBThumbs&quot; cache=&quot;tmdb-images-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1/images?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=$$11&amp;amp;include_image_language=$$11,en,null&lt;/url&gt;" dest="5+">
+ <expression>(.+)::(.+)</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
- </GetTMDBLangThumbsByIdChain>
+ </GetTMDBThumbsByIdChain>
<ParseTMDBThumbs clearbuffers="no" dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="\1" dest="8">
- <expression noclean="1">&quot;id&quot;:([0-9]*),</expression>
- </RegExp>
<RegExp input="$$1" output="\1" dest="7">
<expression clear="yes" noclean="1">&quot;posters&quot;:\[\{([^\]]*)</expression>
</RegExp>
<RegExp input="$$7" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="9">
- <expression clear="yes" repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)</expression>
+ <expression repeat="yes" clear="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)[^:]*:[^:]*:&quot;$$11</expression>
</RegExp>
- <RegExp input="$$9" output="$$9" dest="2">
- <expression clear="yes">(.+)</expression>
+ <RegExp input="$$7" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="9+">
+ <expression repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)[^:]*:[^:]*:&quot;en</expression>
</RegExp>
- <RegExp input="$$9" output="$$12" dest="2+">
- <RegExp input="$INFO[language]" output="&lt;url function=&quot;ParseTMDBAllThumbs&quot; cache=&quot;tmdb-images-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8/images?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="12">
- <expression>en</expression>
- </RegExp>
- <expression>^$</expression>
- </RegExp>
- <RegExp input="$INFO[language]" output="&lt;url function=&quot;ParseTMDBEnThumbs&quot; cache=&quot;tmdb-images-en-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8/images?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=en&lt;/url&gt;" dest="2+">
- <expression>^((?!en).)*$</expression>
- </RegExp>
- <expression noclean="1">(.+)</expression>
- </RegExp>
- </ParseTMDBThumbs>
- <ParseTMDBLangThumbs clearbuffers="no" dest="5">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="\1" dest="8">
- <expression noclean="1">&quot;id&quot;:([0-9]*),</expression>
- </RegExp>
- <RegExp input="$$1" output="\1" dest="7">
- <expression clear="yes" noclean="1">&quot;posters&quot;:\[\{([^\]]*)</expression>
- </RegExp>
- <RegExp input="$$7" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="9">
- <expression clear="yes" repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)</expression>
+ <RegExp input="$$7" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="10">
+ <expression repeat="yes" clear="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)[^:]*:[^:]*:null</expression>
</RegExp>
<RegExp input="$$9" output="$$9" dest="2">
- <expression clear="yes">(.+)</expression>
+ <expression>(.+)</expression>
</RegExp>
- <RegExp input="$$9" output="$$12" dest="2+">
- <RegExp input="$INFO[tmdbthumblanguage]" output="&lt;url function=&quot;ParseTMDBAllThumbs&quot; cache=&quot;tmdb-images-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8/images?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="12">
- <expression>en</expression>
- </RegExp>
+ <RegExp input="$$9" output="$$10" dest="2">
<expression>^$</expression>
</RegExp>
- <RegExp input="$INFO[tmdbthumblanguage]" output="&lt;url function=&quot;ParseTMDBEnThumbs&quot; cache=&quot;tmdb-images-en-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8/images?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=en&lt;/url&gt;" dest="2+">
- <expression>^((?!en).)*$</expression>
- </RegExp>
- <expression noclean="1">(.+)</expression>
- </RegExp>
- </ParseTMDBLangThumbs>
- <ParseTMDBEnThumbs clearbuffers="no" dest="5">
- <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
- <RegExp input="$$1" output="\1" dest="8">
- <expression noclean="1">&quot;id&quot;:([0-9]*),</expression>
- </RegExp>
- <RegExp input="$$1" output="\1" dest="7">
- <expression clear="yes" noclean="1">&quot;posters&quot;:\[\{([^\]]*)</expression>
- </RegExp>
- <RegExp input="$$7" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="9">
- <expression repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)</expression>
- </RegExp>
- <RegExp input="$$9" output="$$9" dest="2">
- <expression clear="yes">(.+)</expression>
- </RegExp>
- <RegExp input="$$9" output="&lt;url function=&quot;ParseTMDBAllThumbs&quot; cache=&quot;tmdb-images-$$8.json&quot;&gt;https://api.tmdb.org/3/movie/$$8/images?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&lt;/url&gt;" dest="2">
+ <RegExp input="$$2" output="&lt;url function=&quot;ParseFallbackTMDBThumbs&quot;&gt;https://api.tmdb.org/3/movie/$$13/images?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&lt;/url&gt;" dest="2">
<expression>^$</expression>
</RegExp>
- <expression noclean="1">(.+)</expression>
+ <expression noclean="1" />
</RegExp>
- </ParseTMDBEnThumbs>
- <ParseTMDBAllThumbs dest="5">
+ </ParseTMDBThumbs>
+
+ <ParseFallbackTMDBThumbs dest="5">
<RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
<RegExp input="$$1" output="\1" dest="7">
<expression clear="yes" noclean="1">&quot;posters&quot;:\[\{([^\]]*)</expression>
</RegExp>
<RegExp input="$$7" output="&lt;thumb aspect=&quot;poster&quot; preview=&quot;$$20w500\1&quot;&gt;$$20original\1&lt;/thumb&gt;" dest="2">
- <expression repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)</expression>
+ <expression repeat="yes" noclean="1">&quot;file_path&quot;:&quot;([^&quot;]*)[^:]*:[^:]*:&quot;[^&quot;]*</expression>
</RegExp>
- <expression noclean="1">(.+)</expression>
+ <expression noclean="1" />
</RegExp>
- </ParseTMDBAllThumbs>
+ </ParseFallbackTMDBThumbs>
<ParseTMDBBaseImageURL clearbuffers="no" dest="4">
<RegExp input="$$5" output="&lt;details&gt;$$20&lt;/details&gt;" dest="4">
<RegExp input="$$1" output="\1" dest="20">
- <expression>"images":\{"base_url":"([^"]*)"</expression>
+ <expression>&quot;images&quot;:\{&quot;base_url&quot;:&quot;([^&quot;]*)&quot;</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
@@ -595,8 +583,17 @@
<GetTMDBPremieredByIdChain dest="4">
<RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
- <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBPremiered&quot; cache=&quot;tmdb-$INFO[tmdbtitlelanguage]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=ecbc86c92da237cb9faff6d3ddc4be6d&amp;amp;language=$INFO[tmdbtitlelanguage]&lt;/url&gt;" dest="5">
- <expression />
+ <RegExp input="$$1" output="\2" dest="16">
+ <expression>(.+)::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBPremiered&quot; cache=&quot;tmdb-\2-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=\2&lt;/url&gt;" dest="5">
+ <expression>(.+)::(.+)</expression>
+ </RegExp>
+ <RegExp input="$$16" output="$$2" dest="5">
+ <RegExp input="$$1" output="&lt;url function=&quot;ParseTMDBPremiered&quot; cache=&quot;tmdb-$INFO[tmdbcertcountry]-\1.json&quot;&gt;https://api.tmdb.org/3/movie/\1?api_key=45ab4cebe57ae11c2ee50c87005ddfe8&amp;amp;language=$INFO[tmdbcertcountry]&lt;/url&gt;" dest="2">
+ <expression/>
+ </RegExp>
+ <expression>Keep Original</expression>
</RegExp>
<expression noclean="1" />
</RegExp>
diff --git a/addons/metadata.tvdb.com/addon.xml b/addons/metadata.tvdb.com/addon.xml
index f8faed97af..b39891ef14 100644
--- a/addons/metadata.tvdb.com/addon.xml
+++ b/addons/metadata.tvdb.com/addon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="metadata.tvdb.com"
name="The TVDB"
- version="3.0.7"
+ version="3.0.9"
provider-name="Team Kodi">
<requires>
<import addon="xbmc.metadata" version="2.1.0"/>
diff --git a/addons/metadata.tvdb.com/changelog.txt b/addons/metadata.tvdb.com/changelog.txt
index b7eb058965..7066da2f46 100644
--- a/addons/metadata.tvdb.com/changelog.txt
+++ b/addons/metadata.tvdb.com/changelog.txt
@@ -1,3 +1,9 @@
+[B]3.0.9[/B]
+- Fixed: Character encoding fixes (part 2)
+
+[B]3.0.8[/B]
+- Fixed: Character encoding fixes
+
[B]3.0.7[/B]
- Fixed: Episode list changes
diff --git a/addons/metadata.tvdb.com/tvdb.xml b/addons/metadata.tvdb.com/tvdb.xml
index acd90c6d71..6fc8144d7d 100644
--- a/addons/metadata.tvdb.com/tvdb.xml
+++ b/addons/metadata.tvdb.com/tvdb.xml
@@ -145,6 +145,9 @@
</xsl:stylesheet>
</XSLT>
+ <RegExp input="$$6" output="\1" dest="6">
+ <expression noclean="1" fixchars="1"/>
+ </RegExp>
</GetSearchResultsAuth>
<!-- input : $$1=series html -->
@@ -237,7 +240,7 @@
<RegExp input="$$1" output="&lt;episodeguide&gt;&lt;url post=&quot;yes&quot; cache=&quot;auth.json&quot;&gt;https://api.thetvdb.com/login?{&quot;apikey&quot;:&quot;439DFEBA9D3059C6&quot;,&quot;id&quot;:\1}|Content-Type=application/json&lt;/url&gt;&lt;/episodeguide&gt;" dest="4+">
<expression noclean="1">"id":\s*?(\d+),</expression>
</RegExp>
- <expression noclean="1"/>
+ <expression noclean="1" fixchars="1"/>
</RegExp>
</GetDetails>
<GetFallbackDetails dest="3" clearbuffers="no">
@@ -260,7 +263,7 @@
</RegExp>
<expression>missingplot</expression>
</RegExp>
- <expression noclean="1"/>
+ <expression noclean="1" fixchars="1"/>
</RegExp>
</GetFallbackDetails>
<GetActors dest="3" clearbuffers="no">
@@ -276,7 +279,7 @@
<RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;order&gt;\3&lt;/order&gt;&lt;/actor&gt;" dest="5+">
<expression repeat="yes" fixchars="1,2">"name":\s*?"([^}]+)",\s*?"role":\s*?"([^}]+)",\s*?"sortOrder":\s*?(\d+),\s*?"image":\s*?(?:""|null),</expression>
</RegExp>
- <expression noclean="1"/>
+ <expression noclean="1" fixchars="1"/>
</RegExp>
</ParseActors>
<GetArt dest="3" clearbuffers="no">
@@ -443,7 +446,7 @@
<RegExp input="$$2" output="https://api.thetvdb.com/login?{&quot;apikey&quot;:&quot;439DFEBA9D3059C6&quot;,&quot;id&quot;:\1}|Content-Type=application/json" dest="2">
<expression>http://(?:www\.)?thetvdb\.com/api/.+/series/(\d+)/all/</expression>
</RegExp>
- <expression noclean="1"/>
+ <expression noclean="1" fixchars="1"/>
</RegExp>
</GetEpisodeList>
<GetEpisodeListAuth dest="3" clearbuffers="no">
@@ -483,7 +486,7 @@
</xsl:stylesheet>
</XSLT>
- <expression noclean="1"/>
+ <expression noclean="1" fixchars="1"/>
</RegExp>
</GetEpisodeListAuth>
<LoadEpisodeList dest="4" clearbuffers="no">
@@ -771,7 +774,7 @@
</RegExp>
<expression>(?!^\Q$INFO[fallbacklanguage]\E$)</expression>
</RegExp>
- <expression noclean="1"/>
+ <expression noclean="1" fixchars="1"/>
</RegExp>
</GetEpisodeDetailsAuth>
<GetFallbackEpisodeDetails dest="3" clearbuffers="no">
@@ -797,7 +800,7 @@
<RegExp input="$$10" output="&lt;Episode&gt;\1&lt;/Episode&gt;" dest="13+">
<expression noclean="1"/>
</RegExp>
- <expression noclean="1"/>
+ <expression noclean="1" fixchars="1"/>
</RegExp>
</GetFallbackEpisodeDetails>
<ParseEpisodeDetails dest="4" clearbuffers="no">
@@ -1099,7 +1102,7 @@
</xsl:stylesheet>
</XSLT>
- <expression noclean="1"/>
+ <expression noclean="1" fixchars="1"/>
</RegExp>
</ParseEpisodeDetails>
</scraper>
diff --git a/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.h b/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.h
index 5c3aed373e..9a589e608a 100644
--- a/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.h
+++ b/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.h
@@ -1,16 +1,16 @@
//
-// HIDRemote.h
-// HIDRemote V1.4 (18th February 2015)
+// HIDRemote.m
+// HIDRemote V1.7 (5th September 2018)
//
// Created by Felix Schwarz on 06.04.07.
-// Copyright 2007-2015 IOSPIRIT GmbH. All rights reserved.
+// Copyright 2007-2018 IOSPIRIT GmbH. All rights reserved.
//
// The latest version of this class is available at
// http://www.iospirit.com/developers/hidremote/
//
// ** LICENSE *************************************************************************
//
-// Copyright (c) 2007-2014 IOSPIRIT GmbH (http://www.iospirit.com/)
+// Copyright (c) 2007-2017 IOSPIRIT GmbH (http://www.iospirit.com/)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
@@ -40,7 +40,6 @@
//
// ************************************************************************************
-
// ************************************************************************************
// ********************************** DOCUMENTATION ***********************************
// ************************************************************************************
@@ -67,6 +66,15 @@
#include <Carbon/Carbon.h>
#endif
+#ifndef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+ #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
+ // Enable thread-safe notification handling by default if deploying to OS X >= 10.5
+ #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING 1
+ #else
+ #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING 0
+ #endif
+#endif
+
#include <unistd.h>
#include <mach/mach.h>
#include <sys/types.h>
@@ -81,12 +89,14 @@
#include <IOKit/hidsystem/IOHIDParameter.h>
#include <IOKit/hidsystem/IOHIDShared.h>
-#pragma mark -- Enums / Codes --
+#pragma mark - Enums / Codes
+#ifndef HID_REMOTE_MODE_ENUM
+#define HID_REMOTE_MODE_ENUM 1
typedef enum
{
kHIDRemoteModeNone = 0L,
- kHIDRemoteModeShared, // Share the remote with others - let's you listen to the remote control events as long as no one has an exclusive lock on it
+ kHIDRemoteModeShared, // Share the remote with others - let's you listen to the remote control events as long as noone has an exclusive lock on it
// (RECOMMENDED ONLY FOR SPECIAL PURPOSES)
kHIDRemoteModeExclusive, // Try to acquire an exclusive lock on the remote (NOT RECOMMENDED)
@@ -94,6 +104,7 @@ typedef enum
kHIDRemoteModeExclusiveAuto // Try to acquire an exclusive lock on the remote whenever the application has focus. Temporarily release control over the
// remote when another application has focus (RECOMMENDED)
} HIDRemoteMode;
+#endif /* HID_REMOTE_MODE_ENUM */
typedef enum
{
@@ -161,7 +172,7 @@ typedef enum
@class HIDRemote;
-#pragma mark -- Delegate protocol (mandatory) --
+#pragma mark - Delegate protocol (mandatory)
@protocol HIDRemoteDelegate
// Notification of button events
@@ -178,7 +189,7 @@ typedef enum
newID:(SInt32)newID
forHardwareWithAttributes:(NSMutableDictionary *)attributes;
-// Notification about hardware additions/removals
+// Notification about hardware additions/removals
- (void)hidRemote:(HIDRemote *)hidRemote // Invoked when new hardware was found / added to HIDRemote's pool
foundNewHardwareWithAttributes:(NSMutableDictionary *)attributes;
@@ -192,11 +203,11 @@ typedef enum
// Matching of newly found receiver hardware
- (BOOL)hidRemote:(HIDRemote *)hidRemote // Invoked when new hardware is inspected
- inspectNewHardwareWithService:(io_service_t)service //
+ inspectNewHardwareWithService:(io_service_t)service //
prematchResult:(BOOL)prematchResult; // Return YES if HIDRemote should go on with this hardware and try
- // to use it, or NO if it should not be pursued further.
+ // to use it, or NO if it should not be persued further.
-// Exclusive lock lending
+// Exlusive lock lending
- (BOOL)hidRemote:(HIDRemote *)hidRemote
lendExclusiveLockToApplicationWithInfo:(NSDictionary *)applicationInfo;
@@ -206,11 +217,10 @@ typedef enum
- (BOOL)hidRemote:(HIDRemote *)hidRemote
shouldRetryExclusiveLockWithInfo:(NSDictionary *)applicationInfo;
-@end
-
+@end
-#pragma mark -- Actual header file for class --
+#pragma mark - Actual header file for class
@interface HIDRemote : NSObject
{
// IOMasterPort
@@ -219,73 +229,73 @@ typedef enum
// Notification ports
IONotificationPortRef _notifyPort;
CFRunLoopSourceRef _notifyRLSource;
-
+
// Matching iterator
io_iterator_t _matchingServicesIterator;
-
+
// SecureInput notification
io_object_t _secureInputNotification;
-
+
// Service attributes
NSMutableDictionary *_serviceAttribMap;
-
+
// Mode
HIDRemoteMode _mode;
BOOL _autoRecover;
NSTimer *_autoRecoveryTimer;
-
+
// Delegate
NSObject <HIDRemoteDelegate> *_delegate;
-
+
// Last seen ID and remote model
SInt32 _lastSeenRemoteID;
HIDRemoteModel _lastSeenModel;
SInt32 _lastSeenModelRemoteID;
-
+
// Unused button codes
NSArray *_unusedButtonCodes;
-
+
// Simulate Plus/Minus Hold
BOOL _simulateHoldEvents;
-
+
// SecureEventInput workaround
BOOL _secureEventInputWorkAround;
UInt64 _lastSecureEventInputPIDSum;
uid_t _lastFrontUserSession;
BOOL _lastScreenIsLocked;
-
+
// Exclusive lock lending
BOOL _exclusiveLockLending;
BOOL _sendExclusiveResourceReuseNotification;
NSNumber *_waitForReturnByPID;
NSNumber *_returnToPID;
BOOL _isRestarting;
-
+
// Status notifications
BOOL _sendStatusNotifications;
NSString *_pidString;
-
+
// Status
BOOL _applicationIsTerminating;
BOOL _isStopping;
-
+
// Thread safety
- #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING /* #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING if you're running your HIDRemote instance on a background thread (requires OS X 10.5 or later) */
+ #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING /* #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING if you're running your HIDRemote instance on a background thread (requires OS X 10.5 or later) */
NSThread *_runOnThread;
#endif
}
-#pragma mark -- PUBLIC: Shared HID Remote --
+#pragma mark - PUBLIC: Shared HID Remote
+ (HIDRemote *)sharedHIDRemote;
-#pragma mark -- PUBLIC: System Information --
+#pragma mark - PUBLIC: System Information
+ (BOOL)isCandelairInstalled;
+ (BOOL)isCandelairInstallationRequiredForRemoteMode:(HIDRemoteMode)remoteMode;
+ (SInt32)OSXVersion;
- (HIDRemoteAluminumRemoteSupportLevel)aluminiumRemoteSystemSupportLevel;
-#pragma mark -- PUBLIC: Interface / API --
-- (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode;
+#pragma mark - PUBLIC: Interface / API
+- (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode;
- (void)stopRemoteControl;
- (BOOL)isStarted;
@@ -307,7 +317,7 @@ typedef enum
- (void)setUnusedButtonCodes:(NSArray *)newArrayWithUnusedButtonCodesAsNSNumbers;
- (NSArray *)unusedButtonCodes;
-#pragma mark -- PUBLIC: Expert APIs --
+#pragma mark - PUBLIC: Expert APIs
- (void)setEnableSecureEventInputWorkaround:(BOOL)newEnableSecureEventInputWorkaround;
- (BOOL)enableSecureEventInputWorkaround;
@@ -317,28 +327,28 @@ typedef enum
- (BOOL)isApplicationTerminating;
- (BOOL)isStopping;
-#pragma mark -- PRIVATE: HID Event handling --
+#pragma mark - PRIVATE: HID Event handling
- (void)_handleButtonCode:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed hidAttribsDict:(NSMutableDictionary *)hidAttribsDict;
- (void)_sendButtonCode:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed hidAttribsDict:(NSMutableDictionary *)hidAttribsDict;
- (void)_hidEventFor:(io_service_t)hidDevice from:(IOHIDQueueInterface **)interface withResult:(IOReturn)result;
-#pragma mark -- PRIVATE: Service setup and destruction --
+#pragma mark - PRIVATE: Service setup and destruction
- (BOOL)_prematchService:(io_object_t)service;
- (HIDRemoteButtonCode)buttonCodeForUsage:(unsigned int)usage usagePage:(unsigned int)usagePage;
- (BOOL)_setupService:(io_object_t)service;
- (void)_destructService:(io_object_t)service;
-#pragma mark -- PRIVATE: Distributed notifications handling --
+#pragma mark - PRIVATE: Distributed notifiations handling
- (void)_postStatusWithAction:(NSString *)action;
- (void)_handleNotifications:(NSNotification *)notification;
- (void)_setSendStatusNotifications:(BOOL)doSend;
- (BOOL)_sendStatusNotifications;
-#pragma mark -- PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto --
+#pragma mark - PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto
- (void)_appStatusChanged:(NSNotification *)notification;
- (void)_delayedAutoRecovery:(NSTimer *)aTimer;
-#pragma mark -- PRIVATE: Notification handling --
+#pragma mark - PRIVATE: Notification handling
- (void)_serviceMatching:(io_iterator_t)iterator;
- (void)_serviceNotificationFor:(io_service_t)service messageType:(natural_t)messageType messageArgument:(void *)messageArgument;
- (void)_updateSessionInformation;
@@ -346,12 +356,12 @@ typedef enum
@end
-#pragma mark -- Information attribute keys --
+#pragma mark - Information attribute keys
extern NSString *kHIDRemoteManufacturer;
extern NSString *kHIDRemoteProduct;
extern NSString *kHIDRemoteTransport;
-#pragma mark -- Internal/Expert attribute keys (AKA: don't touch these unless you really, really, REALLY know what you do) --
+#pragma mark - Internal/Expert attribute keys (AKA: don't touch these unless you really, really, REALLY know what you do)
extern NSString *kHIDRemoteCFPluginInterface;
extern NSString *kHIDRemoteHIDDeviceInterface;
extern NSString *kHIDRemoteCookieButtonCodeLUT;
@@ -365,14 +375,14 @@ extern NSString *kHIDRemoteSimulateHoldEventsOriginButtonCode;
extern NSString *kHIDRemoteAluminumRemoteSupportLevel;
extern NSString *kHIDRemoteAluminumRemoteSupportOnDemand;
-#pragma mark -- Distributed notifications --
+#pragma mark - Distributed notifications
extern NSString *kHIDRemoteDNHIDRemotePing;
extern NSString *kHIDRemoteDNHIDRemoteRetry;
extern NSString *kHIDRemoteDNHIDRemoteStatus;
extern NSString *kHIDRemoteDNHIDRemoteRetryGlobalObject;
-#pragma mark -- Distributed notifications userInfo keys and values --
+#pragma mark - Distributed notifications userInfo keys and values
extern NSString *kHIDRemoteDNStatusHIDRemoteVersionKey;
extern NSString *kHIDRemoteDNStatusPIDKey;
extern NSString *kHIDRemoteDNStatusModeKey;
@@ -385,8 +395,11 @@ extern NSString *kHIDRemoteDNStatusActionStop;
extern NSString *kHIDRemoteDNStatusActionUpdate;
extern NSString *kHIDRemoteDNStatusActionNoNeed;
-#pragma mark -- Driver compatibility flags --
+#pragma mark - Driver compatibility flags
+#ifndef HID_REMOTE_COMPATIBILITY_FLAGS_ENUM
+#define HID_REMOTE_COMPATIBILITY_FLAGS_ENUM 1
typedef enum
{
kHIDRemoteCompatibilityFlagsStandardHIDRemoteDevice = 1L,
} HIDRemoteCompatibilityFlags;
+#endif /* HID_REMOTE_COMPATIBILITY_FLAGS_ENUM */
diff --git a/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.m b/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.m
index 216c3adf6c..acbd16c7f2 100644
--- a/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.m
+++ b/tools/EventClients/Clients/OSXRemote/HIDRemote/HIDRemote.m
@@ -1,32 +1,32 @@
//
// HIDRemote.m
-// HIDRemote V1.4 (18th February 2015)
+// HIDRemote V1.7 (5th September 2018)
//
// Created by Felix Schwarz on 06.04.07.
-// Copyright 2007-2015 IOSPIRIT GmbH. All rights reserved.
+// Copyright 2007-2018 IOSPIRIT GmbH. All rights reserved.
//
// The latest version of this class is available at
// http://www.iospirit.com/developers/hidremote/
//
// ** LICENSE *************************************************************************
//
-// Copyright (c) 2007-2014 IOSPIRIT GmbH (http://www.iospirit.com/)
+// Copyright (c) 2007-2017 IOSPIRIT GmbH (http://www.iospirit.com/)
// All rights reserved.
-//
+//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
-//
+//
// * Redistributions of source code must retain the above copyright notice, this list
// of conditions and the following disclaimer.
-//
+//
// * Redistributions in binary form must reproduce the above copyright notice, this
// list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
-//
+//
// * Neither the name of IOSPIRIT GmbH nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior
// written permission.
-//
+//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
@@ -51,8 +51,39 @@
#import "HIDRemote.h"
+// ARC support
+#if !__has_feature(objc_arc)
+ #define HIDRemoteRetain(object) [object retain]
+ #define HIDRemoteRetained(object) [object retain]
+ #define HIDRemoteRelease(object) [object release]
+ #define HIDRemoteReleaseNil(object) [object release]; object=nil
+ #define HIDRemoteAutoreleased(object) [object autorelease]
+ #define HIDRemoteSuperDealloc(object) [super dealloc]
+
+ #define HIDRemoteAutoreleasePoolOpen() NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ #define HIDRemoteAutoreleasePoolClose() [pool release];
+
+ #define __HIDRemoteBridge
+ #define HIDRemoteBridgingRelease
+ #define HIDRemoteBridgingRetain
+#else /* !__has_feature(objc_arc) */
+ #define HIDRemoteRetain(object)
+ #define HIDRemoteRetained(object) object
+ #define HIDRemoteRelease(object)
+ #define HIDRemoteReleaseNil(object) object=nil
+ #define HIDRemoteAutoreleased(object) object
+ #define HIDRemoteSuperDealloc(object)
+
+ #define HIDRemoteAutoreleasePoolOpen() @autoreleasepool {
+ #define HIDRemoteAutoreleasePoolClose() }
+
+ #define __HIDRemoteBridge __bridge
+ #define HIDRemoteBridgingRelease CFBridgingRelease
+ #define HIDRemoteBridgingRetain CFBridgingRetain
+#endif
+
// Callback Prototypes
-static void HIDEventCallback( void * target,
+static void HIDEventCallback( void * target,
IOReturn result,
void * refcon,
void * sender);
@@ -83,7 +114,7 @@ static HIDRemote *sHIDRemote = nil;
{
sHIDRemote = [[HIDRemote alloc] init];
}
-
+
return (sHIDRemote);
}
@@ -91,10 +122,10 @@ static HIDRemote *sHIDRemote = nil;
{
if ((self = [super init]) != nil)
{
- #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
- _runOnThread = [[NSThread currentThread] retain];
+ #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+ _runOnThread = HIDRemoteRetained([NSThread currentThread]);
#endif
-
+
// Detect application becoming active/inactive
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:) name:NSApplicationDidBecomeActiveNotification object:[NSApplication sharedApplication]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:) name:NSApplicationWillResignActiveNotification object:[NSApplication sharedApplication]];
@@ -102,18 +133,18 @@ static HIDRemote *sHIDRemote = nil;
// Handle distributed notifications
_pidString = [[NSString alloc] initWithFormat:@"%d", getpid()];
-
+
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemotePing object:nil];
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteRetry object:kHIDRemoteDNHIDRemoteRetryGlobalObject];
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteRetry object:_pidString];
// Enabled by default: simulate hold events for plus/minus
_simulateHoldEvents = YES;
-
+
// Enabled by default: work around for a locking issue introduced with Security Update 2008-004 / 10.4.9 and beyond (credit for finding this workaround goes to Martin Kahr)
_secureEventInputWorkAround = YES;
_secureInputNotification = 0;
-
+
// Initialize instance variables
_lastSeenRemoteID = -1;
_lastSeenModel = kHIDRemoteModelUndetermined;
@@ -121,7 +152,7 @@ static HIDRemote *sHIDRemote = nil;
_exclusiveLockLending = NO;
_sendExclusiveResourceReuseNotification = YES;
_applicationIsTerminating = NO;
-
+
// Send status notifications
_sendStatusNotifications = YES;
}
@@ -139,7 +170,7 @@ static HIDRemote *sHIDRemote = nil;
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteRetry object:kHIDRemoteDNHIDRemoteRetryGlobalObject];
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteRetry object:_pidString];
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:nil object:nil]; /* As demanded by the documentation for -[NSDistributedNotificationCenter removeObserver:name:object:] */
-
+
[self stopRemoteControl];
[self setExclusiveLockLendingEnabled:NO];
@@ -148,19 +179,16 @@ static HIDRemote *sHIDRemote = nil;
if (_unusedButtonCodes != nil)
{
- [_unusedButtonCodes release];
- _unusedButtonCodes = nil;
+ HIDRemoteReleaseNil(_unusedButtonCodes);
}
- #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
- [_runOnThread release];
- _runOnThread = nil;
+ #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+ HIDRemoteReleaseNil(_runOnThread);
#endif
- [_pidString release];
- _pidString = nil;
+ HIDRemoteReleaseNil(_pidString);
- [super dealloc];
+ HIDRemoteSuperDealloc();
}
#pragma mark - PUBLIC: System Information
@@ -205,14 +233,14 @@ static HIDRemote *sHIDRemote = nil;
return (YES);
}
break;
-
+
default:
return (NO);
break;
}
break;
}
-
+
return (NO);
}
@@ -228,7 +256,7 @@ static HIDRemote *sHIDRemote = nil;
NSOperatingSystemVersion osVersion;
osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
-
+
sHRGestaltOSXVersion = (SInt32)(0x01000 | ((osVersion.majorVersion-10)<<8) | (osVersion.minorVersion<<4) | osVersion.patchVersion);
#else
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9
@@ -238,7 +266,7 @@ static HIDRemote *sHIDRemote = nil;
if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)])
{
osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
-
+
sHRGestaltOSXVersion = (SInt32)(0x01000 | ((osVersion.majorVersion-10)<<8) | (osVersion.minorVersion<<4) | osVersion.patchVersion);
}
else
@@ -257,7 +285,7 @@ static HIDRemote *sHIDRemote = nil;
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9 */
#endif /* MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9 */
}
-
+
return (sHRGestaltOSXVersion);
}
@@ -266,13 +294,13 @@ static HIDRemote *sHIDRemote = nil;
HIDRemoteAluminumRemoteSupportLevel supportLevel = kHIDRemoteAluminumRemoteSupportLevelNone;
NSEnumerator *attribDictsEnum;
NSDictionary *hidAttribsDict;
-
+
attribDictsEnum = [_serviceAttribMap objectEnumerator];
-
+
while ((hidAttribsDict = [attribDictsEnum nextObject]) != nil)
{
NSNumber *deviceSupportLevel;
-
+
if ((deviceSupportLevel = [hidAttribsDict objectForKey:kHIDRemoteAluminumRemoteSupportLevel]) != nil)
{
if ([deviceSupportLevel intValue] > (int)supportLevel)
@@ -281,7 +309,7 @@ static HIDRemote *sHIDRemote = nil;
}
}
}
-
+
return (supportLevel);
}
@@ -293,16 +321,16 @@ static HIDRemote *sHIDRemote = nil;
kern_return_t kernReturn;
CFMutableDictionaryRef matchDict=NULL;
io_service_t rootService;
-
+
do
{
// Get IOKit master port
kernReturn = IOMasterPort(bootstrap_port, &_masterPort);
if ((kernReturn!=kIOReturnSuccess) || (_masterPort==0)) { break; }
-
+
// Setup notification port
_notifyPort = IONotificationPortCreate(_masterPort);
-
+
if ((_notifyRLSource = IONotificationPortGetRunLoopSource(_notifyPort)) != NULL)
{
CFRunLoopAddSource( CFRunLoopGetCurrent(),
@@ -313,7 +341,7 @@ static HIDRemote *sHIDRemote = nil;
{
break;
}
-
+
// Setup SecureInput notification
if ((hidRemoteMode == kHIDRemoteModeExclusive) || (hidRemoteMode == kHIDRemoteModeExclusiveAuto))
{
@@ -323,10 +351,10 @@ static HIDRemote *sHIDRemote = nil;
rootService,
kIOBusyInterest,
SecureInputNotificationCallback,
- (void *)self,
+ (__HIDRemoteBridge void *)self,
&_secureInputNotification);
if (kernReturn != kIOReturnSuccess) { break; }
-
+
[self _updateSessionInformation];
}
else
@@ -344,39 +372,39 @@ static HIDRemote *sHIDRemote = nil;
kIOFirstMatchNotification,
matchDict, // one reference count consumed by this call
ServiceMatchingCallback,
- (void *) self,
+ (__HIDRemoteBridge void *) self,
&_matchingServicesIterator);
if (kernReturn != kIOReturnSuccess) { break; }
- // Setup serviceAttribMap
+ // Setup serviceAttribMap
_serviceAttribMap = [[NSMutableDictionary alloc] init];
if (_serviceAttribMap==nil) { break; }
-
+
// Phew .. everything went well!
_mode = hidRemoteMode;
CFRelease(matchDict);
-
+
[self _serviceMatching:_matchingServicesIterator];
-
+
[self _postStatusWithAction:kHIDRemoteDNStatusActionStart];
-
+
// Register for system wake notifications
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(_computerDidWake:) name:NSWorkspaceDidWakeNotification object:nil];
-
+
return (YES);
}while(0);
-
+
// An error occured. Do necessary clean up.
if (matchDict!=NULL)
{
CFRelease(matchDict);
matchDict = NULL;
}
-
+
[self stopRemoteControl];
}
-
+
return (NO);
}
@@ -390,31 +418,28 @@ static HIDRemote *sHIDRemote = nil;
if (_autoRecoveryTimer!=nil)
{
[_autoRecoveryTimer invalidate];
- [_autoRecoveryTimer release];
- _autoRecoveryTimer = nil;
+ HIDRemoteReleaseNil(_autoRecoveryTimer);
}
if (_serviceAttribMap!=nil)
{
NSDictionary *cloneDict = [[NSDictionary alloc] initWithDictionary:_serviceAttribMap];
-
+
if (cloneDict!=nil)
{
NSEnumerator *mapKeyEnum = [cloneDict keyEnumerator];
NSNumber *serviceValue;
-
+
while ((serviceValue = [mapKeyEnum nextObject]) != nil)
{
[self _destructService:(io_object_t)[serviceValue unsignedIntValue]];
serviceCount++;
};
-
- [cloneDict release];
- cloneDict = nil;
+
+ HIDRemoteReleaseNil(cloneDict);
}
-
- [_serviceAttribMap release];
- _serviceAttribMap = nil;
+
+ HIDRemoteReleaseNil(_serviceAttribMap);
}
if (_matchingServicesIterator!=0)
@@ -422,7 +447,7 @@ static HIDRemote *sHIDRemote = nil;
IOObjectRelease((io_object_t) _matchingServicesIterator);
_matchingServicesIterator = 0;
}
-
+
if (_secureInputNotification!=0)
{
IOObjectRelease((io_object_t) _secureInputNotification);
@@ -449,8 +474,7 @@ static HIDRemote *sHIDRemote = nil;
if (_returnToPID!=nil)
{
- [_returnToPID release];
- _returnToPID = nil;
+ HIDRemoteReleaseNil(_returnToPID);
}
if (_mode!=kHIDRemoteModeNone)
@@ -464,7 +488,7 @@ static HIDRemote *sHIDRemote = nil;
if (((_mode==kHIDRemoteModeExclusive) || (_mode==kHIDRemoteModeExclusiveAuto)) && (_sendExclusiveResourceReuseNotification==YES) && (_exclusiveLockLending==NO) && (serviceCount>0))
{
_mode = kHIDRemoteModeNone;
-
+
if (!_isRestarting)
{
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry
@@ -481,7 +505,7 @@ static HIDRemote *sHIDRemote = nil;
// Unregister from system wake notifications
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self name:NSWorkspaceDidWakeNotification object:nil];
}
-
+
_mode = kHIDRemoteModeNone;
_isStopping = NO;
}
@@ -498,7 +522,7 @@ static HIDRemote *sHIDRemote = nil;
- (unsigned)activeRemoteControlCount
{
- return ([_serviceAttribMap count]);
+ return ((unsigned)[_serviceAttribMap count]);
}
- (SInt32)lastSeenRemoteControlID
@@ -533,9 +557,9 @@ static HIDRemote *sHIDRemote = nil;
- (void)setUnusedButtonCodes:(NSArray *)newArrayWithUnusedButtonCodesAsNSNumbers
{
- [newArrayWithUnusedButtonCodesAsNSNumbers retain];
- [_unusedButtonCodes release];
-
+ HIDRemoteRetain(newArrayWithUnusedButtonCodesAsNSNumbers);
+ HIDRemoteRelease(_unusedButtonCodes);
+
_unusedButtonCodes = newArrayWithUnusedButtonCodesAsNSNumbers;
[self _postStatusWithAction:kHIDRemoteDNStatusActionUpdate];
@@ -567,7 +591,7 @@ static HIDRemote *sHIDRemote = nil;
if (newExclusiveLockLendingEnabled != _exclusiveLockLending)
{
_exclusiveLockLending = newExclusiveLockLendingEnabled;
-
+
if (_exclusiveLockLending)
{
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteStatus object:nil];
@@ -575,9 +599,8 @@ static HIDRemote *sHIDRemote = nil;
else
{
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteStatus object:nil];
-
- [_waitForReturnByPID release];
- _waitForReturnByPID = nil;
+
+ HIDRemoteReleaseNil(_waitForReturnByPID);
}
}
}
@@ -610,7 +633,7 @@ static HIDRemote *sHIDRemote = nil;
#pragma mark - PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto
- (void)_appStatusChanged:(NSNotification *)notification
{
- #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+ #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only
{
if ([NSThread currentThread] != _runOnThread)
@@ -622,7 +645,7 @@ static HIDRemote *sHIDRemote = nil;
return;
}
}
-
+
if ([[notification name] isEqual:NSApplicationWillResignActiveNotification])
{
if (_mode != kHIDRemoteModeExclusiveAuto)
@@ -630,7 +653,7 @@ static HIDRemote *sHIDRemote = nil;
return;
}
}
-
+
[self performSelector:@selector(_appStatusChanged:) onThread:_runOnThread withObject:notification waitUntilDone:[[notification name] isEqual:NSApplicationWillTerminateNotification]];
return;
}
@@ -642,8 +665,7 @@ static HIDRemote *sHIDRemote = nil;
if (_autoRecoveryTimer!=nil)
{
[_autoRecoveryTimer invalidate];
- [_autoRecoveryTimer release];
- _autoRecoveryTimer = nil;
+ HIDRemoteReleaseNil(_autoRecoveryTimer);
}
if ([[notification name] isEqual:NSApplicationDidBecomeActiveNotification])
@@ -669,11 +691,11 @@ static HIDRemote *sHIDRemote = nil;
_autoRecover = YES;
}
}
-
+
if ([[notification name] isEqual:NSApplicationWillTerminateNotification])
{
_applicationIsTerminating = YES;
-
+
if ([self isStarted])
{
[self stopRemoteControl];
@@ -685,8 +707,7 @@ static HIDRemote *sHIDRemote = nil;
- (void)_delayedAutoRecovery:(NSTimer *)aTimer
{
[_autoRecoveryTimer invalidate];
- [_autoRecoveryTimer release];
- _autoRecoveryTimer = nil;
+ HIDRemoteReleaseNil(_autoRecoveryTimer);
if (_autoRecover)
{
@@ -696,7 +717,7 @@ static HIDRemote *sHIDRemote = nil;
}
-#pragma mark - PRIVATE: Distributed notifications handling
+#pragma mark - PRIVATE: Distributed notifiations handling
- (void)_postStatusWithAction:(NSString *)action
{
if (_sendStatusNotifications)
@@ -722,7 +743,7 @@ static HIDRemote *sHIDRemote = nil;
{
NSString *notificationName;
- #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+ #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only
{
if ([NSThread currentThread] != _runOnThread)
@@ -745,7 +766,7 @@ static HIDRemote *sHIDRemote = nil;
if ([self isStarted])
{
BOOL retry = YES;
-
+
// Ignore our own global retry broadcasts
if ([[notification object] isEqual:kHIDRemoteDNHIDRemoteRetryGlobalObject])
{
@@ -759,7 +780,7 @@ static HIDRemote *sHIDRemote = nil;
}
}
}
-
+
if (retry)
{
if (([self delegate] != nil) &&
@@ -768,25 +789,24 @@ static HIDRemote *sHIDRemote = nil;
retry = [[self delegate] hidRemote:self shouldRetryExclusiveLockWithInfo:[notification userInfo]];
}
}
-
+
if (retry)
{
HIDRemoteMode restartInMode = _mode;
-
+
if (restartInMode != kHIDRemoteModeNone)
{
_isRestarting = YES;
[self stopRemoteControl];
-
- [_returnToPID release];
- _returnToPID = nil;
-
+
+ HIDRemoteReleaseNil(_returnToPID);
+
[self startRemoteControl:restartInMode];
_isRestarting = NO;
-
+
if (restartInMode != kHIDRemoteModeShared)
{
- _returnToPID = [[[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey] retain];
+ _returnToPID = HIDRemoteRetained([[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]);
}
}
}
@@ -794,21 +814,21 @@ static HIDRemote *sHIDRemote = nil;
{
NSNumber *cacheReturnPID = _returnToPID;
- _returnToPID = [[[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey] retain];
+ _returnToPID = HIDRemoteRetained([[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]);
[self _postStatusWithAction:kHIDRemoteDNStatusActionNoNeed];
- [_returnToPID release];
-
+ HIDRemoteRelease(_returnToPID);
+
_returnToPID = cacheReturnPID;
}
}
}
-
+
if (_exclusiveLockLending)
{
if ([notificationName isEqual:kHIDRemoteDNHIDRemoteStatus])
{
NSString *action;
-
+
if ((action = [[notification userInfo] objectForKey:kHIDRemoteDNStatusActionKey]) != nil)
{
if ((_mode == kHIDRemoteModeNone) && (_waitForReturnByPID!=nil))
@@ -818,13 +838,13 @@ static HIDRemote *sHIDRemote = nil;
if ((pidNumber = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]) != nil)
{
returnToPIDNumber = [[notification userInfo] objectForKey:kHIDRemoteDNStatusReturnToPIDKey];
-
+
if ([action isEqual:kHIDRemoteDNStatusActionStart])
{
if ([pidNumber isEqual:_waitForReturnByPID])
{
NSNumber *startMode;
-
+
if ((startMode = [[notification userInfo] objectForKey:kHIDRemoteDNStatusModeKey]) != nil)
{
if ([startMode intValue] == kHIDRemoteModeShared)
@@ -842,9 +862,8 @@ static HIDRemote *sHIDRemote = nil;
{
if ([pidNumber isEqual:_waitForReturnByPID] && ([returnToPIDNumber intValue] == getpid()))
{
- [_waitForReturnByPID release];
- _waitForReturnByPID = nil;
-
+ HIDRemoteReleaseNil(_waitForReturnByPID);
+
if (([self delegate] != nil) &&
([[self delegate] respondsToSelector:@selector(hidRemote:exclusiveLockReleasedByApplicationWithInfo:)]))
{
@@ -866,7 +885,7 @@ static HIDRemote *sHIDRemote = nil;
{
NSNumber *originPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey];
BOOL lendLock = YES;
-
+
if ([originPID intValue] != getpid())
{
if (([self delegate] != nil) &&
@@ -874,16 +893,16 @@ static HIDRemote *sHIDRemote = nil;
{
lendLock = [[self delegate] hidRemote:self lendExclusiveLockToApplicationWithInfo:[notification userInfo]];
}
-
+
if (lendLock)
{
- [_waitForReturnByPID release];
- _waitForReturnByPID = [originPID retain];
-
+ HIDRemoteRelease(_waitForReturnByPID);
+ _waitForReturnByPID = HIDRemoteRetained(originPID);
+
if (_waitForReturnByPID != nil)
{
[self stopRemoteControl];
-
+
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry
object:[NSString stringWithFormat:@"%d", [_waitForReturnByPID intValue]]
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
@@ -918,11 +937,11 @@ static HIDRemote *sHIDRemote = nil;
BOOL serviceMatches = NO;
NSString *ioClass;
NSNumber *candelairHIDRemoteCompatibilityMask;
-
+
if (service != 0)
{
// IOClass matching
- if ((ioClass = (NSString *)IORegistryEntryCreateCFProperty((io_registry_entry_t)service,
+ if ((ioClass = (__HIDRemoteBridge NSString *)IORegistryEntryCreateCFProperty((io_registry_entry_t)service,
CFSTR(kIOClassKey),
kCFAllocatorDefault,
0)) != nil)
@@ -933,14 +952,14 @@ static HIDRemote *sHIDRemote = nil;
CFTypeRef candelairHIDRemoteCompatibilityDevice;
serviceMatches = YES;
-
+
if ((candelairHIDRemoteCompatibilityDevice = IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityDevice"), kCFAllocatorDefault, 0)) != NULL)
{
if (CFEqual(kCFBooleanTrue, candelairHIDRemoteCompatibilityDevice))
{
serviceMatches = NO;
}
-
+
CFRelease (candelairHIDRemoteCompatibilityDevice);
}
}
@@ -950,12 +969,12 @@ static HIDRemote *sHIDRemote = nil;
{
serviceMatches = YES;
}
-
+
CFRelease((CFTypeRef)ioClass);
}
// Match on services that claim compatibility with the HID Remote class (Candelair or third-party) by having a property of CandelairHIDRemoteCompatibilityMask = 1 <Type: Number>
- if ((candelairHIDRemoteCompatibilityMask = (NSNumber *)IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityMask"), kCFAllocatorDefault, 0)) != nil)
+ if ((candelairHIDRemoteCompatibilityMask = (__HIDRemoteBridge NSNumber *)IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityMask"), kCFAllocatorDefault, 0)) != nil)
{
if ([candelairHIDRemoteCompatibilityMask isKindOfClass:[NSNumber class]])
{
@@ -968,7 +987,7 @@ static HIDRemote *sHIDRemote = nil;
serviceMatches = NO;
}
}
-
+
CFRelease((CFTypeRef)candelairHIDRemoteCompatibilityMask);
}
}
@@ -978,7 +997,7 @@ static HIDRemote *sHIDRemote = nil;
{
serviceMatches = [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self inspectNewHardwareWithService:service prematchResult:serviceMatches];
}
-
+
return (serviceMatches);
}
@@ -995,7 +1014,7 @@ static HIDRemote *sHIDRemote = nil;
// Aluminum Remote: Center
buttonCode = (kHIDRemoteButtonCodeCenter|kHIDRemoteButtonCodeAluminumMask);
break;
-
+
case kHIDUsage_Csmr_ModeStep:
// Aluminium Remote: Center Hold
buttonCode = (kHIDRemoteButtonCodeCenterHold|kHIDRemoteButtonCodeAluminumMask);
@@ -1005,11 +1024,11 @@ static HIDRemote *sHIDRemote = nil;
// Aluminum Remote: Play/Pause
buttonCode = (kHIDRemoteButtonCodePlay|kHIDRemoteButtonCodeAluminumMask);
break;
-
+
case kHIDUsage_Csmr_Rewind:
buttonCode = kHIDRemoteButtonCodeLeftHold;
break;
-
+
case kHIDUsage_Csmr_FastForward:
buttonCode = kHIDRemoteButtonCodeRightHold;
break;
@@ -1017,7 +1036,7 @@ static HIDRemote *sHIDRemote = nil;
case kHIDUsage_Csmr_Menu:
buttonCode = kHIDRemoteButtonCodeMenuHold;
break;
-
+
case kHIDUsage_Csmr_VolumeIncrement:
buttonCode = kHIDRemoteButtonCodeUp;
break;
@@ -1027,7 +1046,7 @@ static HIDRemote *sHIDRemote = nil;
break;
}
break;
-
+
case kHIDPage_GenericDesktop:
switch (usage)
{
@@ -1048,15 +1067,27 @@ static HIDRemote *sHIDRemote = nil;
break;
case kHIDUsage_GD_SystemMenuUp:
- buttonCode = kHIDRemoteButtonCodeUp;
+ // macOS 10.13.6 posts kHIDUsage_GD_SystemMenuUp alongside kHIDUsage_Csmr_VolumeIncrement,
+ // which ends up being interpreted as a double press. To avoid this, this usage is ignored
+ // when running under 10.13.6 and later.
+ if ([HIDRemote OSXVersion] < 0x10d6)
+ {
+ buttonCode = kHIDRemoteButtonCodeUp;
+ }
break;
case kHIDUsage_GD_SystemMenuDown:
- buttonCode = kHIDRemoteButtonCodeDown;
+ // macOS 10.13.6 posts kHIDUsage_GD_SystemMenuDown alongside kHIDUsage_Csmr_VolumeDecrement,
+ // which ends up being interpreted as a double press. To avoid this, this usage is ignored
+ // when running under 10.13.6 and later.
+ if ([HIDRemote OSXVersion] < 0x10d6)
+ {
+ buttonCode = kHIDRemoteButtonCodeDown;
+ }
break;
}
break;
-
+
case 0x06: /* Reserved */
switch (usage)
{
@@ -1065,7 +1096,7 @@ static HIDRemote *sHIDRemote = nil;
break;
}
break;
-
+
case 0xFF01: /* Vendor specific */
switch (usage)
{
@@ -1081,7 +1112,7 @@ static HIDRemote *sHIDRemote = nil;
}
break;
}
-
+
return (buttonCode);
}
@@ -1115,52 +1146,52 @@ static HIDRemote *sHIDRemote = nil;
kIOCFPlugInInterfaceID,
&cfPluginInterface,
&score);
-
+
if (kernResult != kIOReturnSuccess)
{
error = [NSError errorWithDomain:NSMachErrorDomain code:kernResult userInfo:nil];
errorCode = 1;
- break;
+ break;
}
-
+
// .. use it to get the HID interface ..
- hResult = (*cfPluginInterface)->QueryInterface( cfPluginInterface,
+ hResult = (*cfPluginInterface)->QueryInterface( cfPluginInterface,
CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122),
(LPVOID)&hidDeviceInterface);
-
+
if ((hResult!=S_OK) || (hidDeviceInterface==NULL))
{
error = [NSError errorWithDomain:NSMachErrorDomain code:hResult userInfo:nil];
errorCode = 2;
- break;
+ break;
}
-
+
// .. then open it ..
switch (_mode)
{
case kHIDRemoteModeShared:
hResult = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeNone);
break;
-
+
case kHIDRemoteModeExclusive:
case kHIDRemoteModeExclusiveAuto:
hResult = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeSeizeDevice);
break;
-
+
default:
goto cleanUp; // Ugh! But there are no "double breaks" available in C AFAIK ..
break;
}
-
+
if (hResult!=S_OK)
{
error = [NSError errorWithDomain:NSMachErrorDomain code:hResult userInfo:nil];
errorCode = 3;
break;
}
-
+
opened = YES;
// .. query the HID elements ..
@@ -1171,7 +1202,7 @@ static HIDRemote *sHIDRemote = nil;
{
error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
errorCode = 4;
-
+
break;
}
@@ -1203,37 +1234,34 @@ static HIDRemote *sHIDRemote = nil;
nil];
{
- UInt32 i, hidElementCnt = CFArrayGetCount(hidElements);
+ UInt32 i, hidElementCnt = (UInt32)CFArrayGetCount(hidElements);
NSMutableDictionary *cookieButtonCodeLUT = [[NSMutableDictionary alloc] init];
NSMutableDictionary *cookieCount = [[NSMutableDictionary alloc] init];
-
+
if ((cookieButtonCodeLUT==nil) || (cookieCount==nil))
{
- [cookieButtonCodeLUT release];
- cookieButtonCodeLUT = nil;
-
- [cookieCount release];
- cookieCount = nil;
+ HIDRemoteReleaseNil(cookieButtonCodeLUT);
+ HIDRemoteReleaseNil(cookieCount);
error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil];
errorCode = 7;
break;
}
-
+
// Analyze the HID elements and find matching elements
for (i=0;i<hidElementCnt;i++)
{
CFDictionaryRef hidDict;
NSNumber *usage, *usagePage, *cookie;
HIDRemoteButtonCode buttonCode = kHIDRemoteButtonCodeNone;
-
+
hidDict = CFArrayGetValueAtIndex(hidElements, i);
-
+
usage = (NSNumber *) CFDictionaryGetValue(hidDict, CFSTR(kIOHIDElementUsageKey));
usagePage = (NSNumber *) CFDictionaryGetValue(hidDict, CFSTR(kIOHIDElementUsagePageKey));
cookie = (NSNumber *) CFDictionaryGetValue(hidDict, CFSTR(kIOHIDElementCookieKey));
-
+
if ((usage!=nil) && (usagePage!=nil) && (cookie!=nil))
{
// Find the button codes for the ID combos
@@ -1245,23 +1273,23 @@ static HIDRemote *sHIDRemote = nil;
#include "HIDRemoteAdditions.h"
#undef _HIDREMOTE_EXTENSIONS_SECTION
#endif /* _HIDREMOTE_EXTENSIONS */
-
+
// Did record match?
if (buttonCode != kHIDRemoteButtonCodeNone)
{
NSString *pairString = [[NSString alloc] initWithFormat:@"%u_%u", [usagePage unsignedIntValue], [usage unsignedIntValue]];
NSNumber *buttonCodeNumber = [[NSNumber alloc] initWithUnsignedInt:(unsigned int)buttonCode];
-
+
#ifdef _HIDREMOTE_EXTENSIONS
// Debug logging code
#define _HIDREMOTE_EXTENSIONS_SECTION 4
#include "HIDRemoteAdditions.h"
#undef _HIDREMOTE_EXTENSIONS_SECTION
#endif /* _HIDREMOTE_EXTENSIONS */
-
+
[cookieCount setObject:buttonCodeNumber forKey:pairString];
[cookieButtonCodeLUT setObject:buttonCodeNumber forKey:cookie];
-
+
(*hidQueueInterface)->addElement(hidQueueInterface,
(IOHIDElementCookie) [cookie unsignedIntValue],
0);
@@ -1273,20 +1301,17 @@ static HIDRemote *sHIDRemote = nil;
#undef _HIDREMOTE_EXTENSIONS_SECTION
#endif /* _HIDREMOTE_EXTENSIONS */
- [buttonCodeNumber release];
- [pairString release];
+ HIDRemoteRelease(buttonCodeNumber);
+ HIDRemoteRelease(pairString);
}
}
}
-
+
// Compare number of *unique* matches (thus the cookieCount dictionary) with required minimum
if ([cookieCount count] < 10)
{
- [cookieButtonCodeLUT release];
- cookieButtonCodeLUT = nil;
-
- [cookieCount release];
- cookieCount = nil;
+ HIDRemoteReleaseNil(cookieButtonCodeLUT);
+ HIDRemoteReleaseNil(cookieCount);
error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil];
errorCode = 8;
@@ -1296,35 +1321,32 @@ static HIDRemote *sHIDRemote = nil;
[hidAttribsDict setObject:cookieButtonCodeLUT forKey:kHIDRemoteCookieButtonCodeLUT];
- [cookieButtonCodeLUT release];
- cookieButtonCodeLUT = nil;
-
- [cookieCount release];
- cookieCount = nil;
+ HIDRemoteReleaseNil(cookieButtonCodeLUT);
+ HIDRemoteReleaseNil(cookieCount);
}
-
+
// Finish setup of IOHIDQueueInterface with CFRunLoop
returnCode = (*hidQueueInterface)->createAsyncEventSource(hidQueueInterface, &queueEventSource);
if ((returnCode != kIOReturnSuccess) || (queueEventSource == NULL))
{
error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
errorCode = 9;
- break;
+ break;
}
-
- returnCode = (*hidQueueInterface)->setEventCallout(hidQueueInterface, HIDEventCallback, (void *)((intptr_t)service), (void *)self);
+
+ returnCode = (*hidQueueInterface)->setEventCallout(hidQueueInterface, HIDEventCallback, (void *)((intptr_t)service), (__HIDRemoteBridge void *)self);
if (returnCode != kIOReturnSuccess)
{
error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
errorCode = 10;
break;
}
-
+
CFRunLoopAddSource( CFRunLoopGetCurrent(),
queueEventSource,
kCFRunLoopCommonModes);
[hidAttribsDict setObject:[NSValue valueWithPointer:(const void *)queueEventSource] forKey:kHIDRemoteCFRunLoopSource];
-
+
returnCode = (*hidQueueInterface)->start(hidQueueInterface);
if (returnCode != kIOReturnSuccess)
{
@@ -1332,7 +1354,7 @@ static HIDRemote *sHIDRemote = nil;
errorCode = 11;
break;
}
-
+
queueStarted = YES;
// Setup device notifications
@@ -1340,7 +1362,7 @@ static HIDRemote *sHIDRemote = nil;
service,
kIOGeneralInterest,
ServiceNotificationCallback,
- self,
+ (__HIDRemoteBridge void *)(self),
&serviceNotification);
if ((returnCode != kIOReturnSuccess) || (serviceNotification==0))
{
@@ -1350,7 +1372,7 @@ static HIDRemote *sHIDRemote = nil;
}
[hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:(unsigned int)serviceNotification] forKey:kHIDRemoteServiceNotification];
-
+
// Retain service
if (IOObjectRetain(service) != kIOReturnSuccess)
{
@@ -1358,13 +1380,13 @@ static HIDRemote *sHIDRemote = nil;
errorCode = 13;
break;
}
-
+
[hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:(unsigned int)service] forKey:kHIDRemoteService];
-
+
// Get some (somewhat optional) infos on the device
{
CFStringRef product, manufacturer, transport;
-
+
if ((product = IORegistryEntryCreateCFProperty( (io_registry_entry_t)service,
(CFStringRef) @"Product",
kCFAllocatorDefault,
@@ -1372,9 +1394,9 @@ static HIDRemote *sHIDRemote = nil;
{
if (CFGetTypeID(product) == CFStringGetTypeID())
{
- [hidAttribsDict setObject:(NSString *)product forKey:kHIDRemoteProduct];
+ [hidAttribsDict setObject:(__HIDRemoteBridge NSString *)product forKey:kHIDRemoteProduct];
}
-
+
CFRelease(product);
}
@@ -1385,9 +1407,9 @@ static HIDRemote *sHIDRemote = nil;
{
if (CFGetTypeID(manufacturer) == CFStringGetTypeID())
{
- [hidAttribsDict setObject:(NSString *)manufacturer forKey:kHIDRemoteManufacturer];
+ [hidAttribsDict setObject:(__HIDRemoteBridge NSString *)manufacturer forKey:kHIDRemoteManufacturer];
}
-
+
CFRelease(manufacturer);
}
@@ -1398,18 +1420,18 @@ static HIDRemote *sHIDRemote = nil;
{
if (CFGetTypeID(transport) == CFStringGetTypeID())
{
- [hidAttribsDict setObject:(NSString *)transport forKey:kHIDRemoteTransport];
+ [hidAttribsDict setObject:(__HIDRemoteBridge NSString *)transport forKey:kHIDRemoteTransport];
}
-
+
CFRelease(transport);
}
}
-
+
// Determine Aluminum Remote support
{
CFNumberRef aluSupport;
HIDRemoteAluminumRemoteSupportLevel supportLevel = kHIDRemoteAluminumRemoteSupportLevelNone;
-
+
if ((_mode == kHIDRemoteModeExclusive) || (_mode == kHIDRemoteModeExclusiveAuto))
{
// Determine if this driver offers on-demand support for the Aluminum Remote (only relevant under OS versions < 10.6.2)
@@ -1421,23 +1443,23 @@ static HIDRemote *sHIDRemote = nil;
// There is => request the driver to enable it for us
if (IORegistryEntrySetCFProperty((io_registry_entry_t)service,
CFSTR("EnableAluminumRemoteSupportForMe"),
- [NSDictionary dictionaryWithObjectsAndKeys:
+ (__HIDRemoteBridge CFTypeRef)([NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithLongLong:(long long)getpid()], @"pid",
[NSNumber numberWithLongLong:(long long)getuid()], @"uid",
- nil]) == kIOReturnSuccess)
+ nil])) == kIOReturnSuccess)
{
if (CFGetTypeID(aluSupport) == CFNumberGetTypeID())
{
- supportLevel = (HIDRemoteAluminumRemoteSupportLevel) [(NSNumber *)aluSupport intValue];
+ supportLevel = (HIDRemoteAluminumRemoteSupportLevel) [(__HIDRemoteBridge NSNumber *)aluSupport intValue];
}
[hidAttribsDict setObject:[NSNumber numberWithBool:YES] forKey:kHIDRemoteAluminumRemoteSupportOnDemand];
}
-
+
CFRelease(aluSupport);
}
}
-
+
if (supportLevel == kHIDRemoteAluminumRemoteSupportLevelNone)
{
if ((aluSupport = IORegistryEntryCreateCFProperty((io_registry_entry_t)service,
@@ -1447,26 +1469,26 @@ static HIDRemote *sHIDRemote = nil;
{
if (CFGetTypeID(aluSupport) == CFNumberGetTypeID())
{
- supportLevel = (HIDRemoteAluminumRemoteSupportLevel) [(NSNumber *)aluSupport intValue];
+ supportLevel = (HIDRemoteAluminumRemoteSupportLevel) [(__HIDRemoteBridge NSNumber *)aluSupport intValue];
}
-
+
CFRelease(aluSupport);
}
else
{
CFStringRef ioKitClassName;
-
+
if ((ioKitClassName = IORegistryEntryCreateCFProperty( (io_registry_entry_t)service,
CFSTR(kIOClassKey),
kCFAllocatorDefault,
0)) != nil)
{
- if ([(NSString *)ioKitClassName isEqual:@"AppleIRController"])
+ if ([(__HIDRemoteBridge NSString *)ioKitClassName isEqual:@"AppleIRController"])
{
if ([HIDRemote OSXVersion] >= 0x1062)
{
// Support for the Aluminum Remote was added only with OS 10.6.2. Previous versions can not distinguish
- // between the Center and the new, separate Play/Pause button. They'll recognize both as presses of the
+ // between the Center and the new, seperate Play/Pause button. They'll recognize both as presses of the
// "Center" button.
//
// You CAN, however, receive Aluminum Remote button presses even under OS 10.5 when using Remote Buddy's
@@ -1476,7 +1498,7 @@ static HIDRemote *sHIDRemote = nil;
supportLevel = kHIDRemoteAluminumRemoteSupportLevelNative;
}
}
-
+
CFRelease(ioKitClassName);
}
}
@@ -1484,24 +1506,23 @@ static HIDRemote *sHIDRemote = nil;
[hidAttribsDict setObject:(NSNumber *)[NSNumber numberWithInt:(int)supportLevel] forKey:kHIDRemoteAluminumRemoteSupportLevel];
}
-
+
// Add it to the serviceAttribMap
[_serviceAttribMap setObject:hidAttribsDict forKey:[NSNumber numberWithUnsignedInt:(unsigned int)service]];
-
+
// And we're done with setup ..
if (([self delegate]!=nil) &&
([[self delegate] respondsToSelector:@selector(hidRemote:foundNewHardwareWithAttributes:)]))
{
[((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self foundNewHardwareWithAttributes:hidAttribsDict];
}
-
- [hidAttribsDict release];
- hidAttribsDict = nil;
-
+
+ HIDRemoteReleaseNil(hidAttribsDict);
+
return(YES);
}while(0);
-
+
cleanUp:
if (([self delegate]!=nil) &&
@@ -1509,7 +1530,7 @@ static HIDRemote *sHIDRemote = nil;
{
if (error!=nil)
{
- error = [NSError errorWithDomain:[error domain]
+ error = [NSError errorWithDomain:[error domain]
code:[error code]
userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:errorCode] forKey:@"InternalErrorCode"]
];
@@ -1517,7 +1538,7 @@ static HIDRemote *sHIDRemote = nil;
[((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self failedNewHardwareWithError:error];
}
-
+
// An error occured or this device is not of interest .. cleanup ..
if (serviceNotification!=0)
{
@@ -1530,7 +1551,7 @@ static HIDRemote *sHIDRemote = nil;
CFRunLoopSourceInvalidate(queueEventSource);
queueEventSource=NULL;
}
-
+
if (hidQueueInterface!=NULL)
{
if (queueStarted)
@@ -1544,16 +1565,15 @@ static HIDRemote *sHIDRemote = nil;
if (hidAttribsDict!=nil)
{
- [hidAttribsDict release];
- hidAttribsDict = nil;
+ HIDRemoteReleaseNil(hidAttribsDict);
}
-
+
if (hidElements!=NULL)
{
CFRelease(hidElements);
hidElements = NULL;
}
-
+
if (hidDeviceInterface!=NULL)
{
if (opened)
@@ -1564,13 +1584,13 @@ static HIDRemote *sHIDRemote = nil;
// opened = NO;
hidDeviceInterface = NULL;
}
-
+
if (cfPluginInterface!=NULL)
{
IODestroyPlugInInterface(cfPluginInterface);
cfPluginInterface = NULL;
}
-
+
return (NO);
}
@@ -1578,14 +1598,14 @@ static HIDRemote *sHIDRemote = nil;
{
NSNumber *serviceValue;
NSMutableDictionary *serviceDict = NULL;
-
+
if ((serviceValue = [NSNumber numberWithUnsignedInt:(unsigned int)service]) == nil)
{
return;
}
-
+
serviceDict = [_serviceAttribMap objectForKey:serviceValue];
-
+
if (serviceDict!=nil)
{
IOHIDDeviceInterface122 **hidDeviceInterface = NULL;
@@ -1605,8 +1625,8 @@ static HIDRemote *sHIDRemote = nil;
cfPluginInterface = (IOCFPlugInInterface **) ([serviceDict objectForKey:kHIDRemoteCFPluginInterface] ? [[serviceDict objectForKey:kHIDRemoteCFPluginInterface] pointerValue] : NULL);
cookieButtonMap = (NSMutableDictionary *) [serviceDict objectForKey:kHIDRemoteCookieButtonCodeLUT];
simulateHoldTimer = (NSTimer *) [serviceDict objectForKey:kHIDRemoteSimulateHoldEventsTimer];
-
- [serviceDict retain];
+
+ HIDRemoteRetain(serviceDict);
[_serviceAttribMap removeObjectForKey:serviceValue];
if (([serviceDict objectForKey:kHIDRemoteAluminumRemoteSupportOnDemand]!=nil) && [[serviceDict objectForKey:kHIDRemoteAluminumRemoteSupportOnDemand] boolValue] && (theService != 0))
@@ -1614,10 +1634,10 @@ static HIDRemote *sHIDRemote = nil;
// We previously requested the driver to enable Aluminum Remote support for us. Tell it to turn it off again - now that we no longer need it
IORegistryEntrySetCFProperty( (io_registry_entry_t)theService,
CFSTR("DisableAluminumRemoteSupportForMe"),
- [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithLongLong:(long long)getpid()], @"pid",
- [NSNumber numberWithLongLong:(long long)getuid()], @"uid",
- nil]);
+ (__HIDRemoteBridge CFTypeRef)([NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithLongLong:(long long)getpid()], @"pid",
+ [NSNumber numberWithLongLong:(long long)getuid()], @"uid",
+ nil]));
}
if (([self delegate]!=nil) &&
@@ -1625,7 +1645,7 @@ static HIDRemote *sHIDRemote = nil;
{
[((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self releasedHardwareWithAttributes:serviceDict];
}
-
+
if (simulateHoldTimer!=nil)
{
[simulateHoldTimer invalidate];
@@ -1642,12 +1662,12 @@ static HIDRemote *sHIDRemote = nil;
queueEventSource,
kCFRunLoopCommonModes);
}
-
+
if ((hidQueueInterface!=NULL) && (cookieButtonMap!=nil))
{
NSEnumerator *cookieEnum = [cookieButtonMap keyEnumerator];
NSNumber *cookie;
-
+
while ((cookie = [cookieEnum nextObject]) != nil)
{
if ((*hidQueueInterface)->hasElement(hidQueueInterface, (IOHIDElementCookie) [cookie unsignedIntValue]))
@@ -1657,31 +1677,31 @@ static HIDRemote *sHIDRemote = nil;
}
};
}
-
+
if (hidQueueInterface!=NULL)
{
(*hidQueueInterface)->stop(hidQueueInterface);
(*hidQueueInterface)->dispose(hidQueueInterface);
(*hidQueueInterface)->Release(hidQueueInterface);
}
-
+
if (hidDeviceInterface!=NULL)
{
(*hidDeviceInterface)->close(hidDeviceInterface);
(*hidDeviceInterface)->Release(hidDeviceInterface);
}
-
+
if (cfPluginInterface!=NULL)
{
IODestroyPlugInInterface(cfPluginInterface);
}
-
+
if (theService!=0)
{
IOObjectRelease(theService);
}
- [serviceDict release];
+ HIDRemoteRelease(serviceDict);
}
}
@@ -1692,11 +1712,11 @@ static HIDRemote *sHIDRemote = nil;
NSMutableDictionary *hidAttribsDict;
NSTimer *shTimer;
NSNumber *shButtonCode;
-
+
if ((hidAttribsDict = (NSMutableDictionary *)[aTimer userInfo]) != nil)
{
if (((shTimer = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsTimer]) != nil) &&
- ((shButtonCode = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsOriginButtonCode]) != nil))
+ ((shButtonCode = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsOriginButtonCode]) != nil))
{
[shTimer invalidate];
[hidAttribsDict removeObjectForKey:kHIDRemoteSimulateHoldEventsTimer];
@@ -1711,7 +1731,7 @@ static HIDRemote *sHIDRemote = nil;
switch (buttonCode)
{
case kHIDRemoteButtonCodeIDChanged:
- // Do nothing, this is handled separately
+ // Do nothing, this is handled seperately
break;
case kHIDRemoteButtonCodeUp:
@@ -1726,17 +1746,17 @@ static HIDRemote *sHIDRemote = nil;
if (isPressed)
{
[hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:buttonCode] forKey:kHIDRemoteSimulateHoldEventsOriginButtonCode];
-
+
if ((shTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.7] interval:0.1 target:self selector:@selector(_simulateHoldEvent:) userInfo:hidAttribsDict repeats:NO]) != nil)
{
[hidAttribsDict setObject:shTimer forKey:kHIDRemoteSimulateHoldEventsTimer];
-
+
// Using CFRunLoopAddTimer instead of [[NSRunLoop currentRunLoop] addTimer:.. for consistency with run loop modes.
// The kCFRunLoopCommonModes counterpart NSRunLoopCommonModes is only available in 10.5 and later, whereas this code
// is designed to be also compatible with 10.4. CFRunLoopTimerRef is "toll-free-bridged" with NSTimer since 10.0.
CFRunLoopAddTimer(CFRunLoopGetCurrent(), (CFRunLoopTimerRef)shTimer, kCFRunLoopCommonModes);
-
- [shTimer release];
+
+ HIDRemoteRelease(shTimer);
break;
}
@@ -1745,7 +1765,7 @@ static HIDRemote *sHIDRemote = nil;
{
shTimer = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsTimer];
shButtonCode = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsOriginButtonCode];
-
+
if ((shTimer!=nil) && (shButtonCode!=nil))
{
[self _sendButtonCode:(HIDRemoteButtonCode)[shButtonCode unsignedIntValue] isPressed:YES hidAttribsDict:hidAttribsDict];
@@ -1762,10 +1782,10 @@ static HIDRemote *sHIDRemote = nil;
[hidAttribsDict removeObjectForKey:kHIDRemoteSimulateHoldEventsTimer];
[hidAttribsDict removeObjectForKey:kHIDRemoteSimulateHoldEventsOriginButtonCode];
-
+
break;
}
-
+
default:
[self _sendButtonCode:buttonCode isPressed:isPressed hidAttribsDict:hidAttribsDict];
break;
@@ -1807,34 +1827,34 @@ static HIDRemote *sHIDRemote = nil;
}
break;
}
-
+
// As soon as we have received a code that's unique to the Aluminum Remote, we can tell kHIDRemoteButtonCodePlayHold and kHIDRemoteButtonCodeCenterHold apart.
// Prior to that, a long press of the new "Play" button will be submitted as a "kHIDRemoteButtonCodeCenterHold", not a "kHIDRemoteButtonCodePlayHold" code.
if ((buttonCode == kHIDRemoteButtonCodeCenterHold) && (_lastSeenModel == kHIDRemoteModelAluminum))
{
buttonCode = kHIDRemoteButtonCodePlayHold;
}
-
+
[((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self eventWithButton:(buttonCode & (~kHIDRemoteButtonCodeAluminumMask)) isPressed:isPressed fromHardwareWithAttributes:hidAttribsDict];
}
}
- (void)_hidEventFor:(io_service_t)hidDevice from:(IOHIDQueueInterface **)interface withResult:(IOReturn)result
{
- NSMutableDictionary *hidAttribsDict = [[[_serviceAttribMap objectForKey:[NSNumber numberWithUnsignedInt:(unsigned int)hidDevice]] retain] autorelease];
-
+ NSMutableDictionary *hidAttribsDict = HIDRemoteAutoreleased(HIDRemoteRetained([_serviceAttribMap objectForKey:[NSNumber numberWithUnsignedInt:(unsigned int)hidDevice]]));
+
if (hidAttribsDict!=nil)
{
IOHIDQueueInterface **queueInterface = NULL;
-
+
queueInterface = [[hidAttribsDict objectForKey:kHIDRemoteHIDQueueInterface] pointerValue];
-
+
if (interface == queueInterface)
{
NSNumber *lastButtonPressedNumber = nil;
HIDRemoteButtonCode lastButtonPressed = kHIDRemoteButtonCodeNone;
NSMutableDictionary *cookieButtonMap = nil;
-
+
cookieButtonMap = [hidAttribsDict objectForKey:kHIDRemoteCookieButtonCodeLUT];
if ((lastButtonPressedNumber = [hidAttribsDict objectForKey:kHIDRemoteLastButtonPressed]) != nil)
@@ -1846,27 +1866,27 @@ static HIDRemote *sHIDRemote = nil;
{
IOHIDEventStruct hidEvent;
AbsoluteTime supportedTime = { 0,0 };
-
+
result = (*queueInterface)->getNextEvent( queueInterface,
&hidEvent,
supportedTime,
0);
-
+
if (result == kIOReturnSuccess)
{
NSNumber *buttonCodeNumber = [cookieButtonMap objectForKey:[NSNumber numberWithUnsignedInt:(unsigned int) hidEvent.elementCookie]];
-
+
#ifdef _HIDREMOTE_EXTENSIONS
// Debug logging code
#define _HIDREMOTE_EXTENSIONS_SECTION 5
#include "HIDRemoteAdditions.h"
#undef _HIDREMOTE_EXTENSIONS_SECTION
#endif /* _HIDREMOTE_EXTENSIONS */
-
+
if (buttonCodeNumber!=nil)
{
HIDRemoteButtonCode buttonCode = [buttonCodeNumber unsignedIntValue];
-
+
if (hidEvent.value == 0)
{
if (buttonCode == lastButtonPressed)
@@ -1891,21 +1911,21 @@ static HIDRemote *sHIDRemote = nil;
{
[((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self remoteIDChangedOldID:_lastSeenRemoteID newID:hidEvent.value forHardwareWithAttributes:hidAttribsDict];
}
-
+
_lastSeenRemoteID = hidEvent.value;
_lastSeenModel = kHIDRemoteModelUndetermined;
}
-
+
[self _handleButtonCode:buttonCode isPressed:YES hidAttribsDict:hidAttribsDict];
lastButtonPressed = buttonCode;
}
}
}
};
-
+
[hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:lastButtonPressed] forKey:kHIDRemoteLastButtonPressed];
}
-
+
#ifdef _HIDREMOTE_EXTENSIONS
// Debug logging code
#define _HIDREMOTE_EXTENSIONS_SECTION 6
@@ -1940,24 +1960,24 @@ static HIDRemote *sHIDRemote = nil;
{
NSArray *consoleUsersArray;
io_service_t rootService;
-
+
if (_masterPort==0) { return; }
-
+
if ((rootService = IORegistryGetRootEntry(_masterPort)) != 0)
{
- if ((consoleUsersArray = (NSArray *)IORegistryEntryCreateCFProperty((io_registry_entry_t)rootService, CFSTR("IOConsoleUsers"), kCFAllocatorDefault, 0)) != nil)
+ if ((consoleUsersArray = (__HIDRemoteBridge NSArray *)IORegistryEntryCreateCFProperty((io_registry_entry_t)rootService, CFSTR("IOConsoleUsers"), kCFAllocatorDefault, 0)) != nil)
{
if ([consoleUsersArray isKindOfClass:[NSArray class]]) // Be careful - ensure this really is an array
{
NSEnumerator *consoleUsersEnum; // I *love* Obj-C2's fast enumerators, but we need to stay compatible with 10.4 :-/
-
+
if ((consoleUsersEnum = [consoleUsersArray objectEnumerator]) != nil)
{
UInt64 secureEventInputPIDSum = 0;
uid_t frontUserSession = 0;
BOOL screenIsLocked = NO;
NSDictionary *consoleUserDict;
-
+
while ((consoleUserDict = [consoleUsersEnum nextObject]) != nil)
{
if ([consoleUserDict isKindOfClass:[NSDictionary class]]) // Be careful - ensure this really is a dictionary
@@ -1966,7 +1986,7 @@ static HIDRemote *sHIDRemote = nil;
NSNumber *onConsole;
NSNumber *userID;
NSNumber *screenIsLockedBool;
-
+
if ((secureInputPID = [consoleUserDict objectForKey:@"kCGSSessionSecureInputPID"]) != nil)
{
if ([secureInputPID isKindOfClass:[NSNumber class]])
@@ -1974,7 +1994,7 @@ static HIDRemote *sHIDRemote = nil;
secureEventInputPIDSum += ((UInt64) [secureInputPID intValue]);
}
}
-
+
if (((onConsole = [consoleUserDict objectForKey:@"kCGSSessionOnConsoleKey"]) != nil) &&
((userID = [consoleUserDict objectForKey:@"kCGSSessionUserIDKey"]) != nil))
{
@@ -1986,7 +2006,7 @@ static HIDRemote *sHIDRemote = nil;
}
}
}
-
+
if ((screenIsLockedBool = [consoleUserDict objectForKey:@"CGSSessionScreenIsLocked"]) != nil)
{
if ([screenIsLockedBool isKindOfClass:[NSNumber class]])
@@ -2002,10 +2022,10 @@ static HIDRemote *sHIDRemote = nil;
_lastScreenIsLocked = screenIsLocked;
}
}
-
+
CFRelease((CFTypeRef)consoleUsersArray);
}
-
+
IOObjectRelease((io_object_t) rootService);
}
}
@@ -2016,7 +2036,7 @@ static HIDRemote *sHIDRemote = nil;
{
HIDRemoteMode restartInMode = _mode;
unsigned checkActiveRemoteControlCount = [self activeRemoteControlCount];
-
+
// Only restart when we already have active remote controls - to avoid race conditions with other applications using kHIDRemoteModeExclusive mode (new in V1.2.1)
if (checkActiveRemoteControlCount > 0)
{
@@ -2024,7 +2044,7 @@ static HIDRemote *sHIDRemote = nil;
[self stopRemoteControl];
[self startRemoteControl:restartInMode];
_isRestarting = NO;
-
+
// Check whether we lost a remote control due to restarting/secure input change notification handling (new in V1.2.1)
if (checkActiveRemoteControlCount != [self activeRemoteControlCount])
{
@@ -2042,9 +2062,9 @@ static HIDRemote *sHIDRemote = nil;
UInt64 old_lastSecureEventInputPIDSum = _lastSecureEventInputPIDSum;
uid_t old_lastFrontUserSession = _lastFrontUserSession;
BOOL old_lastScreenIsLocked = _lastScreenIsLocked;
-
+
[self _updateSessionInformation];
-
+
if (((old_lastSecureEventInputPIDSum != _lastSecureEventInputPIDSum) ||
(old_lastFrontUserSession != _lastFrontUserSession) ||
(old_lastScreenIsLocked != _lastScreenIsLocked)) && _secureEventInputWorkAround)
@@ -2063,7 +2083,7 @@ static HIDRemote *sHIDRemote = nil;
if (NSAppKitVersionNumber >= 1187)
#endif
{
- #ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+ #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only
{
if ([NSThread currentThread] != _runOnThread)
@@ -2082,29 +2102,31 @@ static HIDRemote *sHIDRemote = nil;
#pragma mark - PRIVATE: IOKitLib Callbacks
-static void HIDEventCallback( void * target,
+static void HIDEventCallback( void * target,
IOReturn result,
void * refCon,
void * sender)
{
- HIDRemote *hidRemote = (HIDRemote *)refCon;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ HIDRemote *hidRemote = (__HIDRemoteBridge HIDRemote *)refCon;
+
+ HIDRemoteAutoreleasePoolOpen();
[hidRemote _hidEventFor:(io_service_t)((intptr_t)target) from:(IOHIDQueueInterface**)sender withResult:(IOReturn)result];
- [pool release];
+ HIDRemoteAutoreleasePoolClose();
}
static void ServiceMatchingCallback( void *refCon,
io_iterator_t iterator)
{
- HIDRemote *hidRemote = (HIDRemote *)refCon;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ HIDRemote *hidRemote = (__HIDRemoteBridge HIDRemote *)refCon;
+
+ HIDRemoteAutoreleasePoolOpen();
[hidRemote _serviceMatching:iterator];
- [pool release];
+ HIDRemoteAutoreleasePoolClose();
}
static void ServiceNotificationCallback(void * refCon,
@@ -2112,14 +2134,15 @@ static void ServiceNotificationCallback(void * refCon,
natural_t messageType,
void * messageArgument)
{
- HIDRemote *hidRemote = (HIDRemote *)refCon;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ HIDRemote *hidRemote = (__HIDRemoteBridge HIDRemote *)refCon;
+ HIDRemoteAutoreleasePoolOpen();
+
[hidRemote _serviceNotificationFor:service
messageType:messageType
messageArgument:messageArgument];
- [pool release];
+ HIDRemoteAutoreleasePoolClose();
}
static void SecureInputNotificationCallback( void * refCon,
@@ -2127,14 +2150,15 @@ static void SecureInputNotificationCallback( void * refCon,
natural_t messageType,
void * messageArgument)
{
- HIDRemote *hidRemote = (HIDRemote *)refCon;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ HIDRemote *hidRemote = (__HIDRemoteBridge HIDRemote *)refCon;
+ HIDRemoteAutoreleasePoolOpen();
+
[hidRemote _secureInputNotificationFor:service
messageType:messageType
messageArgument:messageArgument];
- [pool release];
+ HIDRemoteAutoreleasePoolClose();
}
// Attribute dictionary keys
diff --git a/xbmc/cores/ExternalPlayer/ExternalPlayer.cpp b/xbmc/cores/ExternalPlayer/ExternalPlayer.cpp
index feb01bc898..d2f08b8be5 100644
--- a/xbmc/cores/ExternalPlayer/ExternalPlayer.cpp
+++ b/xbmc/cores/ExternalPlayer/ExternalPlayer.cpp
@@ -89,7 +89,7 @@ bool CExternalPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &opti
m_bIsPlaying = true;
m_time = 0;
m_playbackStartTime = XbmcThreads::SystemClockMillis();
- m_launchFilename = file.GetPath();
+ m_launchFilename = file.GetDynPath();
CLog::Log(LOGNOTICE, "%s: %s", __FUNCTION__, m_launchFilename.c_str());
Create();
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp
index 8c5ea25223..fde83a051f 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.cpp
@@ -292,6 +292,15 @@ DemuxPacket* CDVDDemuxClient::Read()
}
}
+ if (!IsVideoReady())
+ {
+ m_packet.reset();
+ DemuxPacket *pPacket = CDVDDemuxUtils::AllocateDemuxPacket(0);
+ pPacket->demuxerId = m_demuxerId;
+ return pPacket;
+ }
+
+ //! @todo drop this block
CDVDInputStream::IDisplayTime *inputStream = m_pInput->GetIDisplayTime();
if (inputStream)
{
@@ -310,6 +319,7 @@ DemuxPacket* CDVDDemuxClient::Read()
m_packet->dispTime += DVD_TIME_TO_MSEC(m_packet->dts - m_dtsAtDisplayTime);
}
}
+
return m_packet.release();
}
@@ -554,6 +564,17 @@ int CDVDDemuxClient::GetNrOfStreams() const
return m_streams.size();
}
+bool CDVDDemuxClient::IsVideoReady()
+{
+ for (const auto& stream : m_streams)
+ {
+ if (stream.second->type == STREAM_VIDEO &&
+ stream.second->ExtraData == nullptr)
+ return false;
+ }
+ return true;
+}
+
std::string CDVDDemuxClient::GetFileName()
{
if (m_pInput)
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h
index 692fe1dd43..d41f354a44 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxClient.h
@@ -47,6 +47,7 @@ protected:
bool ParsePacket(DemuxPacket* pPacket);
void DisposeStreams();
std::shared_ptr<CDemuxStream> GetStreamInternal(int iStreamId);
+ bool IsVideoReady();
std::shared_ptr<CDVDInputStream> m_pInput;
std::shared_ptr<CDVDInputStream::IDemux> m_IDemux;
diff --git a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
index 7bca2e90bc..1663f0c809 100644
--- a/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDDemuxers/DVDDemuxFFmpeg.cpp
@@ -1394,7 +1394,7 @@ void CDVDDemuxFFmpeg::DisposeStreams()
CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx)
{
AVStream* pStream = m_pFormatContext->streams[streamIdx];
- if (pStream)
+ if (pStream && pStream->discard != AVDISCARD_ALL)
{
// Video (mp4) from GoPro cameras can have a 'meta' track used for a file repair containing
// 'fdsc' data, this is also called the SOS track.
@@ -1630,8 +1630,24 @@ CDemuxStream* CDVDDemuxFFmpeg::AddStream(int streamIdx)
#ifdef HAVE_LIBBLURAY
if (m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY))
{
- std::static_pointer_cast<CDVDInputStreamBluray>(m_pInput)->GetStreamInfo(pStream->id, stream->language);
stream->dvdNavId = pStream->id;
+
+ auto it = std::find_if(m_streams.begin(), m_streams.end(),
+ [&stream](const std::pair<int, CDemuxStream*>& v)
+ {return (v.second->dvdNavId == stream->dvdNavId) && (v.second->type == stream->type); });
+
+ if (it != m_streams.end())
+ {
+ if (stream->codec == AV_CODEC_ID_AC3 && it->second->codec == AV_CODEC_ID_TRUEHD)
+ CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::AddStream - discarding duplicated bluray stream (truehd ac3 core)");
+ else
+ CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::AddStream - discarding duplicate bluray stream %s", stream->codecName);
+
+ pStream->discard = AVDISCARD_ALL;
+ delete stream;
+ return nullptr;
+ }
+ std::static_pointer_cast<CDVDInputStreamBluray>(m_pInput)->GetStreamInfo(pStream->id, stream->language);
}
#endif
if( m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) )
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h
index 4e2343b090..8dc39442c9 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStream.h
@@ -155,8 +155,8 @@ public:
virtual ENextStream NextStream() { return NEXTSTREAM_NONE; }
virtual void Abort() {}
virtual int GetBlockSize() { return 0; }
- virtual bool CanSeek() { return true; }
- virtual bool CanPause() { return true; }
+ virtual bool CanSeek() { return true; } //! @todo drop this
+ virtual bool CanPause() { return false; }
/*! \brief Indicate expected read rate in bytes per second.
* This could be used to throttle caching rate. Should
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp
index 21fa6f5f23..26e1824fed 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFFmpeg.cpp
@@ -22,9 +22,6 @@ using PLAYLIST::CPlayListM3U;
CDVDInputStreamFFmpeg::CDVDInputStreamFFmpeg(const CFileItem& fileitem)
: CDVDInputStream(DVDSTREAM_TYPE_FFMPEG, fileitem)
- , m_can_pause(false)
- , m_can_seek(false)
- , m_aborted(false)
{
}
@@ -47,23 +44,14 @@ bool CDVDInputStreamFFmpeg::Open()
if (!CDVDInputStream::Open())
return false;
- m_can_pause = true;
- m_can_seek = true;
- m_aborted = false;
+ m_aborted = false;
if(strnicmp(m_item.GetDynPath().c_str(), "udp://", 6) == 0 ||
strnicmp(m_item.GetDynPath().c_str(), "rtp://", 6) == 0)
{
- m_can_pause = false;
- m_can_seek = false;
m_realtime = true;
}
- if(strnicmp(m_item.GetDynPath().c_str(), "tcp://", 6) == 0)
- {
- m_can_pause = true;
- m_can_seek = false;
- }
return true;
}
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFFmpeg.h b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFFmpeg.h
index 6e7a299f07..e34855ebb0 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFFmpeg.h
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFFmpeg.h
@@ -30,9 +30,6 @@ public:
const CFileItem& GetItem() const { return m_item; }
- bool CanSeek() override { return m_can_seek; }
- bool CanPause() override { return m_can_pause; }
-
std::string GetProxyType() const;
std::string GetProxyHost() const;
uint16_t GetProxyPort() const;
@@ -40,7 +37,5 @@ public:
std::string GetProxyPassword() const;
protected:
- bool m_can_pause;
- bool m_can_seek;
- bool m_aborted;
+ bool m_aborted = false;
};
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h
index bf800938ac..e215953ab2 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamAddon.h
@@ -53,7 +53,7 @@ public:
bool Pause(double dTime) override;
int64_t GetLength() override;
bool IsEOF() override;
- bool CanSeek() override;
+ bool CanSeek() override; //! @todo drop this
bool CanPause() override;
// IDisplayTime
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRBase.h b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRBase.h
index ee48c9e63f..c339599ccd 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRBase.h
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/InputStreamPVRBase.h
@@ -46,7 +46,7 @@ public:
CDVDInputStream::ITimes* GetITimes() override { return this; }
bool GetTimes(Times &times) override;
- bool CanSeek() override;
+ bool CanSeek() override; //! @todo drop this
bool CanPause() override;
void Pause(bool bPaused);
diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp
index 60221e0b6b..2b51c80e5a 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp
+++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp
@@ -1989,9 +1989,11 @@ void CVideoPlayer::HandlePlaySpeed()
threshold = 40;
bool video = m_CurrentVideo.id < 0 || (m_CurrentVideo.syncState == IDVDStreamPlayer::SYNC_WAITSYNC) ||
- (m_CurrentVideo.packets == 0 && m_CurrentAudio.packets > threshold);
+ (m_CurrentVideo.packets == 0 && m_CurrentAudio.packets > threshold) ||
+ (!m_VideoPlayerAudio->AcceptsData() && m_processInfo->GetLevelVQ() < 10);
bool audio = m_CurrentAudio.id < 0 || (m_CurrentAudio.syncState == IDVDStreamPlayer::SYNC_WAITSYNC) ||
- (m_CurrentAudio.packets == 0 && m_CurrentVideo.packets > threshold);
+ (m_CurrentAudio.packets == 0 && m_CurrentVideo.packets > threshold) ||
+ (!m_VideoPlayerVideo->AcceptsData() && m_VideoPlayerAudio->GetLevel() < 10);
if (m_CurrentAudio.syncState == IDVDStreamPlayer::SYNC_WAITSYNC &&
(m_CurrentAudio.avsync == CCurrentStream::AV_SYNC_CONT ||
@@ -4672,8 +4674,9 @@ void CVideoPlayer::UpdatePlayState(double timeout)
state.timeMax = m_pDemuxer->GetStreamLength();
}
- state.canpause = true;
- state.canseek = true;
+ state.canpause = false;
+ state.canseek = false;
+ state.cantempo = false;
state.isInMenu = false;
state.hasMenu = false;
@@ -4732,7 +4735,6 @@ void CVideoPlayer::UpdatePlayState(double timeout)
}
state.canpause = m_pInputStream->CanPause();
- state.canseek = m_pInputStream->CanSeek();
bool realtime = m_pInputStream->IsRealtime();
@@ -4794,9 +4796,13 @@ void CVideoPlayer::UpdatePlayState(double timeout)
if (state.timeMin == state.timeMax)
{
state.canseek = false;
- state.canpause = false;
state.cantempo = false;
}
+ else
+ {
+ state.canseek = true;
+ state.canpause = true;
+ }
m_processInfo->SetPlayTimes(state.startTime, state.time, state.timeMin, state.timeMax);
diff --git a/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp b/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp
index 665d3fcd99..5ea7d37d9f 100644
--- a/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp
+++ b/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp
@@ -96,9 +96,9 @@ void CPlayerCoreFactory::GetPlayers(std::vector<std::string>&players, const bool
void CPlayerCoreFactory::GetPlayers(const CFileItem& item, std::vector<std::string>&players) const
{
- CURL url(item.GetPath());
+ CURL url(item.GetDynPath());
- CLog::Log(LOGDEBUG, "CPlayerCoreFactory::GetPlayers(%s)", CURL::GetRedacted(item.GetPath()).c_str());
+ CLog::Log(LOGDEBUG, "CPlayerCoreFactory::GetPlayers(%s)", CURL::GetRedacted(item.GetDynPath()).c_str());
std::vector<std::string>validPlayers;
GetPlayers(validPlayers);
diff --git a/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp b/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp
index 31de65da82..28a4ca22bc 100644
--- a/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp
+++ b/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp
@@ -157,7 +157,7 @@ void CPlayerSelectionRule::GetPlayers(const CFileItem& item, std::vector<std::st
return;
}
- CURL url(item.GetPath());
+ CURL url(item.GetDynPath());
if (CompileRegExp(m_fileTypes, regExp) && !MatchesRegExp(url.GetFileType(), regExp))
return;
@@ -168,7 +168,7 @@ void CPlayerSelectionRule::GetPlayers(const CFileItem& item, std::vector<std::st
if (CompileRegExp(m_mimeTypes, regExp) && !MatchesRegExp(item.GetMimeType(), regExp))
return;
- if (CompileRegExp(m_fileName, regExp) && !MatchesRegExp(item.GetPath(), regExp))
+ if (CompileRegExp(m_fileName, regExp) && !MatchesRegExp(item.GetDynPath(), regExp))
return;
CLog::Log(LOGDEBUG, "CPlayerSelectionRule::GetPlayers: matches rule: %s", m_name.c_str());
diff --git a/xbmc/input/InputManager.cpp b/xbmc/input/InputManager.cpp
index 6acd88c0e6..7d9c0d208b 100644
--- a/xbmc/input/InputManager.cpp
+++ b/xbmc/input/InputManager.cpp
@@ -219,6 +219,8 @@ bool CInputManager::ProcessEventServer(int windowId, float frameTime)
m_Mouse.SetActive(false);
+ CLog::Log(LOGDEBUG, "EventServer: key %d translated to action %s", wKeyID, actionName);
+
return ExecuteInputAction(CAction(actionID, fAmount, 0.0f, actionName));
}
else
diff --git a/xbmc/messaging/ThreadMessage.h b/xbmc/messaging/ThreadMessage.h
index 538007df9e..e79237a25c 100644
--- a/xbmc/messaging/ThreadMessage.h
+++ b/xbmc/messaging/ThreadMessage.h
@@ -53,6 +53,7 @@ public:
: dwMessage{ messageId }
, param1{ p1 }
, param2{ p2 }
+ , param3{ 0 }
, lpVoid{ payload }
, strParam( param )
, params( vecParams )
diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp
index 812f0b5afc..a2b865e208 100644
--- a/xbmc/music/windows/GUIWindowMusicBase.cpp
+++ b/xbmc/music/windows/GUIWindowMusicBase.cpp
@@ -58,6 +58,7 @@
#include "cores/playercorefactory/PlayerCoreFactory.h"
#include "CueDocument.h"
#include "Autorun.h"
+#include "video/dialogs/GUIDialogVideoInfo.h"
#ifdef TARGET_POSIX
#include "platform/linux/XTimeUtils.h"
@@ -274,9 +275,9 @@ void CGUIWindowMusicBase::OnItemInfo(int iItem)
CFileItemPtr item = m_vecItems->Get(iItem);
- if (item->IsVideoDb())
+ if (item->IsVideo())
{ // Music video on a mixed current playlist
- OnContextButton(iItem, CONTEXT_BUTTON_INFO);
+ CGUIDialogVideoInfo::ShowFor(*item);
return;
}
@@ -316,7 +317,7 @@ void CGUIWindowMusicBase::RetrieveMusicInfo()
for (int i = 0; i < m_vecItems->Size(); ++i)
{
CFileItemPtr pItem = (*m_vecItems)[i];
- if (pItem->m_bIsFolder || pItem->IsPlayList() || pItem->IsPicture() || pItem->IsLyrics())
+ if (pItem->m_bIsFolder || pItem->IsPlayList() || pItem->IsPicture() || pItem->IsLyrics() || pItem->IsVideo())
continue;
CMusicInfoTag& tag = *pItem->GetMusicInfoTag();
diff --git a/xbmc/network/EventClient.cpp b/xbmc/network/EventClient.cpp
index 4f073ff081..7e5a60ccda 100644
--- a/xbmc/network/EventClient.cpp
+++ b/xbmc/network/EventClient.cpp
@@ -26,6 +26,7 @@
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
#include "ServiceBroker.h"
+#include "utils/log.h"
using namespace EVENTCLIENT;
using namespace EVENTPACKET;
@@ -388,6 +389,8 @@ bool CEventClient::OnPacketBUTTON(CEventPacket *packet)
float famount = 0;
bool active = (flags & PTB_DOWN) ? true : false;
+
+ CLog::Log(LOGDEBUG, "EventClient: button code %d %s", bcode, active ? "pressed" : "released");
if(flags & PTB_USE_AMOUNT)
{
@@ -437,15 +440,22 @@ bool CEventClient::OnPacketBUTTON(CEventPacket *packet)
/* if last event had an amount, we must resend without amount */
if(it2->m_bUseAmount && it2->m_fAmount != 0.0)
+ {
m_buttonQueue.push_back(state);
+ }
/* if the last event was waiting for a repeat interval, it has executed already.*/
if(it2->m_bRepeat)
{
if(it2->m_iNextRepeat > 0)
+ {
m_buttonQueue.erase(it2);
+ }
else
+ {
it2->m_bRepeat = false;
+ it2->m_bActive = false;
+ }
}
}
diff --git a/xbmc/platform/linux/input/LibInputTouch.cpp b/xbmc/platform/linux/input/LibInputTouch.cpp
index 7e186df62b..fb771cfb1d 100644
--- a/xbmc/platform/linux/input/LibInputTouch.cpp
+++ b/xbmc/platform/linux/input/LibInputTouch.cpp
@@ -55,7 +55,7 @@ void CLibInputTouch::SetPosition(int slot, CPoint point)
void CLibInputTouch::ProcessTouchDown(libinput_event_touch *e)
{
- int slot = libinput_event_touch_get_slot(e);
+ int slot = libinput_event_touch_get_seat_slot(e);
SetPosition(slot, GetPos(e));
SetEvent(slot, TouchInputDown);
@@ -64,7 +64,7 @@ void CLibInputTouch::ProcessTouchDown(libinput_event_touch *e)
void CLibInputTouch::ProcessTouchMotion(libinput_event_touch *e)
{
- int slot = libinput_event_touch_get_slot(e);
+ int slot = libinput_event_touch_get_seat_slot(e);
uint64_t nanotime = libinput_event_touch_get_time_usec(e) * 1000LL;
SetPosition(slot, GetPos(e));
@@ -78,7 +78,7 @@ void CLibInputTouch::ProcessTouchMotion(libinput_event_touch *e)
void CLibInputTouch::ProcessTouchUp(libinput_event_touch *e)
{
- int slot = libinput_event_touch_get_slot(e);
+ int slot = libinput_event_touch_get_seat_slot(e);
SetEvent(slot, TouchInputUp);
CLog::Log(LOGDEBUG, "CLibInputTouch::%s - touch input up", __FUNCTION__);
@@ -86,7 +86,7 @@ void CLibInputTouch::ProcessTouchUp(libinput_event_touch *e)
void CLibInputTouch::ProcessTouchCancel(libinput_event_touch *e)
{
- int slot = libinput_event_touch_get_slot(e);
+ int slot = libinput_event_touch_get_seat_slot(e);
uint64_t nanotime = libinput_event_touch_get_time_usec(e) * 1000LL;
CLog::Log(LOGDEBUG, "CLibInputTouch::%s - touch input cancel", __FUNCTION__);
diff --git a/xbmc/pvr/windows/GUIEPGGridContainer.cpp b/xbmc/pvr/windows/GUIEPGGridContainer.cpp
index 79c5e8df8c..88fe9737ca 100644
--- a/xbmc/pvr/windows/GUIEPGGridContainer.cpp
+++ b/xbmc/pvr/windows/GUIEPGGridContainer.cpp
@@ -143,7 +143,6 @@ CGUIEPGGridContainer::CGUIEPGGridContainer(const CGUIEPGGridContainer &other)
m_channelScrollOffset(other.m_channelScrollOffset),
m_gridModel(new CGUIEPGGridContainerModel(*other.m_gridModel)),
m_updatedGridModel(other.m_updatedGridModel ? new CGUIEPGGridContainerModel(*other.m_updatedGridModel) : nullptr),
- m_outdatedGridModel(other.m_outdatedGridModel ? new CGUIEPGGridContainerModel(*other.m_outdatedGridModel) : nullptr),
m_item(GetItem(m_channelCursor)) // pointer to grid model internal data.
{
}
@@ -736,7 +735,6 @@ void CGUIEPGGridContainer::UpdateItems()
m_lastChannel = nullptr;
// always use asynchronously precalculated grid data.
- m_outdatedGridModel = std::move(m_gridModel); // destructing grid data can be very expensive, thus this will be done asynchronously, not here.
m_gridModel = std::move(m_updatedGridModel);
if (prevSelectedEpgTag)
@@ -1726,18 +1724,16 @@ void CGUIEPGGridContainer::SetTimelineItems(const std::unique_ptr<CFileItemList>
fBlockSize = m_blockSize;
}
- std::unique_ptr<CGUIEPGGridContainerModel> oldOutdatedGridModel;
std::unique_ptr<CGUIEPGGridContainerModel> oldUpdatedGridModel;
std::unique_ptr<CGUIEPGGridContainerModel> newUpdatedGridModel(new CGUIEPGGridContainerModel);
// can be very expensive. never call with lock acquired.
- newUpdatedGridModel->Refresh(items, gridStart, gridEnd, iRulerUnit, iBlocksPerPage, fBlockSize);
+ newUpdatedGridModel->Initialize(items, gridStart, gridEnd, iRulerUnit, iBlocksPerPage, fBlockSize);
{
CSingleLock lock(m_critSection);
// grid contains CFileItem instances. CFileItem dtor locks global graphics mutex.
// by increasing its refcount make sure, old data are not deleted while we're holding own mutex.
- oldOutdatedGridModel = std::move(m_outdatedGridModel);
oldUpdatedGridModel = std::move(m_updatedGridModel);
m_updatedGridModel = std::move(newUpdatedGridModel);
diff --git a/xbmc/pvr/windows/GUIEPGGridContainer.h b/xbmc/pvr/windows/GUIEPGGridContainer.h
index aeacd0a117..db78ed711a 100644
--- a/xbmc/pvr/windows/GUIEPGGridContainer.h
+++ b/xbmc/pvr/windows/GUIEPGGridContainer.h
@@ -225,7 +225,6 @@ namespace PVR
mutable CCriticalSection m_critSection;
std::unique_ptr<CGUIEPGGridContainerModel> m_gridModel;
std::unique_ptr<CGUIEPGGridContainerModel> m_updatedGridModel;
- std::unique_ptr<CGUIEPGGridContainerModel> m_outdatedGridModel;
GridItem *m_item;
};
diff --git a/xbmc/pvr/windows/GUIEPGGridContainerModel.cpp b/xbmc/pvr/windows/GUIEPGGridContainerModel.cpp
index a77529be5d..e6d5c65176 100644
--- a/xbmc/pvr/windows/GUIEPGGridContainerModel.cpp
+++ b/xbmc/pvr/windows/GUIEPGGridContainerModel.cpp
@@ -14,6 +14,7 @@
#include "ServiceBroker.h"
#include "settings/Settings.h"
#include "utils/Variant.h"
+#include "utils/log.h"
#include "pvr/PVRManager.h"
#include "pvr/channels/PVRChannel.h"
@@ -36,28 +37,13 @@ void CGUIEPGGridContainerModel::SetInvalid()
ruler->SetInvalid();
}
-void CGUIEPGGridContainerModel::Reset()
+void CGUIEPGGridContainerModel::Initialize(const std::unique_ptr<CFileItemList> &items, const CDateTime &gridStart, const CDateTime &gridEnd, int iRulerUnit, int iBlocksPerPage, float fBlockSize)
{
- for (auto &channel : m_gridIndex)
+ if (!m_channelItems.empty())
{
- for (const auto &block : channel)
- {
- if (block.item)
- block.item->ClearProperties();
- }
- channel.clear();
+ CLog::LogF(LOGERROR, "Already initialized!");
+ return;
}
- m_gridIndex.clear();
-
- m_channelItems.clear();
- m_programmeItems.clear();
- m_rulerItems.clear();
- m_epgItemsPtr.clear();
-}
-
-void CGUIEPGGridContainerModel::Refresh(const std::unique_ptr<CFileItemList> &items, const CDateTime &gridStart, const CDateTime &gridEnd, int iRulerUnit, int iBlocksPerPage, float fBlockSize)
-{
- Reset();
////////////////////////////////////////////////////////////////////////
// Create programme & channel items
diff --git a/xbmc/pvr/windows/GUIEPGGridContainerModel.h b/xbmc/pvr/windows/GUIEPGGridContainerModel.h
index 04ddd45157..146ecbe2fe 100644
--- a/xbmc/pvr/windows/GUIEPGGridContainerModel.h
+++ b/xbmc/pvr/windows/GUIEPGGridContainerModel.h
@@ -36,9 +36,10 @@ namespace PVR
static const int MINSPERBLOCK = 5; // minutes
static const int MAXBLOCKS = 33 * 24 * 60 / MINSPERBLOCK; //! 33 days of 5 minute blocks (31 days for upcoming data + 1 day for past data + 1 day for fillers)
- virtual ~CGUIEPGGridContainerModel() { Reset(); }
+ CGUIEPGGridContainerModel() = default;
+ virtual ~CGUIEPGGridContainerModel() = default;
- void Refresh(const std::unique_ptr<CFileItemList> &items, const CDateTime &gridStart, const CDateTime &gridEnd, int iRulerUnit, int iBlocksPerPage, float fBlockSize);
+ void Initialize(const std::unique_ptr<CFileItemList> &items, const CDateTime &gridStart, const CDateTime &gridEnd, int iRulerUnit, int iBlocksPerPage, float fBlockSize);
void SetInvalid();
static const int INVALID_INDEX = -1;
@@ -83,7 +84,6 @@ namespace PVR
private:
void FreeItemsMemory();
- void Reset();
struct ItemsPtr
{
diff --git a/xbmc/windowing/gbm/DRMUtils.cpp b/xbmc/windowing/gbm/DRMUtils.cpp
index 94512a308a..84f869877b 100644
--- a/xbmc/windowing/gbm/DRMUtils.cpp
+++ b/xbmc/windowing/gbm/DRMUtils.cpp
@@ -428,6 +428,8 @@ bool CDRMUtils::FindPlanes()
if (!FindModifiersForPlane(m_overlay_plane))
{
CLog::Log(LOGDEBUG, "CDRMUtils::%s - no drm modifiers present for the overlay plane", __FUNCTION__);
+ m_overlay_plane->modifiers_map.emplace(DRM_FORMAT_ARGB8888, std::vector<uint64_t>{DRM_FORMAT_MOD_LINEAR});
+ m_overlay_plane->modifiers_map.emplace(DRM_FORMAT_XRGB8888, std::vector<uint64_t>{DRM_FORMAT_MOD_LINEAR});
}
return true;
diff --git a/xbmc/windowing/gbm/GBMUtils.cpp b/xbmc/windowing/gbm/GBMUtils.cpp
index 118b99f947..a48d6cc4f8 100644
--- a/xbmc/windowing/gbm/GBMUtils.cpp
+++ b/xbmc/windowing/gbm/GBMUtils.cpp
@@ -48,13 +48,15 @@ bool CGBMUtils::CreateSurface(int width, int height, const uint64_t *modifiers,
GBM_FORMAT_ARGB8888,
modifiers,
modifiers_count);
-#else
- m_surface = gbm_surface_create(m_device,
- width,
- height,
- GBM_FORMAT_ARGB8888,
- GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
#endif
+ if (!m_surface)
+ {
+ m_surface = gbm_surface_create(m_device,
+ width,
+ height,
+ GBM_FORMAT_ARGB8888,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+ }
if (!m_surface)
{