-
Notifications
You must be signed in to change notification settings - Fork 310
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add script.service.latestrating plugin
- Loading branch information
Showing
10 changed files
with
712 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
GNU GENERAL PUBLIC LICENSE | ||
Version 3, 29 June 2007 | ||
|
||
This program is derived in part from the Kodi TV Show Scraper | ||
(https://github.com/xbmc/metadata.tvshows.themoviedb.org.python) | ||
which is licensed under GPL-3.0. | ||
|
||
For the full license text, see https://www.gnu.org/licenses/gpl-3.0.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Latest Rating Service for Kodi | ||
|
||
A Kodi service add-on that automatically updates movie and TV show ratings in your library. | ||
|
||
## Features | ||
- Automatically updates ratings on a configurable schedule | ||
- Supports IMDb and Trakt as rating sources | ||
- Weighted average calculation when multiple sources are enabled | ||
- Configurable date range filters to limit which movies and TV shows get updated | ||
- Built-in log viewer through "Run" function of the add-on (for now you can only see logs in current session) | ||
|
||
## Installation | ||
1. Download the zip file | ||
2. In Kodi, go to Settings > Add-ons > Install from zip file | ||
3. Select the downloaded zip file | ||
|
||
## Configuration | ||
1. Enable desired rating sources (IMDb and/or Trakt) | ||
2. Set update interval and content filters | ||
3. The service will start automatically | ||
|
||
## Credits | ||
Rating fetch functionality and Trakt API key from [Kodi's official TV Show scraper](https://github.com/xbmc/metadata.tvshows.themoviedb.org.python). | ||
|
||
## License | ||
GPL-3.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<addon id="script.service.latestrating" name="Latest Rating Service" version="1.0.2" provider-name="pizzamx"> | ||
<requires> | ||
<import addon="xbmc.python" version="3.0.0" /> | ||
<import addon="xbmc.addon" version="19.0.0"/> | ||
<import addon="script.module.requests" version="2.22.0"/> | ||
</requires> | ||
<extension point="xbmc.python.script" library="default.py"> | ||
<provides>executable</provides> | ||
</extension> | ||
<extension point="xbmc.service" library="service.py" start="login"> | ||
<provides>service</provides> | ||
</extension> | ||
<extension point="xbmc.addon.metadata"> | ||
<summary lang="en_GB">Latest Rating Service</summary> | ||
<description lang="en_GB">Automatically updates ratings for movies and TV shows in your library. Enalbe in settings first after install.</description> | ||
<platform>all</platform> | ||
<license>GPL-3.0</license> | ||
<source>https://github.com/pizzamx/script.service.latestrating</source> | ||
</extension> | ||
</addon> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import xbmcaddon | ||
import xbmcgui | ||
import xbmc | ||
import xbmcvfs | ||
import os | ||
from datetime import datetime | ||
|
||
ADDON = xbmcaddon.Addon() | ||
ADDON_NAME = ADDON.getAddonInfo('name') | ||
|
||
def get_kodi_log_path(): | ||
if xbmc.getCondVisibility('system.platform.windows'): | ||
return xbmcvfs.translatePath('special://home/kodi.log') | ||
else: | ||
return xbmcvfs.translatePath('special://home/temp/kodi.log') | ||
|
||
def parse_log_file(): | ||
log_path = get_kodi_log_path() | ||
if not os.path.exists(log_path): | ||
return ["Log file not found"] | ||
|
||
addon_logs = [] | ||
try: | ||
with open(log_path, 'r', encoding='utf-8', errors='replace') as f: | ||
for line in f: | ||
if f'[{ADDON_NAME}]' in line and '[UPDATE_RESULT]' in line: | ||
try: | ||
# Format: [Latest Rating Service] [2024-01-06 14:30:01] [UPDATE_RESULT] Movie: The Matrix - Rating: 7.9 → 8.5 | ||
# Split by ']' and remove leading '[' | ||
parts = [p.strip(' []') for p in line.split(']')] | ||
if len(parts) >= 3: | ||
timestamp = parts[1] # The timestamp part | ||
# Find the message after [UPDATE_RESULT] | ||
for i, part in enumerate(parts): | ||
if 'UPDATE_RESULT' in part: | ||
message = '] '.join(parts[i+1:]).strip() | ||
formatted_line = f"{timestamp} - {message}" | ||
addon_logs.append(formatted_line) | ||
break | ||
except Exception as e: | ||
print(f"Error parsing line: {line}, Error: {str(e)}") | ||
continue | ||
except Exception as e: | ||
return [f"Error reading log file: {str(e)}"] | ||
|
||
return list(reversed(addon_logs[-1000:])) # Return last 1000 lines in reverse chronological order | ||
|
||
def show_log_viewer(): | ||
logs = parse_log_file() | ||
if not logs: | ||
xbmcgui.Dialog().ok(ADDON_NAME, "No rating updates found") | ||
return | ||
|
||
# Create a list dialog | ||
dialog = xbmcgui.Dialog() | ||
while True: | ||
# Show the logs in a select dialog | ||
idx = dialog.select("Rating Update History", logs) | ||
if idx == -1: # User pressed back/cancel | ||
break | ||
|
||
if __name__ == '__main__': | ||
show_log_viewer() |
7 changes: 7 additions & 0 deletions
7
script.service.latestrating/resources/language/resource.language.en_gb/strings.po
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Kodi Media Center language file | ||
msgid "" | ||
msgstr "" | ||
|
||
msgctxt "#32001" | ||
msgid "View Update Log" | ||
msgstr "View Update Log" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import xbmc | ||
import xbmcaddon | ||
from datetime import datetime | ||
|
||
class Logger: | ||
def __init__(self): | ||
self.addon = xbmcaddon.Addon() | ||
self.addon_name = self.addon.getAddonInfo('name') | ||
|
||
def log(self, message, level=xbmc.LOGINFO): | ||
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') | ||
log_message = f'[{self.addon_name}] [{timestamp}] {message}' | ||
xbmc.log(log_message, level) | ||
|
||
def update_result(self, message): | ||
"""Log an update result with a special prefix""" | ||
self.log(f'[UPDATE_RESULT] {message}', xbmc.LOGINFO) | ||
|
||
def error(self, message): | ||
self.log(message, xbmc.LOGERROR) | ||
|
||
def info(self, message): | ||
self.log(message, xbmc.LOGINFO) | ||
|
||
def debug(self, message): | ||
self.log(message, xbmc.LOGDEBUG) | ||
|
||
def warning(self, message): | ||
self.log(message, xbmc.LOGWARNING) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from datetime import datetime, timedelta | ||
import xbmc | ||
from collections import deque | ||
|
||
class RateLimiter: | ||
def __init__(self, calls_per_second=1): | ||
self.calls_per_second = calls_per_second | ||
self.calls = {} # Dictionary to track calls for different sources | ||
|
||
def wait_for_token(self, source): | ||
"""Wait until we can make another API call for the given source""" | ||
if source not in self.calls: | ||
self.calls[source] = deque(maxlen=self.calls_per_second) | ||
self.calls[source].append(datetime.now()) | ||
return | ||
|
||
# Remove old timestamps | ||
now = datetime.now() | ||
while self.calls[source] and (now - self.calls[source][0]) > timedelta(seconds=1): | ||
self.calls[source].popleft() | ||
|
||
# If we've made too many calls in the last second, wait | ||
if len(self.calls[source]) >= self.calls_per_second: | ||
oldest_call = self.calls[source][0] | ||
wait_time = 1 - (now - oldest_call).total_seconds() | ||
if wait_time > 0: | ||
xbmc.sleep(int(wait_time * 1000)) | ||
|
||
def add_call(self, source): | ||
"""Record that we made an API call""" | ||
if source not in self.calls: | ||
self.calls[source] = deque(maxlen=self.calls_per_second) | ||
self.calls[source].append(datetime.now()) |
Oops, something went wrong.