#!/usr/bin/env python2.7 # Now with Plex auth support! Check getplex.py -h from __future__ import print_function from plexapi.server import PlexServer from plexapi.myplex import MyPlexUser from plexapi.exceptions import NotFound from urlparse import urlparse from getpass import getpass from socket import gethostbyname import sys import argparse DEFAULT_URI = "http://192.168.1.50:32400" def fmtcols(l): maxlen = max(len(i) for i in l) if len(l) % 2 != 0: l.append(" ") split = len(l)/2 l1 = l[0:split] l2 = l[split:] o = [] for key, value in zip(l1,l2): o.append(u"{0:<{2}s} {1}".format(key, value, maxlen)) return u"\n".join(o) def info(*objs): print(*objs, file=sys.stderr) def prompt(*objs): old_stdout = sys.stdout try: sys.stdout = sys.stderr return raw_input(*objs) finally: sys.stdout = old_stdout def get_server(uri=DEFAULT_URI, username=None, password=None, servername=None): try: return PlexServer(uri) except NotFound: pass if not username and not password: info("Could not get server object, maybe you need to be authenticated?") username = prompt("Username: ") if not username else username password = getpass() if not password else password user = MyPlexUser.signin(username, password) if not servername: info("Servers: " + ", ".join(a.name for a in user.resources())) servername = prompt("Please enter server name. If you don't know it, press enter and I'll (very slowly!) search for the correct server: ") or None if servername: return user.getResource(servername).connect() else: info("OK, beginning the search process.") # necessary to match correct server if uri.count(":") >= 2: ip = ":".join(urlparse(uri).netloc.split(":")[:-1]) else: ip = urlparse(uri).netloc info("Getting IP for {}".format(ip)) ip = gethostbyname(ip) info("Got IP from hostname: {}".format(ip) if ip not in uri else "Searching for {}".format(ip)) for srv in user.resources(): try: server = srv.connect() if ip in server.baseuri: info("Found server: {}".format(srv.name)) return server except NotFound: info("Couldn't connect to {}".format(srv.name)) info("Couldn't find server in your user's server list.") return None def lookup_movie(server, movie): return server.library.section("Movies").get(movie) def lookup_episode(server, show, episode): return server.library.section("TV Shows").get(show).episode(episode) def main(): parser = argparse.ArgumentParser() group = parser.add_mutually_exclusive_group() group.add_argument("-m", "--movie", help="Specify movie. Must be exact title.") group.add_argument("-s", "--show", help="Specify show. Must be exact title.") parser.add_argument("-e", "--episode", help="Specify episode. Get list of episodes by specifying show") parser.add_argument("-S", "--server", help="Specify server. Defaults to {}".format(DEFAULT_URI), default=DEFAULT_URI) parser.add_argument("-u", "--username", help="Specify username. Used for Plex authentication") parser.add_argument("-p", "--password", help="Specify password. Provided for convenience only, preferred method is to omit this and enter password at the prompt.") parser.add_argument("--servername", help="Specify server name. Used with -u above, for Plex authentication.") args = parser.parse_args() server = get_server(args.server, username=args.username, password=args.password, servername=args.servername) if not server: info("Aborting.") return if args.movie is not None: if args.movie is "": print(fmtcols([u"{}".format(movie.title) for movie in server.library.section("Movies").all()])) else: print(lookup_movie(server, args.movie).getStreamUrl()) elif args.show is not None: if args.show is "": print(fmtcols([u"{}".format(show.title) for show in server.library.section("TV Shows").all()])) else: if args.episode: print(lookup_episode(server, args.show, args.episode).getStreamUrl()) else: print(fmtcols([u"S{}E{} {}".format(ep.parentIndex.zfill(2), ep.index.zfill(2), ep.title) for ep in server.library.section("TV Shows").get(args.show).episodes()])) if __name__ == "__main__": main()