diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a389162..a8882e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,24 +49,48 @@ jobs: docker-compose -f "${FOLDER}/docker-compose.yml" logs done - - name: "Run tests" + - name: "Test Plex" + run: | + mv test/ci_plex.env .env + python main.py + python test/validate_ci_marklog.py --plex + + rm mark.log + + - name: "Test Jellyfin" + run: | + mv test/ci_jellyfin.env .env + python main.py + python test/validate_ci_marklog.py --jellyfin + + rm mark.log + + - name: "Test Emby" + run: | + mv test/ci_emby.env .env + python main.py + python test/validate_ci_marklog.py --emby + + rm mark.log + + - name: "Test Guids" run: | - # Test guids mv test/ci_guids.env .env python main.py - - cat mark.log python test/validate_ci_marklog.py --dry + rm mark.log - # Test locations + - name: "Test Locations" + run: | mv test/ci_locations.env .env python main.py - - cat mark.log python test/validate_ci_marklog.py --dry + rm mark.log + - name: "Test writing to the servers" + run: | # Test writing to the servers mv test/ci_write.env .env python main.py @@ -74,8 +98,9 @@ jobs: # Test again to test if it can handle existing data python main.py - cat mark.log python test/validate_ci_marklog.py --write + + rm mark.log docker: runs-on: ubuntu-latest diff --git a/test/ci_emby.env b/test/ci_emby.env new file mode 100644 index 0000000..73c7af5 --- /dev/null +++ b/test/ci_emby.env @@ -0,0 +1,116 @@ +# Global Settings + +## Do not mark any shows/movies as played and instead just output to log if they would of been marked. +DRYRUN = "True" + +## Additional logging information +DEBUG = "True" + +## Debugging level, "info" is default, "debug" is more verbose +DEBUG_LEVEL = "info" + +## If set to true then the script will only run once and then exit +RUN_ONLY_ONCE = "True" + +## How often to run the script in seconds +SLEEP_DURATION = 10 + +## Log file where all output will be written to +LOG_FILE = "log.log" + +## Mark file where all shows/movies that have been marked as played will be written to +MARK_FILE = "mark.log" + +## Timeout for requests for jellyfin +REQUEST_TIMEOUT = 300 + +## Max threads for processing +MAX_THREADS = 2 + +## Generate guids +## Generating guids is a slow process, so this is a way to speed up the process +# by using the location only, useful when using same files on multiple servers +GENERATE_GUIDS = "True" + +## Generate locations +## Generating locations is a slow process, so this is a way to speed up the process +## by using the guid only, useful when using different files on multiple servers +GENERATE_LOCATIONS = "True" + +## Map usernames between servers in the event that they are different, order does not matter +## Comma seperated for multiple options +USER_MAPPING = {"JellyUser":"jellyplex_watched"} + +## Map libraries between servers in the even that they are different, order does not matter +## Comma seperated for multiple options +LIBRARY_MAPPING = { "Shows": "TV Shows" } + + +## Blacklisting/Whitelisting libraries, library types such as Movies/TV Shows, and users. Mappings apply so if the mapping for the user or library exist then both will be excluded. +## Comma seperated for multiple options +#BLACKLIST_LIBRARY = "" +#WHITELIST_LIBRARY = "Movies" +#BLACKLIST_LIBRARY_TYPE = "Series" +#WHITELIST_LIBRARY_TYPE = "Movies, movie" +#BLACKLIST_USERS = "" +WHITELIST_USERS = "jellyplex_watched" + + + +# Plex + +## Recommended to use token as it is faster to connect as it is direct to the server instead of going through the plex servers +## URL of the plex server, use hostname or IP address if the hostname is not resolving correctly +## Comma seperated list for multiple servers +PLEX_BASEURL = "https://localhost:32400" + +## Plex token https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/ +## Comma seperated list for multiple servers +PLEX_TOKEN = "mVaCzSyd78uoWkCBzZ_Y" + +## If not using plex token then use username and password of the server admin along with the servername +## Comma seperated for multiple options +#PLEX_USERNAME = "PlexUser, PlexUser2" +#PLEX_PASSWORD = "SuperSecret, SuperSecret2" +#PLEX_SERVERNAME = "Plex Server1, Plex Server2" + +## Skip hostname validation for ssl certificates. +## Set to True if running into ssl certificate errors +SSL_BYPASS = "True" + +# Jellyfin + +## Jellyfin server URL, use hostname or IP address if the hostname is not resolving correctly +## Comma seperated list for multiple servers +JELLYFIN_BASEURL = "http://localhost:8096" + +## Jellyfin api token, created manually by logging in to the jellyfin server admin dashboard and creating an api key +## Comma seperated list for multiple servers +JELLYFIN_TOKEN = "d773c4db3ecc4b028fc0904d9694804c" + +# Emby + +## Emby server URL, use hostname or IP address if the hostname is not resolving correctly +## Comma seperated list for multiple servers +EMBY_BASEURL = "http://localhost:8097" + +## Emby api token, created manually by logging in to the Emby server admin dashboard and creating an api key +## Comma seperated list for multiple servers +EMBY_TOKEN = "ed9507cba8d14d469ae4d58e33afc515" + + +# Syncing Options + +## control the direction of syncing. e.g. SYNC_FROM_PLEX_TO_JELLYFIN set to true will cause the updates from plex +## to be updated in jellyfin. SYNC_FROM_PLEX_TO_PLEX set to true will sync updates between multiple plex servers +SYNC_FROM_PLEX_TO_JELLYFIN = "False" +SYNC_FROM_PLEX_TO_PLEX = "False" +SYNC_FROM_PLEX_TO_EMBY = "False" + +SYNC_FROM_JELLYFIN_TO_PLEX = "False" +SYNC_FROM_JELLYFIN_TO_JELLYFIN = "False" +SYNC_FROM_JELLYFIN_TO_EMBY = "False" + +SYNC_FROM_EMBY_TO_PLEX = "True" +SYNC_FROM_EMBY_TO_JELLYFIN = "True" +SYNC_FROM_EMBY_TO_EMBY = "True" \ No newline at end of file diff --git a/test/ci_guids.env b/test/ci_guids.env index 48a20da..485d8e8 100644 --- a/test/ci_guids.env +++ b/test/ci_guids.env @@ -7,7 +7,7 @@ DRYRUN = "True" DEBUG = "True" ## Debugging level, "info" is default, "debug" is more verbose -DEBUG_LEVEL = "debug" +DEBUG_LEVEL = "info" ## If set to true then the script will only run once and then exit RUN_ONLY_ONCE = "True" diff --git a/test/ci_jellyfin.env b/test/ci_jellyfin.env new file mode 100644 index 0000000..4202f37 --- /dev/null +++ b/test/ci_jellyfin.env @@ -0,0 +1,116 @@ +# Global Settings + +## Do not mark any shows/movies as played and instead just output to log if they would of been marked. +DRYRUN = "True" + +## Additional logging information +DEBUG = "True" + +## Debugging level, "info" is default, "debug" is more verbose +DEBUG_LEVEL = "info" + +## If set to true then the script will only run once and then exit +RUN_ONLY_ONCE = "True" + +## How often to run the script in seconds +SLEEP_DURATION = 10 + +## Log file where all output will be written to +LOG_FILE = "log.log" + +## Mark file where all shows/movies that have been marked as played will be written to +MARK_FILE = "mark.log" + +## Timeout for requests for jellyfin +REQUEST_TIMEOUT = 300 + +## Max threads for processing +MAX_THREADS = 2 + +## Generate guids +## Generating guids is a slow process, so this is a way to speed up the process +# by using the location only, useful when using same files on multiple servers +GENERATE_GUIDS = "True" + +## Generate locations +## Generating locations is a slow process, so this is a way to speed up the process +## by using the guid only, useful when using different files on multiple servers +GENERATE_LOCATIONS = "True" + +## Map usernames between servers in the event that they are different, order does not matter +## Comma seperated for multiple options +USER_MAPPING = {"JellyUser":"jellyplex_watched"} + +## Map libraries between servers in the even that they are different, order does not matter +## Comma seperated for multiple options +LIBRARY_MAPPING = { "Shows": "TV Shows" } + + +## Blacklisting/Whitelisting libraries, library types such as Movies/TV Shows, and users. Mappings apply so if the mapping for the user or library exist then both will be excluded. +## Comma seperated for multiple options +#BLACKLIST_LIBRARY = "" +#WHITELIST_LIBRARY = "Movies" +#BLACKLIST_LIBRARY_TYPE = "Series" +#WHITELIST_LIBRARY_TYPE = "Movies, movie" +#BLACKLIST_USERS = "" +WHITELIST_USERS = "jellyplex_watched" + + + +# Plex + +## Recommended to use token as it is faster to connect as it is direct to the server instead of going through the plex servers +## URL of the plex server, use hostname or IP address if the hostname is not resolving correctly +## Comma seperated list for multiple servers +PLEX_BASEURL = "https://localhost:32400" + +## Plex token https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/ +## Comma seperated list for multiple servers +PLEX_TOKEN = "mVaCzSyd78uoWkCBzZ_Y" + +## If not using plex token then use username and password of the server admin along with the servername +## Comma seperated for multiple options +#PLEX_USERNAME = "PlexUser, PlexUser2" +#PLEX_PASSWORD = "SuperSecret, SuperSecret2" +#PLEX_SERVERNAME = "Plex Server1, Plex Server2" + +## Skip hostname validation for ssl certificates. +## Set to True if running into ssl certificate errors +SSL_BYPASS = "True" + +# Jellyfin + +## Jellyfin server URL, use hostname or IP address if the hostname is not resolving correctly +## Comma seperated list for multiple servers +JELLYFIN_BASEURL = "http://localhost:8096" + +## Jellyfin api token, created manually by logging in to the jellyfin server admin dashboard and creating an api key +## Comma seperated list for multiple servers +JELLYFIN_TOKEN = "d773c4db3ecc4b028fc0904d9694804c" + +# Emby + +## Emby server URL, use hostname or IP address if the hostname is not resolving correctly +## Comma seperated list for multiple servers +EMBY_BASEURL = "http://localhost:8097" + +## Emby api token, created manually by logging in to the Emby server admin dashboard and creating an api key +## Comma seperated list for multiple servers +EMBY_TOKEN = "ed9507cba8d14d469ae4d58e33afc515" + + +# Syncing Options + +## control the direction of syncing. e.g. SYNC_FROM_PLEX_TO_JELLYFIN set to true will cause the updates from plex +## to be updated in jellyfin. SYNC_FROM_PLEX_TO_PLEX set to true will sync updates between multiple plex servers +SYNC_FROM_PLEX_TO_JELLYFIN = "False" +SYNC_FROM_PLEX_TO_PLEX = "False" +SYNC_FROM_PLEX_TO_EMBY = "False" + +SYNC_FROM_JELLYFIN_TO_PLEX = "True" +SYNC_FROM_JELLYFIN_TO_JELLYFIN = "True" +SYNC_FROM_JELLYFIN_TO_EMBY = "True" + +SYNC_FROM_EMBY_TO_PLEX = "False" +SYNC_FROM_EMBY_TO_JELLYFIN = "False" +SYNC_FROM_EMBY_TO_EMBY = "False" \ No newline at end of file diff --git a/test/ci_locations.env b/test/ci_locations.env index 6628f39..bc1bedf 100644 --- a/test/ci_locations.env +++ b/test/ci_locations.env @@ -7,7 +7,7 @@ DRYRUN = "True" DEBUG = "True" ## Debugging level, "info" is default, "debug" is more verbose -DEBUG_LEVEL = "debug" +DEBUG_LEVEL = "info" ## If set to true then the script will only run once and then exit RUN_ONLY_ONCE = "True" diff --git a/test/ci_plex.env b/test/ci_plex.env new file mode 100644 index 0000000..97d01dc --- /dev/null +++ b/test/ci_plex.env @@ -0,0 +1,116 @@ +# Global Settings + +## Do not mark any shows/movies as played and instead just output to log if they would of been marked. +DRYRUN = "True" + +## Additional logging information +DEBUG = "True" + +## Debugging level, "info" is default, "debug" is more verbose +DEBUG_LEVEL = "info" + +## If set to true then the script will only run once and then exit +RUN_ONLY_ONCE = "True" + +## How often to run the script in seconds +SLEEP_DURATION = 10 + +## Log file where all output will be written to +LOG_FILE = "log.log" + +## Mark file where all shows/movies that have been marked as played will be written to +MARK_FILE = "mark.log" + +## Timeout for requests for jellyfin +REQUEST_TIMEOUT = 300 + +## Max threads for processing +MAX_THREADS = 2 + +## Generate guids +## Generating guids is a slow process, so this is a way to speed up the process +# by using the location only, useful when using same files on multiple servers +GENERATE_GUIDS = "True" + +## Generate locations +## Generating locations is a slow process, so this is a way to speed up the process +## by using the guid only, useful when using different files on multiple servers +GENERATE_LOCATIONS = "True" + +## Map usernames between servers in the event that they are different, order does not matter +## Comma seperated for multiple options +USER_MAPPING = {"JellyUser":"jellyplex_watched"} + +## Map libraries between servers in the even that they are different, order does not matter +## Comma seperated for multiple options +LIBRARY_MAPPING = { "Shows": "TV Shows" } + + +## Blacklisting/Whitelisting libraries, library types such as Movies/TV Shows, and users. Mappings apply so if the mapping for the user or library exist then both will be excluded. +## Comma seperated for multiple options +#BLACKLIST_LIBRARY = "" +#WHITELIST_LIBRARY = "Movies" +#BLACKLIST_LIBRARY_TYPE = "Series" +#WHITELIST_LIBRARY_TYPE = "Movies, movie" +#BLACKLIST_USERS = "" +WHITELIST_USERS = "jellyplex_watched" + + + +# Plex + +## Recommended to use token as it is faster to connect as it is direct to the server instead of going through the plex servers +## URL of the plex server, use hostname or IP address if the hostname is not resolving correctly +## Comma seperated list for multiple servers +PLEX_BASEURL = "https://localhost:32400" + +## Plex token https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/ +## Comma seperated list for multiple servers +PLEX_TOKEN = "mVaCzSyd78uoWkCBzZ_Y" + +## If not using plex token then use username and password of the server admin along with the servername +## Comma seperated for multiple options +#PLEX_USERNAME = "PlexUser, PlexUser2" +#PLEX_PASSWORD = "SuperSecret, SuperSecret2" +#PLEX_SERVERNAME = "Plex Server1, Plex Server2" + +## Skip hostname validation for ssl certificates. +## Set to True if running into ssl certificate errors +SSL_BYPASS = "True" + +# Jellyfin + +## Jellyfin server URL, use hostname or IP address if the hostname is not resolving correctly +## Comma seperated list for multiple servers +JELLYFIN_BASEURL = "http://localhost:8096" + +## Jellyfin api token, created manually by logging in to the jellyfin server admin dashboard and creating an api key +## Comma seperated list for multiple servers +JELLYFIN_TOKEN = "d773c4db3ecc4b028fc0904d9694804c" + +# Emby + +## Emby server URL, use hostname or IP address if the hostname is not resolving correctly +## Comma seperated list for multiple servers +EMBY_BASEURL = "http://localhost:8097" + +## Emby api token, created manually by logging in to the Emby server admin dashboard and creating an api key +## Comma seperated list for multiple servers +EMBY_TOKEN = "ed9507cba8d14d469ae4d58e33afc515" + + +# Syncing Options + +## control the direction of syncing. e.g. SYNC_FROM_PLEX_TO_JELLYFIN set to true will cause the updates from plex +## to be updated in jellyfin. SYNC_FROM_PLEX_TO_PLEX set to true will sync updates between multiple plex servers +SYNC_FROM_PLEX_TO_JELLYFIN = "True" +SYNC_FROM_PLEX_TO_PLEX = "True" +SYNC_FROM_PLEX_TO_EMBY = "True" + +SYNC_FROM_JELLYFIN_TO_PLEX = "False" +SYNC_FROM_JELLYFIN_TO_JELLYFIN = "False" +SYNC_FROM_JELLYFIN_TO_EMBY = "False" + +SYNC_FROM_EMBY_TO_PLEX = "False" +SYNC_FROM_EMBY_TO_JELLYFIN = "False" +SYNC_FROM_EMBY_TO_EMBY = "False" \ No newline at end of file diff --git a/test/ci_write.env b/test/ci_write.env index 7afa0b5..5e229f0 100644 --- a/test/ci_write.env +++ b/test/ci_write.env @@ -7,7 +7,7 @@ DRYRUN = "False" DEBUG = "True" ## Debugging level, "info" is default, "debug" is more verbose -DEBUG_LEVEL = "debug" +DEBUG_LEVEL = "info" ## If set to true then the script will only run once and then exit RUN_ONLY_ONCE = "True" diff --git a/test/validate_ci_marklog.py b/test/validate_ci_marklog.py index 1416100..5d18785 100644 --- a/test/validate_ci_marklog.py +++ b/test/validate_ci_marklog.py @@ -4,15 +4,12 @@ import os, argparse def parse_args(): - parser = argparse.ArgumentParser( - description="Check the mark.log file that is generated by the CI to make sure it contains the expected values" - ) - parser.add_argument( - "--dry", action="store_true", help="Check the mark.log file for dry-run" - ) - parser.add_argument( - "--write", action="store_true", help="Check the mark.log file for write-run" - ) + parser = argparse.ArgumentParser(description="Check the mark.log file that is generated by the CI to make sure it contains the expected values") + parser.add_argument("--dry", action="store_true", help="Check the mark.log file for dry-run") + parser.add_argument("--write", action="store_true", help="Check the mark.log file for write-run") + parser.add_argument("--plex", action="store_true", help="Check the mark.log file for Plex") + parser.add_argument("--jellyfin", action="store_true", help="Check the mark.log file for Jellyfin") + parser.add_argument("--emby", action="store_true", help="Check the mark.log file for Emby") return parser.parse_args() @@ -43,7 +40,8 @@ def check_marklog(lines, expected_values): + str(len(found_values)) + " values, expected " + str(len(expected_values)) - + " values" + + " values\n" + + "\n".join(found_values) ) # Check that the two lists contain the same values @@ -63,12 +61,8 @@ def check_marklog(lines, expected_values): def main(): args = parse_args() - - # Expected values for the mark.log file, dry-run is slightly different than write-run - # due to some of the items being copied over from one server to another and now being there - # for the next server run. - if args.dry: - expected_values = [ + expected = { + "dry": [ # Jellyfin -> Plex "jellyplex_watched/Movies/Five Nights at Freddy's", "jellyplex_watched/Movies/The Hunger Games: The Ballad of Songbirds & Snakes/301215", @@ -91,11 +85,9 @@ def main(): "JellyUser/Movies/Tears of Steel", # Jellyfin -> Emby "jellyplex_watched/Movies/The Family Plan", - "jellyplex_watched/Movies/Five Nights at Freddy's", - ] - - elif args.write: - expected_values = [ + "jellyplex_watched/Movies/Five Nights at Freddy's" + ], + "write": [ "jellyplex_watched/Movies/Five Nights at Freddy's", "jellyplex_watched/Movies/The Hunger Games: The Ballad of Songbirds & Snakes/301215", "jellyplex_watched/TV Shows/Doctor Who (2005)/Rose", @@ -113,8 +105,49 @@ def main(): "jellyplex_watched/Movies/Five Nights at Freddy's", "JellyUser/Movies/Tears of Steel", "jellyplex_watched/TV shows/Doctor Who (2005)/World War Three (2)", + "jellyplex_watched/TV shows/Monarch: Legacy of Monsters/Parallels and Interiors/240429" + ], + "plex": [ + "JellyUser/Movies/Big Buck Bunny", + "JellyUser/Shows/Doctor Who/The Unquiet Dead", + "JellyUser/Shows/Monarch: Legacy of Monsters/Secrets and Lies", + "jellyplex_watched/Movies/Big Buck Bunny", + "jellyplex_watched/Movies/The Family Plan", + ], + "jellyfin": [ + "jellyplex_watched/Movies/Five Nights at Freddy's", + "jellyplex_watched/Movies/The Hunger Games: The Ballad of Songbirds & Snakes/301215", + "jellyplex_watched/TV Shows/Doctor Who (2005)/Rose", + "jellyplex_watched/TV Shows/Doctor Who (2005)/The End of the World/300670", + "jellyplex_watched/TV Shows/Monarch: Legacy of Monsters/Aftermath", + "jellyplex_watched/TV Shows/Monarch: Legacy of Monsters/Departure/300741", + "jellyplex_watched/Movies/The Family Plan", + "jellyplex_watched/Movies/Five Nights at Freddy's" + ], + "emby": [ + "jellyplex_watched/Movies/Tears of Steel", + "jellyplex_watched/TV shows/Doctor Who (2005)/World War Three (2)", "jellyplex_watched/TV shows/Monarch: Legacy of Monsters/Parallels and Interiors/240429", + "JellyUser/Movies/Tears of Steel" ] + } + + # Expected values for the mark.log file, dry-run is slightly different than write-run + # due to some of the items being copied over from one server to another and now being there + # for the next server run. + if args.dry: + expected_values = expected["dry"] + elif args.write: + expected_values = expected["write"] + elif args.plex: + expected_values = expected["plex"] + elif args.jellyfin: + expected_values = expected["jellyfin"] + elif args.emby: + expected_values = expected["emby"] + else: + print("No server specified") + exit(1) lines = read_marklog() if not check_marklog(lines, expected_values):