def webhook(bind: str, port: int): """ Listen for WebHook data from HTTP """ with socketserver.TCPServer((bind, port), HttpRequestHandler, bind_and_activate=False) as httpd: plex = factory.plex_api() mf = factory.media_factory() httpd.allow_reuse_address = True httpd.webhook = WebhookHandler(plex, mf) try: click.echo(f"Serving at http://{bind}:{port}") try: httpd.server_bind() httpd.server_activate() except Exception: httpd.server_close() raise httpd.serve_forever() except KeyboardInterrupt: pass httpd.server_close() click.echo("Stopping httpd...")
def watch(): server = factory.plex_server() trakt = factory.trakt_api() plex = factory.plex_api() mf = factory.media_factory() config = factory.config() ws = WebSocketListener(server) updater = WatchStateUpdater(plex, trakt, mf, config) ws.on( PlaySessionStateNotification, updater.on_play, state=["playing", "stopped", "paused"], ) ws.on( ActivityNotification, updater.on_activity, type="library.refresh.items", event="ended", progress=100, ) ws.on(TimelineEntry, updater.on_delete, state=9, metadata_state="deleted") ws.on(Error, updater.on_error) print("Listening for events!") ws.listen()
def inspect_media(id): plex = factory.plex_api() mf = factory.media_factory() print("") pm = plex.fetch_item(id) if not pm: print(f"Inspecting {id}: Not found") return print(f"Inspecting {id}: {pm}") url = plex.media_url(pm) print(f"URL: {url}") media = pm.item print(f"Media.Type: {media.type}") print(f"Media.Guid: '{media.guid}'") if not pm.is_legacy_agent: print(f"Media.Guids: {media.guids}") if media.type in ["episode", "movie"]: audio = pm.audio_streams[0] print(f"Audio: '{audio.audioChannelLayout}', '{audio.displayTitle}'") video = pm.video_streams[0] print(f"Video: '{video.codec}'") print("Parts:") for index, part in enumerate(pm.parts, start=1): print(f" Part {index}: {part.file}") print("Guids:") for guid in pm.guids: print(f" Guid: {guid}, Id: {guid.id}, Provider: {guid.provider}") print(f"Metadata: {pm.to_json()}") m = mf.resolve_any(pm) if not m: return # fetch show property for watched_on_trakt if m.is_episode: ps = plex.fetch_item(m.plex.item.grandparentRatingKey) ms = mf.resolve_any(ps) m.show = ms print(f"Trakt: {m.trakt_url}") print(f"Plex Rating: {m.plex_rating}") print(f"Trakt Rating: {m.trakt_rating}") print(f"Watched on Plex: {m.watched_on_plex}") print(f"Watched on Trakt: {m.watched_on_trakt}") print("Plex play history:") for h in m.plex_history(device=True, account=True): print( f"- {h.viewedAt} by {h.account.name} on {h.device.name} with {h.device.platform}" )
def unmatched(no_progress_bar: bool, local: bool): """ List media that has no match in Trakt or Plex """ config = factory.run_config().update(progressbar=not no_progress_bar) ensure_login() plex = factory.plex_api() trakt = factory.trakt_api() mf = factory.media_factory() pb = factory.progressbar(config.progressbar) wc = WalkConfig() walker = Walker(plex, trakt, mf, wc, progressbar=pb) if not wc.is_valid(): click.echo("Nothing to scan, this is likely due conflicting options given.") return failed = [] if local: for pm in walker.get_plex_movies(): if pm.guids[0].provider == 'local': failed.append(pm) else: for pm in walker.get_plex_movies(): movie = mf.resolve_any(pm) if not movie: failed.append(pm) for pm in failed: p = pm.item url = plex.media_url(pm) print("=" * 80) print(f"No match: {pm}") print(f"URL: {url}") print(f"Title: {p.title}") print(f"Year: {p.year}") print(f"Updated At: {p.updatedAt}") for l in p.locations: print(f"Location: {l}") print("")