From e58009744e677b7f2d5baf58d7c1f7d69430fb9d Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Tue, 18 Dec 2018 22:21:56 -0600 Subject: [PATCH 01/37] added last octet of ip for logging geoip lookups --- varken/helpers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/varken/helpers.py b/varken/helpers.py index 88426b3..d4b7133 100644 --- a/varken/helpers.py +++ b/varken/helpers.py @@ -27,7 +27,8 @@ class GeoIPHandler(object): def lookup(self, ipaddress): ip = ipaddress - self.logger.debug('Getting lat/long for Tautulli stream') + self.logger.debug('Getting lat/long for Tautulli stream using ip with last octet ending in %s', + ip.split('.')[-1:]) return self.reader.city(ip) def update(self): From 0b4e75375272d210270da21533d8b9e119ed1bc8 Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Wed, 19 Dec 2018 01:52:13 -0600 Subject: [PATCH 02/37] add quality as tag to sonarr queue to match radarr --- varken/sonarr.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/varken/sonarr.py b/varken/sonarr.py index 19a36c9..3f807c4 100644 --- a/varken/sonarr.py +++ b/varken/sonarr.py @@ -150,9 +150,9 @@ class SonarrAPI(object): protocol_id = 0 queue.append((show.series['title'], show.episode['title'], show.protocol.upper(), - protocol_id, sxe, show.id)) + protocol_id, sxe, show.id, show.quality['quality']['name'])) - for series_title, episode_title, protocol, protocol_id, sxe, sonarr_id in queue: + for series_title, episode_title, protocol, protocol_id, sxe, sonarr_id, quality in queue: hash_id = hashit(f'{self.server.id}{series_title}{sxe}') influx_payload.append( { @@ -165,7 +165,8 @@ class SonarrAPI(object): "epname": episode_title, "sxe": sxe, "protocol": protocol, - "protocol_id": protocol_id + "protocol_id": protocol_id, + "quality": quality }, "time": now, "fields": { @@ -173,5 +174,4 @@ class SonarrAPI(object): } } ) - self.dbmanager.write_points(influx_payload) From dd16ed4c04f68c8759fb2feee9697da5ecc92c00 Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Wed, 19 Dec 2018 01:56:06 -0600 Subject: [PATCH 03/37] move off tagged version --- varken/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/varken/__init__.py b/varken/__init__.py index e19b0bd..4e48cdb 100644 --- a/varken/__init__.py +++ b/varken/__init__.py @@ -1,2 +1,2 @@ -VERSION = 1.4 -BRANCH = 'master' +VERSION = 1.5 +BRANCH = 'pre-nightly' From d4c59cddb8d6904618d1d16faae2b009b25a4d6b Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Wed, 19 Dec 2018 07:43:42 -0500 Subject: [PATCH 04/37] Add FQDN log message --- varken/iniparser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/varken/iniparser.py b/varken/iniparser.py index dcd2e44..f6410b1 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -82,7 +82,7 @@ class INIParser(object): url_check) exit(1) else: - self.logger.error('%s is invalid! URL must host/IP. ie. localhost', url_check) + self.logger.error('%s is invalid! URL must FQDN host/IP. ie. localhost', url_check) exit(1) else: self.logger.debug('%s is a valid URL in the config.', url_check) From 9424a5ee9535fdf5e27f28aeb4222a0c8be69df1 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Fri, 21 Dec 2018 22:00:06 -0400 Subject: [PATCH 05/37] Add the ability to use just hostname #66 --- varken/iniparser.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/varken/iniparser.py b/varken/iniparser.py index f6410b1..8d44464 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -63,8 +63,9 @@ class INIParser(object): url_check = url inc_port = include_port - search = (r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain... + search = (r'(?:([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}|' # domain... r'localhost|' # localhost... + r'^[a-zA-Z0-9_-]*$|' r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip ) From 38c0213ead087a6daa5cb529229f4d4a1726e24c Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Fri, 21 Dec 2018 23:29:01 -0400 Subject: [PATCH 06/37] Update log message to reflect changes --- varken/iniparser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/varken/iniparser.py b/varken/iniparser.py index 8d44464..f2a5370 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -83,7 +83,7 @@ class INIParser(object): url_check) exit(1) else: - self.logger.error('%s is invalid! URL must FQDN host/IP. ie. localhost', url_check) + self.logger.error('%s is invalid! URL must host/IP. ie. localhost', url_check) exit(1) else: self.logger.debug('%s is a valid URL in the config.', url_check) From b7e5c9d58064ef4b19cea327e9f7324f38eae8f7 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Sat, 22 Dec 2018 21:33:02 -0400 Subject: [PATCH 07/37] Allow port in hostname only config --- varken/iniparser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/varken/iniparser.py b/varken/iniparser.py index f2a5370..5474784 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -65,7 +65,7 @@ class INIParser(object): search = (r'(?:([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}|' # domain... r'localhost|' # localhost... - r'^[a-zA-Z0-9_-]*$|' + r'^[a-zA-Z0-9_-]*|' r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip ) From eae5b92905b8675f5246af2d086d3190de7c7af1 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Sun, 23 Dec 2018 11:25:52 -0400 Subject: [PATCH 08/37] Improve logging messaging for URLs --- varken/iniparser.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/varken/iniparser.py b/varken/iniparser.py index 5474784..b74a838 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -59,8 +59,9 @@ class INIParser(object): self.logger.error('Config file missing (varken.ini) in %s', self.data_folder) exit(1) - def url_check(self, url=None, include_port=True): + def url_check(self, url=None, include_port=True, section=None): url_check = url + module = section inc_port = include_port search = (r'(?:([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}|' # domain... @@ -79,20 +80,20 @@ class INIParser(object): valid = match(regex, url_check) is not None if not valid: if inc_port: - self.logger.error('%s is invalid! URL must host/IP and port if not 80 or 443. ie. localhost:8080', - url_check) + self.logger.error('%s is invalid in module [%s]! URL must host/IP and port if not 80 or 443. ie. localhost:8080', + url_check, module) exit(1) else: - self.logger.error('%s is invalid! URL must host/IP. ie. localhost', url_check) + self.logger.error('%s is invalid in module [%s]! URL must host/IP. ie. localhost', url_check, module) exit(1) else: - self.logger.debug('%s is a valid URL in the config.', url_check) + self.logger.debug('%s is a valid URL in module [%s].', url_check, module) return url_check def parse_opts(self): self.read_file() # Parse InfluxDB options - url = self.url_check(self.config.get('influxdb', 'url'), include_port=False) + url = self.url_check(self.config.get('influxdb', 'url'), include_port=False, section='influxdb') port = self.config.getint('influxdb', 'port') @@ -112,7 +113,7 @@ class INIParser(object): server = None section = f"{service}-{server_id}" try: - url = self.url_check(self.config.get(section, 'url')) + url = self.url_check(self.config.get(section, 'url'), section=section) apikey = None if service != 'ciscoasa': From 3188593a9430f51cc5c6949358f0a30c0cac403f Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Sun, 23 Dec 2018 11:53:25 -0400 Subject: [PATCH 09/37] Update example to reflect cisco asa server change --- data/varken.example.ini | 2 +- varken/iniparser.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/varken.example.ini b/data/varken.example.ini index b061984..ef52b56 100644 --- a/data/varken.example.ini +++ b/data/varken.example.ini @@ -10,7 +10,7 @@ sonarr_server_ids = 1,2 radarr_server_ids = 1,2 tautulli_server_ids = 1 ombi_server_ids = 1 -ciscoasa_firewall_ids = false +ciscoasa_server_ids = false sickchill_server_ids = false [influxdb] diff --git a/varken/iniparser.py b/varken/iniparser.py index b74a838..c920d96 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -66,10 +66,10 @@ class INIParser(object): search = (r'(?:([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}|' # domain... r'localhost|' # localhost... - r'^[a-zA-Z0-9_-]*|' + r'^[a-zA-Z0-9_-]*|' # hostname only. My soul dies a little every time this is used... r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip ) - + # Include search for port if it is needed. if inc_port: search = (search + r'(?::\d+)?' + r'(?:/?|[/?]\S+)$') else: From cb6cc553019412e1ad74adb97a83b05a3f250625 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Wed, 26 Dec 2018 23:23:21 -0500 Subject: [PATCH 10/37] Update Tautulli structures. Fixes #73 --- varken/structures.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/varken/structures.py b/varken/structures.py index accd4fe..2f714db 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -142,6 +142,8 @@ class TautulliStream(NamedTuple): subtitles: int = None stream_subtitle_language: str = None channel_stream: int = None + channel_icon: str = None + channel_title: str = None video_bitrate: str = None is_allow_sync: int = None stream_video_bitrate: str = None @@ -297,6 +299,7 @@ class TautulliStream(NamedTuple): stream_subtitle_container: str = None sub_type: str = None extra_type: str = None + _cache_time: str = None class TVShow(NamedTuple): From 7645f969cc7c98c1d65901f1d6220ea9944f4428 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Thu, 27 Dec 2018 00:45:38 -0500 Subject: [PATCH 11/37] Remove _cache_time --- varken/structures.py | 1 - 1 file changed, 1 deletion(-) diff --git a/varken/structures.py b/varken/structures.py index 2f714db..ef00b6e 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -299,7 +299,6 @@ class TautulliStream(NamedTuple): stream_subtitle_container: str = None sub_type: str = None extra_type: str = None - _cache_time: str = None class TVShow(NamedTuple): From 19bd10be320b5c9e1f03b06ac9e904494c06f22c Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Thu, 27 Dec 2018 10:22:45 -0500 Subject: [PATCH 12/37] Update config example --- data/varken.example.ini | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/data/varken.example.ini b/data/varken.example.ini index ef52b56..39c382b 100644 --- a/data/varken.example.ini +++ b/data/varken.example.ini @@ -2,7 +2,7 @@ # - Sonarr + Radarr scripts support multiple servers. You can remove the second # server by putting a # in front of the lines and section name, and removing # that number from your server_ids list -# - fallback_ip, This is used when there is no IP listed in tautulli. +# - fallback_ip, This is used when there is no IP listed in Tautulli. # This can happen when you are streaming locally. This is usually your public IP. [global] @@ -16,12 +16,12 @@ sickchill_server_ids = false [influxdb] url = influxdb.domain.tld port = 8086 -username = -password = +username = root +password = root [tautulli-1] url = tautulli.domain.tld:8181 -fallback_ip = 0.0.0.0 +fallback_ip = 1.1.1.1 apikey = xxxxxxxxxxxxxxxx ssl = false verify_ssl = false @@ -92,8 +92,6 @@ verify_ssl = false get_missing = true get_missing_run_seconds = 300 - - [ciscoasa-1] url = firewall.domain.tld username = cisco From 3dd3a2c732422836009bc03648bece7d11e9f633 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Thu, 27 Dec 2018 11:24:45 -0500 Subject: [PATCH 13/37] Fix first run exception --- varken/helpers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/varken/helpers.py b/varken/helpers.py index 0a5d166..492cebf 100644 --- a/varken/helpers.py +++ b/varken/helpers.py @@ -39,6 +39,8 @@ class GeoIPHandler(object): except FileNotFoundError: self.logger.error("Could not find GeoLite2 DB as: %s", self.dbfile) self.download() + dbdate = date.fromtimestamp(stat(self.dbfile).st_ctime) + first_wednesday_day = [week[2:3][0] for week in monthcalendar(today.year, today.month) if week[2:3][0] != 0][0] first_wednesday_date = date(today.year, today.month, first_wednesday_day) From e7ac122db319b37e3712311820856a787c68f84a Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Thu, 27 Dec 2018 12:33:35 -0500 Subject: [PATCH 14/37] Add spacing --- varken/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/varken/helpers.py b/varken/helpers.py index 492cebf..beae9af 100644 --- a/varken/helpers.py +++ b/varken/helpers.py @@ -40,7 +40,7 @@ class GeoIPHandler(object): self.logger.error("Could not find GeoLite2 DB as: %s", self.dbfile) self.download() dbdate = date.fromtimestamp(stat(self.dbfile).st_ctime) - + first_wednesday_day = [week[2:3][0] for week in monthcalendar(today.year, today.month) if week[2:3][0] != 0][0] first_wednesday_date = date(today.year, today.month, first_wednesday_day) From 1ee99481e408a1588b5f7e17897a75d90be83557 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Thu, 27 Dec 2018 13:25:39 -0500 Subject: [PATCH 15/37] Fix Ombi tv request status --- varken/ombi.py | 15 ++++++++++++--- varken/structures.py | 3 +++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/varken/ombi.py b/varken/ombi.py index f9a4830..c535aba 100644 --- a/varken/ombi.py +++ b/varken/ombi.py @@ -66,13 +66,17 @@ class OmbiAPI(object): for movie in movie_requests: hash_id = hashit(f'{movie.id}{movie.theMovieDbId}{movie.title}') status = None + # Denied = 0, Approved = 1, Completed = 2, Pending = 3 if movie.denied: status = 0 + elif movie.approved and movie.available: status = 2 + elif movie.approved: status = 1 + else: status = 3 @@ -97,14 +101,19 @@ class OmbiAPI(object): for show in tv_show_requests: hash_id = hashit(f'{show.id}{show.tvDbId}{show.title}') + status = None # Denied = 0, Approved = 1, Completed = 2, Pending = 3 - if show.childRequests[0]['denied']: + if show.childRequests[0]['denied'] is True: status = 0 - elif show.childRequests[0]['approved'] and show.childRequests[0]['available']: + print(str(show.childRequests[0]['denied']) + ' ' + show.title) + + elif show.childRequests[0]['approved'] is True and show.childRequests[0]['available'] is True: status = 2 - elif show.childRequests[0]['approved']: + + elif show.childRequests[0]['approved'] is True: status = 1 + else: status = 3 diff --git a/varken/structures.py b/varken/structures.py index ef00b6e..bfc297c 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -410,6 +410,9 @@ class OmbiTVRequest(NamedTuple): totalSeasons: int = None childRequests: list = None id: int = None + denied: bool = None + markedAsDenied: str = None + deniedReason: None = None class SickChillTVShow(NamedTuple): From eba291f87eaa06e95171be203d269400b7dc2b54 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Thu, 27 Dec 2018 13:50:00 -0500 Subject: [PATCH 16/37] Remove debug --- varken/ombi.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/varken/ombi.py b/varken/ombi.py index c535aba..bd5e041 100644 --- a/varken/ombi.py +++ b/varken/ombi.py @@ -104,14 +104,13 @@ class OmbiAPI(object): status = None # Denied = 0, Approved = 1, Completed = 2, Pending = 3 - if show.childRequests[0]['denied'] is True: + if show.childRequests[0]['denied']: status = 0 - print(str(show.childRequests[0]['denied']) + ' ' + show.title) - elif show.childRequests[0]['approved'] is True and show.childRequests[0]['available'] is True: + elif show.childRequests[0]['approved'] and show.childRequests[0]['available']: status = 2 - elif show.childRequests[0]['approved'] is True: + elif show.childRequests[0]['approved']: status = 1 else: From f950b3719f5e28ae58c940dca03a7480c9b95fec Mon Sep 17 00:00:00 2001 From: Oscar Andersson Date: Thu, 27 Dec 2018 20:02:44 +0100 Subject: [PATCH 17/37] Add Ombi issues counter --- Varken.py | 2 ++ data/varken.example.ini | 3 +++ varken/iniparser.py | 6 +++++- varken/ombi.py | 30 +++++++++++++++++++++++++++++- varken/structures.py | 7 +++++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Varken.py b/Varken.py index 20aea2b..b0b5ab9 100644 --- a/Varken.py +++ b/Varken.py @@ -121,6 +121,8 @@ if __name__ == "__main__": schedule.every(server.request_type_run_seconds).seconds.do(threaded, OMBI.get_request_counts) if server.request_total_counts: schedule.every(server.request_total_run_seconds).seconds.do(threaded, OMBI.get_all_requests) + if server.request_issues_counts: + schedule.every(server.request_issues_type_run_seconds).seconds.do(threaded, OMBI.get_issues_counts) if CONFIG.sickchill_enabled: for server in CONFIG.sickchill_servers: diff --git a/data/varken.example.ini b/data/varken.example.ini index 39c382b..e1db4da 100644 --- a/data/varken.example.ini +++ b/data/varken.example.ini @@ -83,6 +83,9 @@ get_request_type_counts = true request_type_run_seconds = 300 get_request_total_counts = true request_total_run_seconds = 300 +get_request_issues_counts = true +request_type_issues_run_seconds = 300 + [sickchill-1] url = sickchill.domain.tld:8081 diff --git a/varken/iniparser.py b/varken/iniparser.py index c920d96..a304450 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -179,9 +179,13 @@ class INIParser(object): request_total_run_seconds = self.config.getint(section, 'request_total_run_seconds') + request_issues_counts = self.config.getboolean(section, 'get_request_issues_counts') + + request_issues_type_run_seconds = self.config.getint(section, 'request_type_issues_run_seconds') + server = OmbiServer(server_id, scheme + url, apikey, verify_ssl, request_type_counts, request_type_run_seconds, request_total_counts, - request_total_run_seconds) + request_total_run_seconds, request_issues_counts, request_issues_type_run_seconds) if service == 'sickchill': get_missing = self.config.getboolean(section, 'get_missing') diff --git a/varken/ombi.py b/varken/ombi.py index c535aba..03cd8c3 100644 --- a/varken/ombi.py +++ b/varken/ombi.py @@ -3,7 +3,7 @@ from requests import Session, Request from datetime import datetime, timezone from varken.helpers import connection_handler, hashit -from varken.structures import OmbiRequestCounts, OmbiMovieRequest, OmbiTVRequest +from varken.structures import OmbiRequestCounts, OmbiIssuesCounts, OmbiMovieRequest, OmbiTVRequest class OmbiAPI(object): @@ -165,3 +165,31 @@ class OmbiAPI(object): ] self.dbmanager.write_points(influx_payload) + + def get_issues_counts(self): + now = datetime.now(timezone.utc).astimezone().isoformat() + endpoint = '/api/v1/Issues/count' + + req = self.session.prepare_request(Request('GET', self.server.url + endpoint)) + get = connection_handler(self.session, req, self.server.verify_ssl) + + if not get: + return + + requests = OmbiIssuesCounts(**get) + influx_payload = [ + { + "measurement": "Ombi", + "tags": { + "type": "Issues_Counts" + }, + "time": now, + "fields": { + "pending": requests.pending, + "in_progress": requests.inProgress, + "resolved": requests.resolved + } + } + ] + + self.dbmanager.write_points(influx_payload) diff --git a/varken/structures.py b/varken/structures.py index bfc297c..7b57f85 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -61,6 +61,8 @@ class OmbiServer(NamedTuple): request_type_run_seconds: int = 30 request_total_counts: bool = False request_total_run_seconds: int = 30 + request_issues_counts: bool = False + request_issues_type_run_seconds: int = 30 class TautulliServer(NamedTuple): @@ -106,6 +108,11 @@ class OmbiRequestCounts(NamedTuple): approved: int = 0 available: int = 0 +class OmbiIssuesCounts(NamedTuple): + pending: int = 0 + inProgress: int = 0 + resolved: int = 0 + class TautulliStream(NamedTuple): rating: str = None From e393b330a41af908fa733b94cb4c965becc83054 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Thu, 27 Dec 2018 15:56:49 -0500 Subject: [PATCH 18/37] Update failback_ip info --- data/varken.example.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/varken.example.ini b/data/varken.example.ini index 39c382b..1090f71 100644 --- a/data/varken.example.ini +++ b/data/varken.example.ini @@ -3,7 +3,7 @@ # server by putting a # in front of the lines and section name, and removing # that number from your server_ids list # - fallback_ip, This is used when there is no IP listed in Tautulli. -# This can happen when you are streaming locally. This is usually your public IP. +# This can happen when you are streaming locally. Set this to your public IP. [global] sonarr_server_ids = 1,2 From 2efa38507eb2a04585af1639448a23cc47081908 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Thu, 27 Dec 2018 15:57:34 -0500 Subject: [PATCH 19/37] More words --- data/varken.example.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/varken.example.ini b/data/varken.example.ini index 1090f71..80b9e81 100644 --- a/data/varken.example.ini +++ b/data/varken.example.ini @@ -4,6 +4,8 @@ # that number from your server_ids list # - fallback_ip, This is used when there is no IP listed in Tautulli. # This can happen when you are streaming locally. Set this to your public IP. +# You do not need to change this value if your IP changes. This is only for +# location lookups when there is a failure. [global] sonarr_server_ids = 1,2 From ba63276df3781a84b8b1777d8aab84a9a0d32a25 Mon Sep 17 00:00:00 2001 From: Oscar Andersson Date: Thu, 27 Dec 2018 22:07:41 +0100 Subject: [PATCH 20/37] Add possibility to get all issues --- Varken.py | 2 ++ data/varken.example.ini | 3 +- varken/iniparser.py | 8 +++++- varken/ombi.py | 61 ++++++++++++++++++++++++++++++++++++++++- varken/structures.py | 18 ++++++++++++ 5 files changed, 89 insertions(+), 3 deletions(-) diff --git a/Varken.py b/Varken.py index b0b5ab9..99ab580 100644 --- a/Varken.py +++ b/Varken.py @@ -123,6 +123,8 @@ if __name__ == "__main__": schedule.every(server.request_total_run_seconds).seconds.do(threaded, OMBI.get_all_requests) if server.request_issues_counts: schedule.every(server.request_issues_type_run_seconds).seconds.do(threaded, OMBI.get_issues_counts) + if server.issues_total_counts: + schedule.every(server.issues_total_run_seconds).seconds.do(threaded, OMBI.get_all_issues) if CONFIG.sickchill_enabled: for server in CONFIG.sickchill_servers: diff --git a/data/varken.example.ini b/data/varken.example.ini index e1db4da..ffec3e5 100644 --- a/data/varken.example.ini +++ b/data/varken.example.ini @@ -85,7 +85,8 @@ get_request_total_counts = true request_total_run_seconds = 300 get_request_issues_counts = true request_type_issues_run_seconds = 300 - +get_issues_total_counts = true +issues_total_run_seconds = 300 [sickchill-1] url = sickchill.domain.tld:8081 diff --git a/varken/iniparser.py b/varken/iniparser.py index a304450..76552e1 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -183,9 +183,15 @@ class INIParser(object): request_issues_type_run_seconds = self.config.getint(section, 'request_type_issues_run_seconds') + issues_total_counts = self.config.getboolean(section, 'get_issues_total_counts') + + issues_total_run_seconds = self.config.getint(section, 'issues_total_run_seconds') + server = OmbiServer(server_id, scheme + url, apikey, verify_ssl, request_type_counts, request_type_run_seconds, request_total_counts, - request_total_run_seconds, request_issues_counts, request_issues_type_run_seconds) + request_total_run_seconds, request_issues_counts, + request_issues_type_run_seconds, issues_total_counts, + issues_total_run_seconds) if service == 'sickchill': get_missing = self.config.getboolean(section, 'get_missing') diff --git a/varken/ombi.py b/varken/ombi.py index 03cd8c3..e0e8831 100644 --- a/varken/ombi.py +++ b/varken/ombi.py @@ -3,7 +3,7 @@ from requests import Session, Request from datetime import datetime, timezone from varken.helpers import connection_handler, hashit -from varken.structures import OmbiRequestCounts, OmbiIssuesCounts, OmbiMovieRequest, OmbiTVRequest +from varken.structures import OmbiRequestCounts, OmbiIssuesCounts, OmbiIssue, OmbiMovieRequest, OmbiTVRequest class OmbiAPI(object): @@ -193,3 +193,62 @@ class OmbiAPI(object): ] self.dbmanager.write_points(influx_payload) + + def get_all_issues(self): + now = datetime.now(timezone.utc).astimezone().isoformat() + endpoint = '/api/v1/Issues/' + + req = self.session.prepare_request(Request('GET', self.server.url + endpoint)) + get_issues = connection_handler(self.session, req, self.server.verify_ssl) + + + if not any([get_issues]): + self.logger.error('No json replies. Discarding job') + return + + issues_count = len(get_issues) + + try: + issue_list = [OmbiIssue(**issue) for issue in get_issues] + except TypeError as e: + self.logger.error('TypeError has occurred : %s while creating OmbiIssue structure', e) + return + + influx_payload = [ + { + "measurement": "Ombi", + "tags": { + "type": "Issues_Total", + "server": self.server.id + }, + "time": now, + "fields": { + "total": issues_count + } + } + ] + # Request Type: Movie = 1, TV Show = 0 + # Status: 0 = Pending, 1 = In Progress, 2 = Resolved + for issue in issue_list: + hash_id = hashit(f'{issue.id}{issue.requestId}{issue.title}') + + influx_payload.append( + { + "measurement": "Ombi", + "tags": { + "type": "Issues", + "server": self.server.id, + "request_type": issue.requestType, + "status": issue.status, + "title": issue.title, + "subject": issue.subject, + "description": issue.description + }, + "time": now, + "fields": { + "hash": hash_id + } + } + ) + + self.dbmanager.write_points(influx_payload) \ No newline at end of file diff --git a/varken/structures.py b/varken/structures.py index 7b57f85..721a0fe 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -63,6 +63,8 @@ class OmbiServer(NamedTuple): request_total_run_seconds: int = 30 request_issues_counts: bool = False request_issues_type_run_seconds: int = 30 + issues_total_counts: bool = False + issues_total_run_seconds: int = 30 class TautulliServer(NamedTuple): @@ -402,6 +404,22 @@ class OmbiMovieRequest(NamedTuple): canApprove: bool = None id: int = None +class OmbiIssue(NamedTuple): + title: str = None + requestType: int = None + providerId: int = None + requestId: int = None + subject: str = None + description: str = None + issueCategoryId: int = None + issueCategory: dict = None + status: int = None + resovledDate: None = None + userReportedId: str = None + userReported: str = None + comments: str = None + id: int = None + class OmbiTVRequest(NamedTuple): tvDbId: int = None From ec85c4b4a62870b448f3a715ebb7a30c0cffcc7d Mon Sep 17 00:00:00 2001 From: Oscar Andersson Date: Thu, 27 Dec 2018 22:28:36 +0100 Subject: [PATCH 21/37] Fix variable names to follow structure --- Varken.py | 8 ++++---- data/varken.example.ini | 8 ++++---- varken/iniparser.py | 14 +++++++------- varken/ombi.py | 2 +- varken/structures.py | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Varken.py b/Varken.py index 99ab580..a377098 100644 --- a/Varken.py +++ b/Varken.py @@ -121,10 +121,10 @@ if __name__ == "__main__": schedule.every(server.request_type_run_seconds).seconds.do(threaded, OMBI.get_request_counts) if server.request_total_counts: schedule.every(server.request_total_run_seconds).seconds.do(threaded, OMBI.get_all_requests) - if server.request_issues_counts: - schedule.every(server.request_issues_type_run_seconds).seconds.do(threaded, OMBI.get_issues_counts) - if server.issues_total_counts: - schedule.every(server.issues_total_run_seconds).seconds.do(threaded, OMBI.get_all_issues) + if server.issue_status_counts: + schedule.every(server.issue_status_run_seconds).seconds.do(threaded, OMBI.get_issue_counts) + if server.issue_total_counts: + schedule.every(server.issue_total_run_seconds).seconds.do(threaded, OMBI.get_all_issues) if CONFIG.sickchill_enabled: for server in CONFIG.sickchill_servers: diff --git a/data/varken.example.ini b/data/varken.example.ini index ffec3e5..6069be3 100644 --- a/data/varken.example.ini +++ b/data/varken.example.ini @@ -83,10 +83,10 @@ get_request_type_counts = true request_type_run_seconds = 300 get_request_total_counts = true request_total_run_seconds = 300 -get_request_issues_counts = true -request_type_issues_run_seconds = 300 -get_issues_total_counts = true -issues_total_run_seconds = 300 +get_issue_status_counts = true +issue_status_run_seconds = 300 +get_issue_total_counts = true +issue_total_run_seconds = 300 [sickchill-1] url = sickchill.domain.tld:8081 diff --git a/varken/iniparser.py b/varken/iniparser.py index 76552e1..67d0b9b 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -179,19 +179,19 @@ class INIParser(object): request_total_run_seconds = self.config.getint(section, 'request_total_run_seconds') - request_issues_counts = self.config.getboolean(section, 'get_request_issues_counts') + issue_status_counts = self.config.getboolean(section, 'get_issue_status_counts') - request_issues_type_run_seconds = self.config.getint(section, 'request_type_issues_run_seconds') + issue_status_run_seconds = self.config.getint(section, 'issue_status_run_seconds') - issues_total_counts = self.config.getboolean(section, 'get_issues_total_counts') + issue_total_counts = self.config.getboolean(section, 'get_issue_total_counts') - issues_total_run_seconds = self.config.getint(section, 'issues_total_run_seconds') + issue_total_run_seconds = self.config.getint(section, 'issue_total_run_seconds') server = OmbiServer(server_id, scheme + url, apikey, verify_ssl, request_type_counts, request_type_run_seconds, request_total_counts, - request_total_run_seconds, request_issues_counts, - request_issues_type_run_seconds, issues_total_counts, - issues_total_run_seconds) + request_total_run_seconds, issue_status_counts, + issue_status_run_seconds, issue_total_counts, + issue_total_run_seconds) if service == 'sickchill': get_missing = self.config.getboolean(section, 'get_missing') diff --git a/varken/ombi.py b/varken/ombi.py index e0e8831..c3f1d36 100644 --- a/varken/ombi.py +++ b/varken/ombi.py @@ -166,7 +166,7 @@ class OmbiAPI(object): self.dbmanager.write_points(influx_payload) - def get_issues_counts(self): + def get_issue_counts(self): now = datetime.now(timezone.utc).astimezone().isoformat() endpoint = '/api/v1/Issues/count' diff --git a/varken/structures.py b/varken/structures.py index 721a0fe..dec726b 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -61,10 +61,10 @@ class OmbiServer(NamedTuple): request_type_run_seconds: int = 30 request_total_counts: bool = False request_total_run_seconds: int = 30 - request_issues_counts: bool = False - request_issues_type_run_seconds: int = 30 - issues_total_counts: bool = False - issues_total_run_seconds: int = 30 + issue_status_counts: bool = False + issue_status_run_seconds: int = 30 + issue_total_counts: bool = False + issue_total_run_seconds: int = 30 class TautulliServer(NamedTuple): From 8d09a784b8eb1368a9a7b38e2148202829d3f96d Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Thu, 27 Dec 2018 18:49:43 -0500 Subject: [PATCH 22/37] Actually fix tv request status --- varken/ombi.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/varken/ombi.py b/varken/ombi.py index bd5e041..6230170 100644 --- a/varken/ombi.py +++ b/varken/ombi.py @@ -65,7 +65,6 @@ class OmbiAPI(object): # Request Type: Movie = 1, TV Show = 0 for movie in movie_requests: hash_id = hashit(f'{movie.id}{movie.theMovieDbId}{movie.title}') - status = None # Denied = 0, Approved = 1, Completed = 2, Pending = 3 if movie.denied: @@ -101,7 +100,6 @@ class OmbiAPI(object): for show in tv_show_requests: hash_id = hashit(f'{show.id}{show.tvDbId}{show.title}') - status = None # Denied = 0, Approved = 1, Completed = 2, Pending = 3 if show.childRequests[0]['denied']: From dfcbee4eb40d3e9832e2823951db8874c51ce636 Mon Sep 17 00:00:00 2001 From: Oscar Andersson Date: Sat, 29 Dec 2018 20:46:28 +0100 Subject: [PATCH 23/37] Remove detailed version of issues --- Varken.py | 2 -- data/varken.example.ini | 2 -- varken/iniparser.py | 7 +---- varken/ombi.py | 61 +---------------------------------------- varken/structures.py | 18 ------------ 5 files changed, 2 insertions(+), 88 deletions(-) diff --git a/Varken.py b/Varken.py index a377098..c157646 100644 --- a/Varken.py +++ b/Varken.py @@ -123,8 +123,6 @@ if __name__ == "__main__": schedule.every(server.request_total_run_seconds).seconds.do(threaded, OMBI.get_all_requests) if server.issue_status_counts: schedule.every(server.issue_status_run_seconds).seconds.do(threaded, OMBI.get_issue_counts) - if server.issue_total_counts: - schedule.every(server.issue_total_run_seconds).seconds.do(threaded, OMBI.get_all_issues) if CONFIG.sickchill_enabled: for server in CONFIG.sickchill_servers: diff --git a/data/varken.example.ini b/data/varken.example.ini index 6069be3..d7d858b 100644 --- a/data/varken.example.ini +++ b/data/varken.example.ini @@ -85,8 +85,6 @@ get_request_total_counts = true request_total_run_seconds = 300 get_issue_status_counts = true issue_status_run_seconds = 300 -get_issue_total_counts = true -issue_total_run_seconds = 300 [sickchill-1] url = sickchill.domain.tld:8081 diff --git a/varken/iniparser.py b/varken/iniparser.py index 67d0b9b..beb4d3f 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -183,15 +183,10 @@ class INIParser(object): issue_status_run_seconds = self.config.getint(section, 'issue_status_run_seconds') - issue_total_counts = self.config.getboolean(section, 'get_issue_total_counts') - - issue_total_run_seconds = self.config.getint(section, 'issue_total_run_seconds') - server = OmbiServer(server_id, scheme + url, apikey, verify_ssl, request_type_counts, request_type_run_seconds, request_total_counts, request_total_run_seconds, issue_status_counts, - issue_status_run_seconds, issue_total_counts, - issue_total_run_seconds) + issue_status_run_seconds) if service == 'sickchill': get_missing = self.config.getboolean(section, 'get_missing') diff --git a/varken/ombi.py b/varken/ombi.py index c3f1d36..ebf3af5 100644 --- a/varken/ombi.py +++ b/varken/ombi.py @@ -3,7 +3,7 @@ from requests import Session, Request from datetime import datetime, timezone from varken.helpers import connection_handler, hashit -from varken.structures import OmbiRequestCounts, OmbiIssuesCounts, OmbiIssue, OmbiMovieRequest, OmbiTVRequest +from varken.structures import OmbiRequestCounts, OmbiIssuesCounts, OmbiMovieRequest, OmbiTVRequest class OmbiAPI(object): @@ -192,63 +192,4 @@ class OmbiAPI(object): } ] - self.dbmanager.write_points(influx_payload) - - def get_all_issues(self): - now = datetime.now(timezone.utc).astimezone().isoformat() - endpoint = '/api/v1/Issues/' - - req = self.session.prepare_request(Request('GET', self.server.url + endpoint)) - get_issues = connection_handler(self.session, req, self.server.verify_ssl) - - - if not any([get_issues]): - self.logger.error('No json replies. Discarding job') - return - - issues_count = len(get_issues) - - try: - issue_list = [OmbiIssue(**issue) for issue in get_issues] - except TypeError as e: - self.logger.error('TypeError has occurred : %s while creating OmbiIssue structure', e) - return - - influx_payload = [ - { - "measurement": "Ombi", - "tags": { - "type": "Issues_Total", - "server": self.server.id - }, - "time": now, - "fields": { - "total": issues_count - } - } - ] - # Request Type: Movie = 1, TV Show = 0 - # Status: 0 = Pending, 1 = In Progress, 2 = Resolved - for issue in issue_list: - hash_id = hashit(f'{issue.id}{issue.requestId}{issue.title}') - - influx_payload.append( - { - "measurement": "Ombi", - "tags": { - "type": "Issues", - "server": self.server.id, - "request_type": issue.requestType, - "status": issue.status, - "title": issue.title, - "subject": issue.subject, - "description": issue.description - }, - "time": now, - "fields": { - "hash": hash_id - } - } - ) - self.dbmanager.write_points(influx_payload) \ No newline at end of file diff --git a/varken/structures.py b/varken/structures.py index dec726b..4916fee 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -63,8 +63,6 @@ class OmbiServer(NamedTuple): request_total_run_seconds: int = 30 issue_status_counts: bool = False issue_status_run_seconds: int = 30 - issue_total_counts: bool = False - issue_total_run_seconds: int = 30 class TautulliServer(NamedTuple): @@ -404,22 +402,6 @@ class OmbiMovieRequest(NamedTuple): canApprove: bool = None id: int = None -class OmbiIssue(NamedTuple): - title: str = None - requestType: int = None - providerId: int = None - requestId: int = None - subject: str = None - description: str = None - issueCategoryId: int = None - issueCategory: dict = None - status: int = None - resovledDate: None = None - userReportedId: str = None - userReported: str = None - comments: str = None - id: int = None - class OmbiTVRequest(NamedTuple): tvDbId: int = None From 0629c61a29dde252f8a8e0cbdd02f9bfe64a68ce Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sat, 29 Dec 2018 21:57:48 -0600 Subject: [PATCH 24/37] pep8 for merge + changes --- varken/helpers.py | 3 +-- varken/iniparser.py | 7 ++++--- varken/ombi.py | 2 +- varken/structures.py | 1 + 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/varken/helpers.py b/varken/helpers.py index beae9af..648eb5a 100644 --- a/varken/helpers.py +++ b/varken/helpers.py @@ -33,7 +33,7 @@ class GeoIPHandler(object): def update(self): today = date.today() - dbdate = None + try: dbdate = date.fromtimestamp(stat(self.dbfile).st_ctime) except FileNotFoundError: @@ -55,7 +55,6 @@ class GeoIPHandler(object): else: self.logger.debug('Geolite2 DB will update in %s days', abs(td.days)) - def download(self): tar_dbfile = abspath(join(self.data_folder, 'GeoLite2-City.tar.gz')) url = 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz' diff --git a/varken/iniparser.py b/varken/iniparser.py index beb4d3f..badbdc4 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -66,7 +66,7 @@ class INIParser(object): search = (r'(?:([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}|' # domain... r'localhost|' # localhost... - r'^[a-zA-Z0-9_-]*|' # hostname only. My soul dies a little every time this is used... + r'^[a-zA-Z0-9_-]*|' # hostname only. My soul dies a little every time this is used... r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip ) # Include search for port if it is needed. @@ -80,7 +80,8 @@ class INIParser(object): valid = match(regex, url_check) is not None if not valid: if inc_port: - self.logger.error('%s is invalid in module [%s]! URL must host/IP and port if not 80 or 443. ie. localhost:8080', + self.logger.error('%s is invalid in module [%s]! URL must host/IP and ' + 'port if not 80 or 443. ie. localhost:8080', url_check, module) exit(1) else: @@ -185,7 +186,7 @@ class INIParser(object): server = OmbiServer(server_id, scheme + url, apikey, verify_ssl, request_type_counts, request_type_run_seconds, request_total_counts, - request_total_run_seconds, issue_status_counts, + request_total_run_seconds, issue_status_counts, issue_status_run_seconds) if service == 'sickchill': diff --git a/varken/ombi.py b/varken/ombi.py index 7299273..86f8e33 100644 --- a/varken/ombi.py +++ b/varken/ombi.py @@ -189,4 +189,4 @@ class OmbiAPI(object): } ] - self.dbmanager.write_points(influx_payload) \ No newline at end of file + self.dbmanager.write_points(influx_payload) diff --git a/varken/structures.py b/varken/structures.py index 4916fee..694b8cc 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -108,6 +108,7 @@ class OmbiRequestCounts(NamedTuple): approved: int = 0 available: int = 0 + class OmbiIssuesCounts(NamedTuple): pending: int = 0 inProgress: int = 0 From c95f7519a53e8666f3784b39d3edba20f950a893 Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sat, 29 Dec 2018 22:04:39 -0600 Subject: [PATCH 25/37] add ability to filter by encoding/decoding status --- varken/tautulli.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/varken/tautulli.py b/varken/tautulli.py index 5bde35a..336bba9 100644 --- a/varken/tautulli.py +++ b/varken/tautulli.py @@ -108,6 +108,8 @@ class TautulliAPI(object): "quality": quality, "video_decision": video_decision.title(), "transcode_decision": decision.title(), + "transcode_hw_decoding": session.transcode_hw_decoding, + "transcode_hw_encoding": session.transcode_hw_encoding, "media_type": session.media_type.title(), "audio_codec": session.audio_codec.upper(), "audio_profile": session.audio_profile.upper(), From 570d90c7209722dfe19f65bd79f5c4f8f24eeb58 Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sat, 29 Dec 2018 22:33:58 -0600 Subject: [PATCH 26/37] add missing key lastSearchTime --- varken/structures.py | 1 + 1 file changed, 1 insertion(+) diff --git a/varken/structures.py b/varken/structures.py index 694b8cc..7339d17 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -327,6 +327,7 @@ class TVShow(NamedTuple): sceneEpisodeNumber: int = None sceneSeasonNumber: int = None series: dict = None + lastSearchTime: str = None id: int = None From 6f2979151b179318ff438a4eeb4f991cdda55aa8 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Sat, 29 Dec 2018 23:52:35 -0500 Subject: [PATCH 27/37] Update the python min version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe68aa7..e3a6b29 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ from the Plex ecosystem into InfluxDB. Examples use Grafana for a frontend Requirements: -* Python3.6+ +* Python3.6.7+ * Python3-pip * [InfluxDB](https://www.influxdata.com/) From 92c634f3ebafb137f45ca4a9cd54eb6203484ce2 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Sun, 30 Dec 2018 01:01:12 -0500 Subject: [PATCH 28/37] Force minimum python minor version --- varken/structures.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/varken/structures.py b/varken/structures.py index 7339d17..c5f3994 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -4,9 +4,9 @@ from logging import getLogger logger = getLogger('temp') # Check for python3.6 or newer to resolve erroneous typing.NamedTuple issues -if version_info < (3, 6): - logger.error('Varken requires python3.6 or newer. You are on python%s.%s - Exiting...', - version_info.major, version_info.minor) +if version_info < (3, 6, 2): + logger.error('Varken requires python3.6.2 or newer. You are on python%s.%s.%s - Exiting...', + version_info.major, version_info.minor, version_info.micro) exit(1) From 70a6a306280ecb539766ce7e18eb84776e8dee7f Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sun, 30 Dec 2018 00:06:01 -0600 Subject: [PATCH 29/37] add missing key addOptions and removed space. Fixes #68 --- varken/structures.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/varken/structures.py b/varken/structures.py index c5f3994..aa4b0ad 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -6,7 +6,7 @@ logger = getLogger('temp') # Check for python3.6 or newer to resolve erroneous typing.NamedTuple issues if version_info < (3, 6, 2): logger.error('Varken requires python3.6.2 or newer. You are on python%s.%s.%s - Exiting...', - version_info.major, version_info.minor, version_info.micro) + version_info.major, version_info.minor, version_info.micro) exit(1) @@ -369,6 +369,7 @@ class Movie(NamedTuple): physicalRelease: str = None physicalReleaseNote: str = None website: str = None + addOptions: str = None id: int = None From 49fa4c1a6e31b9709a08ed032340ba4fbf7df89d Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sun, 30 Dec 2018 00:10:51 -0600 Subject: [PATCH 30/37] sorted for easier key search6 --- varken/structures.py | 620 +++++++++++++++++++++---------------------- 1 file changed, 310 insertions(+), 310 deletions(-) diff --git a/varken/structures.py b/varken/structures.py index aa4b0ad..baf8549 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -11,426 +11,426 @@ if version_info < (3, 6, 2): class Queue(NamedTuple): - movie: dict = None - series: dict = None - episode: dict = None - quality: dict = None - size: float = None - title: str = None - sizeleft: float = None - timeleft: str = None - estimatedCompletionTime: str = None - status: str = None - trackedDownloadStatus: str = None - statusMessages: list = None downloadId: str = None - protocol: str = None + episode: dict = None + estimatedCompletionTime: str = None id: int = None + movie: dict = None + protocol: str = None + quality: dict = None + series: dict = None + size: float = None + sizeleft: float = None + status: str = None + statusMessages: list = None + timeleft: str = None + title: str = None + trackedDownloadStatus: str = None class SonarrServer(NamedTuple): - id: int = None - url: str = None api_key: str = None - verify_ssl: bool = False - missing_days: int = 0 - missing_days_run_seconds: int = 30 future_days: int = 0 future_days_run_seconds: int = 30 + id: int = None + missing_days: int = 0 + missing_days_run_seconds: int = 30 queue: bool = False queue_run_seconds: int = 30 + url: str = None + verify_ssl: bool = False class RadarrServer(NamedTuple): - id: int = None - url: str = None api_key: str = None - verify_ssl: bool = False - queue: bool = False - queue_run_seconds: int = 30 get_missing: bool = False get_missing_run_seconds: int = 30 + id: int = None + queue: bool = False + queue_run_seconds: int = 30 + url: str = None + verify_ssl: bool = False class OmbiServer(NamedTuple): - id: int = None - url: str = None api_key: str = None - verify_ssl: bool = False - request_type_counts: bool = False - request_type_run_seconds: int = 30 - request_total_counts: bool = False - request_total_run_seconds: int = 30 + id: int = None issue_status_counts: bool = False issue_status_run_seconds: int = 30 + request_total_counts: bool = False + request_total_run_seconds: int = 30 + request_type_counts: bool = False + request_type_run_seconds: int = 30 + url: str = None + verify_ssl: bool = False class TautulliServer(NamedTuple): - id: int = None - url: str = None - fallback_ip: str = None api_key: str = None - verify_ssl: bool = None + fallback_ip: str = None get_activity: bool = False get_activity_run_seconds: int = 30 get_stats: bool = False get_stats_run_seconds: int = 30 + id: int = None + url: str = None + verify_ssl: bool = None class InfluxServer(NamedTuple): - url: str = 'localhost' - port: int = 8086 - username: str = 'root' password: str = 'root' + port: int = 8086 + url: str = 'localhost' + username: str = 'root' class SickChillServer(NamedTuple): - id: int = None - url: str = None api_key: str = None - verify_ssl: bool = False get_missing: bool = False get_missing_run_seconds: int = 30 + id: int = None + url: str = None + verify_ssl: bool = False class CiscoASAFirewall(NamedTuple): + get_bandwidth_run_seconds: int = 30 id: int = None + outside_interface: str = None + password: str = 'cisco' url: str = '192.168.1.1' username: str = 'cisco' - password: str = 'cisco' - outside_interface: str = None verify_ssl: bool = False - get_bandwidth_run_seconds: int = 30 class OmbiRequestCounts(NamedTuple): - pending: int = 0 approved: int = 0 available: int = 0 + pending: int = 0 class OmbiIssuesCounts(NamedTuple): - pending: int = 0 inProgress: int = 0 + pending: int = 0 resolved: int = 0 class TautulliStream(NamedTuple): - rating: str = None - transcode_width: str = None - labels: list = None - stream_bitrate: str = None - bandwidth: str = None - optimized_version: int = None - video_language: str = None - parent_rating_key: str = None - rating_key: str = None - platform_version: str = None - transcode_hw_decoding: int = None - thumb: str = None - title: str = None - video_codec_level: str = None - tagline: str = None - last_viewed_at: str = None - audio_sample_rate: str = None - user_rating: str = None - platform: str = None - collections: list = None - location: str = None - transcode_container: str = None - audio_channel_layout: str = None - local: str = None - stream_subtitle_format: str = None - stream_video_ref_frames: str = None - transcode_hw_encode_title: str = None - stream_container_decision: str = None - audience_rating: str = None - full_title: str = None - ip_address: str = None - subtitles: int = None - stream_subtitle_language: str = None - channel_stream: int = None - channel_icon: str = None - channel_title: str = None - video_bitrate: str = None - is_allow_sync: int = None - stream_video_bitrate: str = None - summary: str = None - stream_audio_decision: str = None - aspect_ratio: str = None - audio_bitrate_mode: str = None - transcode_hw_decode_title: str = None - stream_audio_channel_layout: str = None - deleted_user: int = None - library_name: str = None - art: str = None - stream_video_resolution: str = None - video_profile: str = None - sort_title: str = None - stream_video_codec_level: str = None - stream_video_height: str = None - year: str = None - stream_duration: str = None - stream_audio_channels: str = None - video_language_code: str = None - transcode_key: str = None - transcode_throttled: int = None - container: str = None - stream_audio_bitrate: str = None - user: str = None - selected: int = None - product_version: str = None - subtitle_location: str = None - transcode_hw_requested: int = None - video_height: str = None - state: str = None - is_restricted: int = None - email: str = None - stream_container: str = None - transcode_speed: str = None - video_bit_depth: str = None - stream_audio_sample_rate: str = None - grandparent_title: str = None - studio: str = None - transcode_decision: str = None - video_width: str = None - bitrate: str = None - machine_id: str = None - originally_available_at: str = None - video_frame_rate: str = None - synced_version_profile: str = None - friendly_name: str = None - audio_profile: str = None - optimized_version_title: str = None - platform_name: str = None - stream_video_language: str = None - keep_history: int = None - stream_audio_codec: str = None - stream_video_codec: str = None - grandparent_thumb: str = None - synced_version: int = None - transcode_hw_decode: str = None - user_thumb: str = None - stream_video_width: str = None - height: str = None - stream_subtitle_decision: str = None - audio_codec: str = None - parent_title: str = None - guid: str = None - audio_language_code: str = None - transcode_video_codec: str = None - transcode_audio_codec: str = None - stream_video_decision: str = None - user_id: int = None - transcode_height: str = None - transcode_hw_full_pipeline: int = None - throttled: str = None - quality_profile: str = None - width: str = None - live: int = None - stream_subtitle_forced: int = None - media_type: str = None - video_resolution: str = None - stream_subtitle_location: str = None - do_notify: int = None - video_ref_frames: str = None - stream_subtitle_language_code: str = None - audio_channels: str = None - stream_audio_language_code: str = None - optimized_version_profile: str = None - relay: int = None - duration: str = None - rating_image: str = None - is_home_user: int = None - is_admin: int = None - ip_address_public: str = None - allow_guest: int = None - transcode_audio_channels: str = None - stream_audio_channel_layout_: str = None - media_index: str = None - stream_video_framerate: str = None - transcode_hw_encode: str = None - grandparent_rating_key: str = None - original_title: str = None - added_at: str = None - banner: str = None - bif_thumb: str = None - parent_media_index: str = None - live_uuid: str = None - audio_language: str = None - stream_audio_bitrate_mode: str = None - username: str = None - subtitle_decision: str = None - children_count: str = None - updated_at: str = None - player: str = None - subtitle_format: str = None - file: str = None - file_size: str = None - session_key: str = None - id: str = None - subtitle_container: str = None - genres: list = None - stream_video_language_code: str = None - indexes: int = None - video_decision: str = None - stream_audio_language: str = None - writers: list = None actors: list = None - progress_percent: str = None - audio_decision: str = None - subtitle_forced: int = None - profile: str = None - product: str = None - view_offset: str = None - type: str = None + added_at: str = None + allow_guest: int = None + art: str = None + aspect_ratio: str = None + audience_rating: str = None audience_rating_image: str = None audio_bitrate: str = None - section_id: str = None - stream_subtitle_codec: str = None - subtitle_codec: str = None - video_codec: str = None - device: str = None - stream_video_bit_depth: str = None - video_framerate: str = None - transcode_hw_encoding: int = None - transcode_protocol: str = None - shared_libraries: list = None - stream_aspect_ratio: str = None + audio_bitrate_mode: str = None + audio_channels: str = None + audio_channel_layout: str = None + audio_codec: str = None + audio_decision: str = None + audio_language: str = None + audio_language_code: str = None + audio_profile: str = None + audio_sample_rate: str = None + bandwidth: str = None + banner: str = None + bif_thumb: str = None + bitrate: str = None + channel_icon: str = None + channel_stream: int = None + channel_title: str = None + children_count: str = None + collections: list = None + container: str = None content_rating: str = None - session_id: str = None + deleted_user: int = None + device: str = None directors: list = None - parent_thumb: str = None - subtitle_language_code: str = None - transcode_progress: int = None - subtitle_language: str = None - stream_subtitle_container: str = None - sub_type: str = None + do_notify: int = None + duration: str = None + email: str = None extra_type: str = None + file: str = None + file_size: str = None + friendly_name: str = None + full_title: str = None + genres: list = None + grandparent_rating_key: str = None + grandparent_thumb: str = None + grandparent_title: str = None + guid: str = None + height: str = None + id: str = None + indexes: int = None + ip_address: str = None + ip_address_public: str = None + is_admin: int = None + is_allow_sync: int = None + is_home_user: int = None + is_restricted: int = None + keep_history: int = None + labels: list = None + last_viewed_at: str = None + library_name: str = None + live: int = None + live_uuid: str = None + local: str = None + location: str = None + machine_id: str = None + media_index: str = None + media_type: str = None + optimized_version: int = None + optimized_version_profile: str = None + optimized_version_title: str = None + originally_available_at: str = None + original_title: str = None + parent_media_index: str = None + parent_rating_key: str = None + parent_thumb: str = None + parent_title: str = None + platform: str = None + platform_name: str = None + platform_version: str = None + player: str = None + product: str = None + product_version: str = None + profile: str = None + progress_percent: str = None + quality_profile: str = None + rating: str = None + rating_image: str = None + rating_key: str = None + relay: int = None + section_id: str = None + selected: int = None + session_id: str = None + session_key: str = None + shared_libraries: list = None + sort_title: str = None + state: str = None + stream_aspect_ratio: str = None + stream_audio_bitrate: str = None + stream_audio_bitrate_mode: str = None + stream_audio_channels: str = None + stream_audio_channel_layout: str = None + stream_audio_channel_layout_: str = None + stream_audio_codec: str = None + stream_audio_decision: str = None + stream_audio_language: str = None + stream_audio_language_code: str = None + stream_audio_sample_rate: str = None + stream_bitrate: str = None + stream_container: str = None + stream_container_decision: str = None + stream_duration: str = None + stream_subtitle_codec: str = None + stream_subtitle_container: str = None + stream_subtitle_decision: str = None + stream_subtitle_forced: int = None + stream_subtitle_format: str = None + stream_subtitle_language: str = None + stream_subtitle_language_code: str = None + stream_subtitle_location: str = None + stream_video_bitrate: str = None + stream_video_bit_depth: str = None + stream_video_codec: str = None + stream_video_codec_level: str = None + stream_video_decision: str = None + stream_video_framerate: str = None + stream_video_height: str = None + stream_video_language: str = None + stream_video_language_code: str = None + stream_video_ref_frames: str = None + stream_video_resolution: str = None + stream_video_width: str = None + studio: str = None + subtitles: int = None + subtitle_codec: str = None + subtitle_container: str = None + subtitle_decision: str = None + subtitle_forced: int = None + subtitle_format: str = None + subtitle_language: str = None + subtitle_language_code: str = None + subtitle_location: str = None + sub_type: str = None + summary: str = None + synced_version: int = None + synced_version_profile: str = None + tagline: str = None + throttled: str = None + thumb: str = None + title: str = None + transcode_audio_channels: str = None + transcode_audio_codec: str = None + transcode_container: str = None + transcode_decision: str = None + transcode_height: str = None + transcode_hw_decode: str = None + transcode_hw_decode_title: str = None + transcode_hw_decoding: int = None + transcode_hw_encode: str = None + transcode_hw_encode_title: str = None + transcode_hw_encoding: int = None + transcode_hw_full_pipeline: int = None + transcode_hw_requested: int = None + transcode_key: str = None + transcode_progress: int = None + transcode_protocol: str = None + transcode_speed: str = None + transcode_throttled: int = None + transcode_video_codec: str = None + transcode_width: str = None + type: str = None + updated_at: str = None + user: str = None + username: str = None + user_id: int = None + user_rating: str = None + user_thumb: str = None + video_bitrate: str = None + video_bit_depth: str = None + video_codec: str = None + video_codec_level: str = None + video_decision: str = None + video_framerate: str = None + video_frame_rate: str = None + video_height: str = None + video_language: str = None + video_language_code: str = None + video_profile: str = None + video_ref_frames: str = None + video_resolution: str = None + video_width: str = None + view_offset: str = None + width: str = None + writers: list = None + year: str = None class TVShow(NamedTuple): - seriesId: int = None - episodeFileId: int = None - seasonNumber: int = None - episodeNumber: int = None - title: str = None + absoluteEpisodeNumber: int = None airDate: str = None airDateUtc: str = None - overview: str = None episodeFile: dict = None + episodeFileId: int = None + episodeNumber: int = None hasFile: bool = None + id: int = None + lastSearchTime: str = None monitored: bool = None - unverifiedSceneNumbering: bool = None - absoluteEpisodeNumber: int = None + overview: str = None sceneAbsoluteEpisodeNumber: int = None sceneEpisodeNumber: int = None sceneSeasonNumber: int = None + seasonNumber: int = None series: dict = None - lastSearchTime: str = None - id: int = None + seriesId: int = None + title: str = None + unverifiedSceneNumbering: bool = None class Movie(NamedTuple): - title: str = None - alternativeTitles: list = None - secondaryYearSourceId: int = None - sortTitle: str = None - sizeOnDisk: int = None - status: str = None - overview: str = None - inCinemas: str = None - images: list = None - downloaded: bool = None - year: int = None - secondaryYear: str = None - hasFile: bool = None - youTubeTrailerId: str = None - studio: str = None - path: str = None - profileId: int = None - pathState: str = None - monitored: bool = None - minimumAvailability: str = None - isAvailable: bool = None - folderName: str = None - runtime: int = None - lastInfoSync: str = None - cleanTitle: str = None - imdbId: str = None - tmdbId: int = None - titleSlug: str = None - genres: list = None - tags: list = None added: str = None - ratings: dict = None + addOptions: str = None + alternativeTitles: list = None + cleanTitle: str = None + downloaded: bool = None + folderName: str = None + genres: list = None + hasFile: bool = None + id: int = None + images: list = None + imdbId: str = None + inCinemas: str = None + isAvailable: bool = None + lastInfoSync: str = None + minimumAvailability: str = None + monitored: bool = None movieFile: dict = None - qualityProfileId: int = None + overview: str = None + path: str = None + pathState: str = None physicalRelease: str = None physicalReleaseNote: str = None + profileId: int = None + qualityProfileId: int = None + ratings: dict = None + runtime: int = None + secondaryYear: str = None + secondaryYearSourceId: int = None + sizeOnDisk: int = None + sortTitle: str = None + status: str = None + studio: str = None + tags: list = None + title: str = None + titleSlug: str = None + tmdbId: int = None website: str = None - addOptions: str = None - id: int = None + year: int = None + youTubeTrailerId: str = None class OmbiMovieRequest(NamedTuple): - theMovieDbId: int = None + approved: bool = None + available: bool = None + background: str = None + canApprove: bool = None + denied: bool = None + deniedReason: None = None + digitalRelease: bool = None + digitalReleaseDate: None = None + id: int = None + imdbId: str = None issueId: None = None issues: None = None - subscribed: bool = None - showSubscribe: bool = None - rootPathOverride: int = None - qualityOverride: int = None - imdbId: str = None + markedAsApproved: str = None + markedAsAvailable: None = None + markedAsDenied: str = None overview: str = None posterPath: str = None - releaseDate: str = None - digitalReleaseDate: None = None - status: str = None - background: str = None + qualityOverride: int = None released: bool = None - digitalRelease: bool = None - title: str = None - approved: bool = None - markedAsApproved: str = None + releaseDate: str = None requestedDate: str = None - available: bool = None - markedAsAvailable: None = None - requestedUserId: str = None - denied: bool = None - markedAsDenied: str = None - deniedReason: None = None - requestType: int = None requestedUser: dict = None - canApprove: bool = None - id: int = None + requestedUserId: str = None + requestType: int = None + rootPathOverride: int = None + showSubscribe: bool = None + status: str = None + subscribed: bool = None + theMovieDbId: int = None + title: str = None class OmbiTVRequest(NamedTuple): - tvDbId: int = None - imdbId: str = None - qualityOverride: None = None - rootFolder: None = None - overview: str = None - title: str = None - posterPath: str = None background: str = None - releaseDate: str = None - status: str = None - totalSeasons: int = None childRequests: list = None - id: int = None denied: bool = None - markedAsDenied: str = None deniedReason: None = None + id: int = None + imdbId: str = None + markedAsDenied: str = None + overview: str = None + posterPath: str = None + qualityOverride: None = None + releaseDate: str = None + rootFolder: None = None + status: str = None + title: str = None + totalSeasons: int = None + tvDbId: int = None class SickChillTVShow(NamedTuple): airdate: str = None airs: str = None + episode: int = None ep_name: str = None ep_plot: str = None - episode: int = None indexerid: int = None network: str = None paused: int = None From 95947fecc538250f153646ecc83b154a69176693 Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sun, 30 Dec 2018 00:13:40 -0600 Subject: [PATCH 31/37] added final missing model from movies --- varken/structures.py | 1 + 1 file changed, 1 insertion(+) diff --git a/varken/structures.py b/varken/structures.py index baf8549..5f741eb 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -335,6 +335,7 @@ class Movie(NamedTuple): added: str = None addOptions: str = None alternativeTitles: list = None + certification: str = None cleanTitle: str = None downloaded: bool = None folderName: str = None From 9734fa963bcb85531c3bef75fbefcbb7c9698a62 Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sun, 30 Dec 2018 00:33:55 -0600 Subject: [PATCH 32/37] explicitly define server inits --- varken/iniparser.py | 46 +++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/varken/iniparser.py b/varken/iniparser.py index badbdc4..3569503 100644 --- a/varken/iniparser.py +++ b/varken/iniparser.py @@ -101,8 +101,7 @@ class INIParser(object): username = self.config.get('influxdb', 'username') password = self.config.get('influxdb', 'password') - - self.influx_server = InfluxServer(url, port, username, password) + self.influx_server = InfluxServer(url=url, port=port, username=username, password=password) # Check for all enabled services for service in self.services: @@ -140,9 +139,11 @@ class INIParser(object): queue_run_seconds = self.config.getint(section, 'queue_run_seconds') - server = SonarrServer(server_id, scheme + url, apikey, verify_ssl, missing_days, - missing_days_run_seconds, future_days, future_days_run_seconds, - queue, queue_run_seconds) + server = SonarrServer(id=server_id, url=scheme + url, api_key=apikey, verify_ssl=verify_ssl, + missing_days=missing_days, future_days=future_days, + missing_days_run_seconds=missing_days_run_seconds, + future_days_run_seconds=future_days_run_seconds, + queue=queue, queue_run_seconds=queue_run_seconds) if service == 'radarr': queue = self.config.getboolean(section, 'queue') @@ -153,8 +154,9 @@ class INIParser(object): get_missing_run_seconds = self.config.getint(section, 'get_missing_run_seconds') - server = RadarrServer(server_id, scheme + url, apikey, verify_ssl, queue, queue_run_seconds, - get_missing, get_missing_run_seconds) + server = RadarrServer(id=server_id, url=scheme + url, api_key=apikey, verify_ssl=verify_ssl, + queue_run_seconds=queue_run_seconds, get_missing=get_missing, + queue=queue, get_missing_run_seconds=get_missing_run_seconds) if service == 'tautulli': fallback_ip = self.config.get(section, 'fallback_ip') @@ -167,9 +169,11 @@ class INIParser(object): get_stats_run_seconds = self.config.getint(section, 'get_stats_run_seconds') - server = TautulliServer(server_id, scheme + url, fallback_ip, apikey, verify_ssl, - get_activity, get_activity_run_seconds, get_stats, - get_stats_run_seconds) + server = TautulliServer(id=server_id, url=scheme + url, api_key=apikey, + verify_ssl=verify_ssl, get_activity=get_activity, + fallback_ip=fallback_ip, get_stats=get_stats, + get_activity_run_seconds=get_activity_run_seconds, + get_stats_run_seconds=get_stats_run_seconds) if service == 'ombi': request_type_counts = self.config.getboolean(section, 'get_request_type_counts') @@ -184,18 +188,22 @@ class INIParser(object): issue_status_run_seconds = self.config.getint(section, 'issue_status_run_seconds') - server = OmbiServer(server_id, scheme + url, apikey, verify_ssl, request_type_counts, - request_type_run_seconds, request_total_counts, - request_total_run_seconds, issue_status_counts, - issue_status_run_seconds) + server = OmbiServer(id=server_id, url=scheme + url, api_key=apikey, verify_ssl=verify_ssl, + request_type_counts=request_type_counts, + request_type_run_seconds=request_type_run_seconds, + request_total_counts=request_total_counts, + request_total_run_seconds=request_total_run_seconds, + issue_status_counts=issue_status_counts, + issue_status_run_seconds=issue_status_run_seconds) if service == 'sickchill': get_missing = self.config.getboolean(section, 'get_missing') get_missing_run_seconds = self.config.getint(section, 'get_missing_run_seconds') - server = SickChillServer(server_id, scheme + url, apikey, verify_ssl, - get_missing, get_missing_run_seconds) + server = SickChillServer(id=server_id, url=scheme + url, api_key=apikey, + verify_ssl=verify_ssl, get_missing=get_missing, + get_missing_run_seconds=get_missing_run_seconds) if service == 'ciscoasa': username = self.config.get(section, 'username') @@ -206,8 +214,10 @@ class INIParser(object): get_bandwidth_run_seconds = self.config.getint(section, 'get_bandwidth_run_seconds') - server = CiscoASAFirewall(server_id, scheme + url, username, password, outside_interface, - verify_ssl, get_bandwidth_run_seconds) + server = CiscoASAFirewall(id=server_id, url=scheme + url, verify_ssl=verify_ssl, + username=username, password=password, + outside_interface=outside_interface, + get_bandwidth_run_seconds=get_bandwidth_run_seconds) getattr(self, f'{service}_servers').append(server) From 3038c9f58636e8519099b91f8f0549cb0fba0927 Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sun, 30 Dec 2018 00:40:44 -0600 Subject: [PATCH 33/37] moved to sections --- varken/structures.py | 321 ++++++++++++++++++++++--------------------- 1 file changed, 164 insertions(+), 157 deletions(-) diff --git a/varken/structures.py b/varken/structures.py index 5f741eb..7ca2505 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -10,22 +10,12 @@ if version_info < (3, 6, 2): exit(1) -class Queue(NamedTuple): - downloadId: str = None - episode: dict = None - estimatedCompletionTime: str = None - id: int = None - movie: dict = None - protocol: str = None - quality: dict = None - series: dict = None - size: float = None - sizeleft: float = None - status: str = None - statusMessages: list = None - timeleft: str = None - title: str = None - trackedDownloadStatus: str = None +# Server Structures +class InfluxServer(NamedTuple): + password: str = 'root' + port: int = 8086 + url: str = 'localhost' + username: str = 'root' class SonarrServer(NamedTuple): @@ -77,13 +67,6 @@ class TautulliServer(NamedTuple): verify_ssl: bool = None -class InfluxServer(NamedTuple): - password: str = 'root' - port: int = 8086 - url: str = 'localhost' - username: str = 'root' - - class SickChillServer(NamedTuple): api_key: str = None get_missing: bool = False @@ -103,6 +86,26 @@ class CiscoASAFirewall(NamedTuple): verify_ssl: bool = False +# Shared +class Queue(NamedTuple): + downloadId: str = None + episode: dict = None + estimatedCompletionTime: str = None + id: int = None + movie: dict = None + protocol: str = None + quality: dict = None + series: dict = None + size: float = None + sizeleft: float = None + status: str = None + statusMessages: list = None + timeleft: str = None + title: str = None + trackedDownloadStatus: str = None + + +# Ombi Structures class OmbiRequestCounts(NamedTuple): approved: int = 0 available: int = 0 @@ -115,6 +118,144 @@ class OmbiIssuesCounts(NamedTuple): resolved: int = 0 +class OmbiTVRequest(NamedTuple): + background: str = None + childRequests: list = None + denied: bool = None + deniedReason: None = None + id: int = None + imdbId: str = None + markedAsDenied: str = None + overview: str = None + posterPath: str = None + qualityOverride: None = None + releaseDate: str = None + rootFolder: None = None + status: str = None + title: str = None + totalSeasons: int = None + tvDbId: int = None + + +class OmbiMovieRequest(NamedTuple): + approved: bool = None + available: bool = None + background: str = None + canApprove: bool = None + denied: bool = None + deniedReason: None = None + digitalRelease: bool = None + digitalReleaseDate: None = None + id: int = None + imdbId: str = None + issueId: None = None + issues: None = None + markedAsApproved: str = None + markedAsAvailable: None = None + markedAsDenied: str = None + overview: str = None + posterPath: str = None + qualityOverride: int = None + released: bool = None + releaseDate: str = None + requestedDate: str = None + requestedUser: dict = None + requestedUserId: str = None + requestType: int = None + rootPathOverride: int = None + showSubscribe: bool = None + status: str = None + subscribed: bool = None + theMovieDbId: int = None + title: str = None + + +# Sonarr +class TVShow(NamedTuple): + absoluteEpisodeNumber: int = None + airDate: str = None + airDateUtc: str = None + episodeFile: dict = None + episodeFileId: int = None + episodeNumber: int = None + hasFile: bool = None + id: int = None + lastSearchTime: str = None + monitored: bool = None + overview: str = None + sceneAbsoluteEpisodeNumber: int = None + sceneEpisodeNumber: int = None + sceneSeasonNumber: int = None + seasonNumber: int = None + series: dict = None + seriesId: int = None + title: str = None + unverifiedSceneNumbering: bool = None + + +# Radarr +class Movie(NamedTuple): + added: str = None + addOptions: str = None + alternativeTitles: list = None + certification: str = None + cleanTitle: str = None + downloaded: bool = None + folderName: str = None + genres: list = None + hasFile: bool = None + id: int = None + images: list = None + imdbId: str = None + inCinemas: str = None + isAvailable: bool = None + lastInfoSync: str = None + minimumAvailability: str = None + monitored: bool = None + movieFile: dict = None + overview: str = None + path: str = None + pathState: str = None + physicalRelease: str = None + physicalReleaseNote: str = None + profileId: int = None + qualityProfileId: int = None + ratings: dict = None + runtime: int = None + secondaryYear: str = None + secondaryYearSourceId: int = None + sizeOnDisk: int = None + sortTitle: str = None + status: str = None + studio: str = None + tags: list = None + title: str = None + titleSlug: str = None + tmdbId: int = None + website: str = None + year: int = None + youTubeTrailerId: str = None + + +# Sickchill +class SickChillTVShow(NamedTuple): + airdate: str = None + airs: str = None + episode: int = None + ep_name: str = None + ep_plot: str = None + indexerid: int = None + network: str = None + paused: int = None + quality: str = None + season: int = None + show_name: str = None + show_status: str = None + tvdbid: int = None + weekday: int = None + + +# Tautulli class TautulliStream(NamedTuple): actors: list = None added_at: str = None @@ -307,137 +448,3 @@ class TautulliStream(NamedTuple): width: str = None writers: list = None year: str = None - - -class TVShow(NamedTuple): - absoluteEpisodeNumber: int = None - airDate: str = None - airDateUtc: str = None - episodeFile: dict = None - episodeFileId: int = None - episodeNumber: int = None - hasFile: bool = None - id: int = None - lastSearchTime: str = None - monitored: bool = None - overview: str = None - sceneAbsoluteEpisodeNumber: int = None - sceneEpisodeNumber: int = None - sceneSeasonNumber: int = None - seasonNumber: int = None - series: dict = None - seriesId: int = None - title: str = None - unverifiedSceneNumbering: bool = None - - -class Movie(NamedTuple): - added: str = None - addOptions: str = None - alternativeTitles: list = None - certification: str = None - cleanTitle: str = None - downloaded: bool = None - folderName: str = None - genres: list = None - hasFile: bool = None - id: int = None - images: list = None - imdbId: str = None - inCinemas: str = None - isAvailable: bool = None - lastInfoSync: str = None - minimumAvailability: str = None - monitored: bool = None - movieFile: dict = None - overview: str = None - path: str = None - pathState: str = None - physicalRelease: str = None - physicalReleaseNote: str = None - profileId: int = None - qualityProfileId: int = None - ratings: dict = None - runtime: int = None - secondaryYear: str = None - secondaryYearSourceId: int = None - sizeOnDisk: int = None - sortTitle: str = None - status: str = None - studio: str = None - tags: list = None - title: str = None - titleSlug: str = None - tmdbId: int = None - website: str = None - year: int = None - youTubeTrailerId: str = None - - -class OmbiMovieRequest(NamedTuple): - approved: bool = None - available: bool = None - background: str = None - canApprove: bool = None - denied: bool = None - deniedReason: None = None - digitalRelease: bool = None - digitalReleaseDate: None = None - id: int = None - imdbId: str = None - issueId: None = None - issues: None = None - markedAsApproved: str = None - markedAsAvailable: None = None - markedAsDenied: str = None - overview: str = None - posterPath: str = None - qualityOverride: int = None - released: bool = None - releaseDate: str = None - requestedDate: str = None - requestedUser: dict = None - requestedUserId: str = None - requestType: int = None - rootPathOverride: int = None - showSubscribe: bool = None - status: str = None - subscribed: bool = None - theMovieDbId: int = None - title: str = None - - -class OmbiTVRequest(NamedTuple): - background: str = None - childRequests: list = None - denied: bool = None - deniedReason: None = None - id: int = None - imdbId: str = None - markedAsDenied: str = None - overview: str = None - posterPath: str = None - qualityOverride: None = None - releaseDate: str = None - rootFolder: None = None - status: str = None - title: str = None - totalSeasons: int = None - tvDbId: int = None - - -class SickChillTVShow(NamedTuple): - airdate: str = None - airs: str = None - episode: int = None - ep_name: str = None - ep_plot: str = None - indexerid: int = None - network: str = None - paused: int = None - quality: str = None - season: int = None - show_name: str = None - show_status: str = None - tvdbid: int = None - weekday: int = None From 1c0ea465e8f2776cea820bb4a463bfafb533884a Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sun, 30 Dec 2018 00:43:10 -0600 Subject: [PATCH 34/37] specified classes --- varken/radarr.py | 10 +++++----- varken/sonarr.py | 12 ++++++------ varken/structures.py | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/varken/radarr.py b/varken/radarr.py index d5ad514..e8a15d0 100644 --- a/varken/radarr.py +++ b/varken/radarr.py @@ -2,7 +2,7 @@ from logging import getLogger from requests import Session, Request from datetime import datetime, timezone -from varken.structures import Movie, Queue +from varken.structures import RadarrMovie, Queue from varken.helpers import hashit, connection_handler @@ -31,9 +31,9 @@ class RadarrAPI(object): return try: - movies = [Movie(**movie) for movie in get] + movies = [RadarrMovie(**movie) for movie in get] except TypeError as e: - self.logger.error('TypeError has occurred : %s while creating Movie structure', e) + self.logger.error('TypeError has occurred : %s while creating RadarrMovie structure', e) return for movie in movies: @@ -82,9 +82,9 @@ class RadarrAPI(object): for movie in get: try: - movie['movie'] = Movie(**movie['movie']) + movie['movie'] = RadarrMovie(**movie['movie']) except TypeError as e: - self.logger.error('TypeError has occurred : %s while creating Movie structure', e) + self.logger.error('TypeError has occurred : %s while creating RadarrMovie structure', e) return try: diff --git a/varken/sonarr.py b/varken/sonarr.py index 3f807c4..b90dad9 100644 --- a/varken/sonarr.py +++ b/varken/sonarr.py @@ -2,7 +2,7 @@ from logging import getLogger from requests import Session, Request from datetime import datetime, timezone, date, timedelta -from varken.structures import Queue, TVShow +from varken.structures import Queue, SonarrTVShow from varken.helpers import hashit, connection_handler @@ -34,11 +34,11 @@ class SonarrAPI(object): if not get: return - # Iteratively create a list of TVShow Objects from response json + # Iteratively create a list of SonarrTVShow Objects from response json try: - tv_shows = [TVShow(**show) for show in get] + tv_shows = [SonarrTVShow(**show) for show in get] except TypeError as e: - self.logger.error('TypeError has occurred : %s while creating TVShow structure', e) + self.logger.error('TypeError has occurred : %s while creating SonarrTVShow structure', e) return # Add show to missing list if file does not exist @@ -87,9 +87,9 @@ class SonarrAPI(object): return try: - tv_shows = [TVShow(**show) for show in get] + tv_shows = [SonarrTVShow(**show) for show in get] except TypeError as e: - self.logger.error('TypeError has occurred : %s while creating TVShow structure', e) + self.logger.error('TypeError has occurred : %s while creating SonarrTVShow structure', e) return for show in tv_shows: diff --git a/varken/structures.py b/varken/structures.py index 7ca2505..0672f50 100644 --- a/varken/structures.py +++ b/varken/structures.py @@ -171,7 +171,7 @@ class OmbiMovieRequest(NamedTuple): # Sonarr -class TVShow(NamedTuple): +class SonarrTVShow(NamedTuple): absoluteEpisodeNumber: int = None airDate: str = None airDateUtc: str = None @@ -194,7 +194,7 @@ class TVShow(NamedTuple): # Radarr -class Movie(NamedTuple): +class RadarrMovie(NamedTuple): added: str = None addOptions: str = None alternativeTitles: list = None From cb55a41b7bbdfe20cdc9e9db60bfc6893f27c431 Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sun, 30 Dec 2018 00:59:02 -0600 Subject: [PATCH 35/37] updated readme for grafana.com info --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e3a6b29..e43ce9a 100644 --- a/README.md +++ b/README.md @@ -103,9 +103,16 @@ do not include database creation, please ensure you create an influx database named `varken` ### Grafana -[Grafana Installation Documentation](http://docs.grafana.org/installation/) +[Grafana Installation Documentation](http://docs.grafana.org/installation/) +[Official Example Dashboards](https://grafana.com/dashboards?search=Varken%20%5BOfficial%5D) Grafana is used in our examples but not required, nor packaged as part of -Varken. Panel example pictures are pinned in the grafana-panels channel of -discord. Future releases may contain a json-generator, but it does not exist -as varken stands today. +Varken. Panel examples now exist in both nightly and tagged releases hosted +on grafana.com (link above). + +1. Use the link above, then click on your desired dashboard version +2. Click `Copy ID to Clipboard` +3. In grafana, click your dashboards menu dropdown, and then click `Import dashboard` +4. Paste the ID into the `Grafana.com Dashboard` field and then click into empty space on the screen. (This should change the screen to show `Importing Dashboard from Grafana.com` +5. Select your varken datasource name in the dropdown labeled `Varken` +6. Click Import! \ No newline at end of file From 36139df61b58afa4b4af4e5b942d358d27ec9741 Mon Sep 17 00:00:00 2001 From: samwiseg0 Date: Sun, 30 Dec 2018 02:19:28 -0500 Subject: [PATCH 36/37] Update image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e3a6b29..9bae1ca 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Requirements:

Example Dashboard - +

Supported Modules: From 8d4fb3dc181c311e5f5e7830bd6bfd4a725954d8 Mon Sep 17 00:00:00 2001 From: "Nicholas St. Germain" Date: Sun, 30 Dec 2018 01:37:33 -0600 Subject: [PATCH 37/37] version release --- CHANGELOG.md | 30 +++++++++++++++++++++++++----- varken/__init__.py | 2 +- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eda655d..6ad9ec5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,25 @@ # Change Log -## [v1.4](https://github.com/Boerderij/Varken/tree/v1.4) (2018-12-18) +## [v1.5](https://github.com/Boerderij/Varken/tree/v1.5) (2018-12-30) +[Full Changelog](https://github.com/Boerderij/Varken/compare/v1.4...v1.5) + +**Implemented enhancements:** + +- \[Feature Request\] Add issues from Ombi [\#70](https://github.com/Boerderij/Varken/issues/70) +- \[Feature Request\] Allow DNS Hostnames [\#66](https://github.com/Boerderij/Varken/issues/66) +- Replace static grafana configs with a Public Example [\#32](https://github.com/Boerderij/Varken/issues/32) + +**Fixed bugs:** + +- \[BUG\] unexpected keyword argument 'channel\_icon' [\#73](https://github.com/Boerderij/Varken/issues/73) +- \[BUG\] Unexpected keyword argument 'addOptions' [\#68](https://github.com/Boerderij/Varken/issues/68) + +**Merged pull requests:** + +- v1.5 Merge [\#75](https://github.com/Boerderij/Varken/pull/75) ([DirtyCajunRice](https://github.com/DirtyCajunRice)) +- Add Ombi Issues [\#74](https://github.com/Boerderij/Varken/pull/74) ([anderssonoscar0](https://github.com/anderssonoscar0)) + +## [v1.4](https://github.com/Boerderij/Varken/tree/v1.4) (2018-12-19) [Full Changelog](https://github.com/Boerderij/Varken/compare/v1.3-nightly...v1.4) **Implemented enhancements:** @@ -92,10 +111,6 @@ ## [v0.2-nightly](https://github.com/Boerderij/Varken/tree/v0.2-nightly) (2018-12-06) [Full Changelog](https://github.com/Boerderij/Varken/compare/v0.1...v0.2-nightly) -**Implemented enhancements:** - -- Tautulli - multiple server support? [\#25](https://github.com/Boerderij/Varken/issues/25) - **Closed issues:** - Create the DB if it does not exist. [\#38](https://github.com/Boerderij/Varken/issues/38) @@ -105,7 +120,12 @@ - use a config.ini instead of command-line flags [\#33](https://github.com/Boerderij/Varken/issues/33) - Migrate crontab to python schedule package [\#31](https://github.com/Boerderij/Varken/issues/31) - Consolidate missing and missing\_days in sonarr.py [\#30](https://github.com/Boerderij/Varken/issues/30) +- Database Withou any scripts [\#29](https://github.com/Boerderij/Varken/issues/29) +- Grafana dashboard json doesn't match format of readme screenshot? [\#28](https://github.com/Boerderij/Varken/issues/28) - Ombi something new \[Request\] [\#26](https://github.com/Boerderij/Varken/issues/26) +- Users Online not populating [\#24](https://github.com/Boerderij/Varken/issues/24) +- Missing dashboard [\#23](https://github.com/Boerderij/Varken/issues/23) +- Is there a Docker Image available for these scripts? [\#22](https://github.com/Boerderij/Varken/issues/22) - Support for Linux without ASA [\#21](https://github.com/Boerderij/Varken/issues/21) **Merged pull requests:** diff --git a/varken/__init__.py b/varken/__init__.py index 4e48cdb..fba0206 100644 --- a/varken/__init__.py +++ b/varken/__init__.py @@ -1,2 +1,2 @@ VERSION = 1.5 -BRANCH = 'pre-nightly' +BRANCH = 'master'