[4] added version webhook

pull/811/head
meisnate12 3 years ago
parent 338fdbce04
commit 66f9aa8af9

@ -1 +1 @@
1.16.2-develop3 1.16.2-develop4

@ -55,6 +55,7 @@ settings:
custom_repo: custom_repo:
webhooks: # Can be individually specified per library as well webhooks: # Can be individually specified per library as well
error: error:
version:
run_start: run_start:
run_end: run_end:
changes: changes:

@ -19,6 +19,7 @@ Once you have added the apikey your config.yml you have to add `notifiarr` to an
```yaml ```yaml
webhooks: webhooks:
error: notifiarr error: notifiarr
version: notifiarr
run_start: notifiarr run_start: notifiarr
run_end: notifiarr run_end: notifiarr
collection_changes: notifiarr collection_changes: notifiarr

@ -9,6 +9,7 @@ Below is a `webhooks` mapping example and the full set of attributes:
```yaml ```yaml
webhooks: webhooks:
error: https://www.myspecialdomain.com/pmm error: https://www.myspecialdomain.com/pmm
version:
run_start: run_start:
run_end: run_end:
changes: changes:
@ -17,6 +18,7 @@ webhooks:
| Attribute | Global | Library | Collection | | Attribute | Global | Library | Collection |
|:----------------------------------------|:-------:|:--------:|:----------:| |:----------------------------------------|:-------:|:--------:|:----------:|
| [`error`](#error-notifications) | ✅ | ✅ | ❌ | | [`error`](#error-notifications) | ✅ | ✅ | ❌ |
| [`version`](#version-notifications) | ✅ | ❌ | ❌ |
| [`run_start`](#run-start-notifications) | ✅ | ❌ | ❌ | | [`run_start`](#run-start-notifications) | ✅ | ❌ | ❌ |
| [`run_end`](#run-end-notifications) | ✅ | ❌ | ❌ | | [`run_end`](#run-end-notifications) | ✅ | ❌ | ❌ |
| [`changes`](#changes-notifications) | ✅ | ✅ | ✅ | | [`changes`](#changes-notifications) | ✅ | ✅ | ✅ |
@ -72,6 +74,20 @@ The Error notification will be sent whenever an error occurs. The payload that i
} }
``` ```
## Version Notifications
The Version notification will be sent at the beginning of a run if there is a newer version available.
### JSON Payload
```yaml
{
"current": str, // Current Version
"latest": str, // Latest Version
"notes": str // Sends the lateset release notes or new commits to develop since your version
}
```
## Run Start Notifications ## Run Start Notifications
The Run Start notification will be sent at the beginning of every run. The Run Start notification will be sent at the beginning of every run.
@ -81,7 +97,6 @@ The Run Start notification will be sent at the beginning of every run.
```yaml ```yaml
{ {
"start_time": str, // Time Run is started Format "YY-mm-dd HH:MM:SS" "start_time": str, // Time Run is started Format "YY-mm-dd HH:MM:SS"
"new_version": str // New Version or null if version is current
} }
``` ```
@ -96,7 +111,6 @@ The Run End notification will be sent at the end of every run with statistics.
"start_time": str, // Time Run started Format "YY-mm-dd HH:MM:SS" "start_time": str, // Time Run started Format "YY-mm-dd HH:MM:SS"
"end_time": str, // Time Run ended Format "YY-mm-dd HH:MM:SS" "end_time": str, // Time Run ended Format "YY-mm-dd HH:MM:SS"
"run_time": str, // Time Run took to complete Format "HH:MM" "run_time": str, // Time Run took to complete Format "HH:MM"
"new_version": str, // New Version or null if version is current
"collections_created": int, // Number of Collections/Playlists Created "collections_created": int, // Number of Collections/Playlists Created
"collections_modified": int, // Number of Collections/Playlists Modified "collections_modified": int, // Number of Collections/Playlists Modified
"collections_deleted": int, // Number of Collections/Playlists Removed "collections_deleted": int, // Number of Collections/Playlists Removed

@ -9,6 +9,7 @@ from modules.convert import Convert
from modules.flixpatrol import FlixPatrol from modules.flixpatrol import FlixPatrol
from modules.icheckmovies import ICheckMovies from modules.icheckmovies import ICheckMovies
from modules.imdb import IMDb from modules.imdb import IMDb
from modules.github import GitHub
from modules.letterboxd import Letterboxd from modules.letterboxd import Letterboxd
from modules.mal import MyAnimeList from modules.mal import MyAnimeList
from modules.meta import PlaylistFile from modules.meta import PlaylistFile
@ -63,7 +64,8 @@ class ConfigFile:
self.default_dir = default_dir self.default_dir = default_dir
self.read_only = attrs["read_only"] if "read_only" in attrs else False self.read_only = attrs["read_only"] if "read_only" in attrs else False
self.new_version = attrs["new_version"] if "new_version" in attrs else None self.version = attrs["version"] if "version" in attrs else None
self.latest_version = attrs["latest_version"] if "latest_version" in attrs else None
self.test_mode = attrs["test"] if "test" in attrs else False self.test_mode = attrs["test"] if "test" in attrs else False
self.trace_mode = attrs["trace"] if "trace" in attrs else False self.trace_mode = attrs["trace"] if "trace" in attrs else False
self.delete_collections = attrs["delete"] if "delete" in attrs else False self.delete_collections = attrs["delete"] if "delete" in attrs else False
@ -324,17 +326,12 @@ class ConfigFile:
import urllib3 import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
self.webhooks = {
"error": check_for_attribute(self.data, "error", parent="webhooks", var_type="list", default_is_none=True),
"run_start": check_for_attribute(self.data, "run_start", parent="webhooks", var_type="list", default_is_none=True),
"run_end": check_for_attribute(self.data, "run_end", parent="webhooks", var_type="list", default_is_none=True),
"changes": check_for_attribute(self.data, "changes", parent="webhooks", var_type="list", default_is_none=True)
}
if self.general["cache"]: if self.general["cache"]:
logger.separator() logger.separator()
self.Cache = Cache(self.config_path, self.general["cache_expiration"]) self.Cache = Cache(self.config_path, self.general["cache_expiration"])
else: else:
self.Cache = None self.Cache = None
self.GitHub = GitHub(self)
logger.separator() logger.separator()
@ -354,9 +351,18 @@ class ConfigFile:
else: else:
logger.warning("notifiarr attribute not found") logger.warning("notifiarr attribute not found")
self.webhooks = {
"error": check_for_attribute(self.data, "error", parent="webhooks", var_type="list", default_is_none=True),
"version": check_for_attribute(self.data, "version", parent="webhooks", var_type="list", default_is_none=True),
"run_start": check_for_attribute(self.data, "run_start", parent="webhooks", var_type="list", default_is_none=True),
"run_end": check_for_attribute(self.data, "run_end", parent="webhooks", var_type="list", default_is_none=True),
"changes": check_for_attribute(self.data, "changes", parent="webhooks", var_type="list", default_is_none=True)
}
self.Webhooks = Webhooks(self, self.webhooks, notifiarr=self.NotifiarrFactory) self.Webhooks = Webhooks(self, self.webhooks, notifiarr=self.NotifiarrFactory)
try: try:
self.Webhooks.start_time_hooks(self.start_time, self.new_version) self.Webhooks.start_time_hooks(self.start_time)
if self.version[1] != self.latest_version[1] or (self.version[2] and self.version[2] < self.latest_version[2]):
self.Webhooks.version_hooks(self.version, self.latest_version)
except Failed as e: except Failed as e:
logger.stacktrace() logger.stacktrace()
logger.error(f"Webhooks Error: {e}") logger.error(f"Webhooks Error: {e}")

@ -0,0 +1,30 @@
import re
from modules import util
from modules.util import Failed
logger = util.logger
base_url = "https://api.github.com/repos/meisnate12/Plex-Meta-Manager"
class GitHub:
def __init__(self, config):
self.config = config
def latest_release_notes(self):
response = self.config.get_json(f"{base_url}/releases/latest")
return response["body"]
def get_develop_commits(self, dev_version):
master_sha = self.config.get_json(f"{base_url}/commits/master")["sha"]
response = self.config.get_json(f"{base_url}/commits?sha=develop")
commits = []
for commit in response:
if commit["sha"] == master_sha:
break
message = commit["commit"]["message"]
match = re.match("^\\[(\\d)\\]", message)
if match and int(match.group(1)) <= dev_version:
break
commits.append(message)
return "\n".join(commits)

@ -1,4 +1,4 @@
import glob, logging, os, re, signal, sys, time import glob, logging, os, re, requests, signal, sys, time
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pathvalidate import is_valid_filename, sanitize_filename from pathvalidate import is_valid_filename, sanitize_filename
from plexapi.audio import Album, Track from plexapi.audio import Album, Track
@ -92,6 +92,18 @@ def make_ordinal(n):
def add_zero(number): def add_zero(number):
return str(number) if len(str(number)) > 1 else f"0{number}" return str(number) if len(str(number)) > 1 else f"0{number}"
def current_version(develop=False):
url = f"https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/{'develop' if develop else 'master'}/VERSION"
try:
return parse_version(requests.get(url).content.decode().strip())
except requests.exceptions.ConnectionError:
return None
def parse_version(version):
split_version = version.split("-develop")
return version, split_version[0], int(split_version[1]) if len(split_version) > 1 else 0
def add_dict_list(keys, value, dict_map): def add_dict_list(keys, value, dict_map):
for key in keys: for key in keys:
if key in dict_map: if key in dict_map:

@ -8,6 +8,7 @@ class Webhooks:
def __init__(self, config, system_webhooks, library=None, notifiarr=None): def __init__(self, config, system_webhooks, library=None, notifiarr=None):
self.config = config self.config = config
self.error_webhooks = system_webhooks["error"] if "error" in system_webhooks else [] self.error_webhooks = system_webhooks["error"] if "error" in system_webhooks else []
self.version_webhooks = system_webhooks["version"] if "version" in system_webhooks else []
self.run_start_webhooks = system_webhooks["run_start"] if "run_start" in system_webhooks else [] self.run_start_webhooks = system_webhooks["run_start"] if "run_start" in system_webhooks else []
self.run_end_webhooks = system_webhooks["run_end"] if "run_end" in system_webhooks else [] self.run_end_webhooks = system_webhooks["run_end"] if "run_end" in system_webhooks else []
self.library = library self.library = library
@ -44,20 +45,25 @@ class Webhooks:
if response.status_code >= 400: if response.status_code >= 400:
raise Failed(f"({response.status_code} [{response.reason}])") raise Failed(f"({response.status_code} [{response.reason}])")
def start_time_hooks(self, start_time, version): def start_time_hooks(self, start_time):
if self.run_start_webhooks: if self.run_start_webhooks:
self._request(self.run_start_webhooks, { self._request(self.run_start_webhooks, {"start_time": start_time.strftime("%Y-%m-%d %H:%M:%S")})
"start_time": start_time.strftime("%Y-%m-%d %H:%M:%S"),
"new_version": version def version_hooks(self, version, latest_version):
}) if self.version_webhooks:
notes = None
if version[1] != latest_version[1]:
notes = self.config.GitHub.latest_release_notes()
elif version[2] and version[2] < latest_version[2]:
notes = self.config.GitHub.get_develop_commits(version[2])
self._request(self.version_webhooks, {"current": version[0], "latest": latest_version[0], "notes": notes})
def end_time_hooks(self, start_time, end_time, run_time, stats, version): def end_time_hooks(self, start_time, end_time, run_time, stats):
if self.run_end_webhooks: if self.run_end_webhooks:
self._request(self.run_end_webhooks, { self._request(self.run_end_webhooks, {
"start_time": start_time.strftime("%Y-%m-%d %H:%M:%S"), "start_time": start_time.strftime("%Y-%m-%d %H:%M:%S"),
"end_time": end_time.strftime("%Y-%m-%d %H:%M:%S"), "end_time": end_time.strftime("%Y-%m-%d %H:%M:%S"),
"run_time": run_time, "run_time": run_time,
"new_version": version,
"collections_created": stats["created"], "collections_created": stats["created"],
"collections_modified": stats["modified"], "collections_modified": stats["modified"],
"collections_deleted": stats["deleted"], "collections_deleted": stats["deleted"],

@ -108,22 +108,14 @@ def my_except_hook(exctype, value, tb):
sys.excepthook = my_except_hook sys.excepthook = my_except_hook
def get_versions(presplit_version):
split_version = presplit_version.split("-develop")
return presplit_version, split_version[0], int(split_version[1]) if len(split_version) > 1 else 0
version = ("Unknown", "Unknown", 0) version = ("Unknown", "Unknown", 0)
with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "VERSION")) as handle: with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "VERSION")) as handle:
for line in handle.readlines(): for line in handle.readlines():
line = line.strip() line = line.strip()
if len(line) > 0: if len(line) > 0:
version = get_versions(line) version = util.parse_version(line)
break break
version_url = f"https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/{'develop' if version[1] else 'master'}/VERSION"
latest_version = get_versions(requests.get(version_url).content.decode().strip())
new_version = latest_version[0] if version[1] != latest_version[1] or (version[2] and version[2] < latest_version[2]) else None
plexapi.BASE_HEADERS['X-Plex-Client-Identifier'] = "Plex-Meta-Manager" plexapi.BASE_HEADERS['X-Plex-Client-Identifier'] = "Plex-Meta-Manager"
def start(attrs): def start(attrs):
@ -137,6 +129,9 @@ def start(attrs):
logger.info_center("|_| |_|\\___/_/\\_\\ |_| |_|\\___|\\__\\__,_| |_| |_|\\__,_|_| |_|\\__,_|\\__, |\\___|_| ") logger.info_center("|_| |_|\\___/_/\\_\\ |_| |_|\\___|\\__\\__,_| |_| |_|\\__,_|_| |_|\\__,_|\\__, |\\___|_| ")
logger.info_center(" |___/ ") logger.info_center(" |___/ ")
logger.info(f" Version: {version[0]}") logger.info(f" Version: {version[0]}")
latest_version = util.current_version()
new_version = latest_version[0] if latest_version and (version[1] != latest_version[1] or (version[2] and version[2] < latest_version[2])) else None
if new_version: if new_version:
logger.info(f" Newest Version: {new_version}") logger.info(f" Newest Version: {new_version}")
if "time" in attrs and attrs["time"]: start_type = f"{attrs['time']} " if "time" in attrs and attrs["time"]: start_type = f"{attrs['time']} "
@ -149,7 +144,8 @@ def start(attrs):
attrs["time"] = start_time.strftime("%H:%M") attrs["time"] = start_time.strftime("%H:%M")
attrs["time_obj"] = start_time attrs["time_obj"] = start_time
attrs["read_only"] = read_only_config attrs["read_only"] = read_only_config
attrs["new_version"] = new_version attrs["version"] = version
attrs["latest_version"] = latest_version
logger.separator(debug=True) logger.separator(debug=True)
logger.debug(f"--config (PMM_CONFIG): {config_file}") logger.debug(f"--config (PMM_CONFIG): {config_file}")
logger.debug(f"--time (PMM_TIME): {times}") logger.debug(f"--time (PMM_TIME): {times}")
@ -193,7 +189,7 @@ def start(attrs):
run_time = str(end_time - start_time).split('.')[0] run_time = str(end_time - start_time).split('.')[0]
if config: if config:
try: try:
config.Webhooks.end_time_hooks(start_time, end_time, run_time, stats, new_version) config.Webhooks.end_time_hooks(start_time, end_time, run_time, stats)
except Failed as e: except Failed as e:
logger.stacktrace() logger.stacktrace()
logger.error(f"Webhooks Error: {e}") logger.error(f"Webhooks Error: {e}")

Loading…
Cancel
Save