Steven Smith revised this gist . Go to revision
1 file changed, 69 insertions, 9 deletions
getplex.py
| @@ -1,5 +1,15 @@ | |||
| 1 | 1 | #!/usr/bin/env python2.7 | |
| 2 | + | # Now with Plex auth support! Check getplex.py -h | |
| 3 | + | from __future__ import print_function | |
| 2 | 4 | from plexapi.server import PlexServer | |
| 5 | + | from plexapi.myplex import MyPlexUser | |
| 6 | + | from plexapi.exceptions import NotFound | |
| 7 | + | ||
| 8 | + | from urlparse import urlparse | |
| 9 | + | from getpass import getpass | |
| 10 | + | from socket import gethostbyname | |
| 11 | + | ||
| 12 | + | import sys | |
| 3 | 13 | import argparse | |
| 4 | 14 | ||
| 5 | 15 | DEFAULT_URI = "http://192.168.1.50:32400" | |
| @@ -16,8 +26,52 @@ def fmtcols(l): | |||
| 16 | 26 | o.append(u"{0:<{2}s} {1}".format(key, value, maxlen)) | |
| 17 | 27 | return u"\n".join(o) | |
| 18 | 28 | ||
| 19 | - | def get_server(uri=DEFAULT_URI): | |
| 20 | - | return PlexServer(uri) | |
| 29 | + | def info(*objs): | |
| 30 | + | print(*objs, file=sys.stderr) | |
| 31 | + | ||
| 32 | + | def prompt(*objs): | |
| 33 | + | old_stdout = sys.stdout | |
| 34 | + | try: | |
| 35 | + | sys.stdout = sys.stderr | |
| 36 | + | return raw_input(*objs) | |
| 37 | + | finally: | |
| 38 | + | sys.stdout = old_stdout | |
| 39 | + | ||
| 40 | + | def get_server(uri=DEFAULT_URI, username=None, password=None, servername=None): | |
| 41 | + | try: | |
| 42 | + | return PlexServer(uri) | |
| 43 | + | except NotFound: | |
| 44 | + | pass | |
| 45 | + | if not username and not password: | |
| 46 | + | info("Could not get server object, maybe you need to be authenticated?") | |
| 47 | + | username = prompt("Username: ") if not username else username | |
| 48 | + | password = getpass() if not password else password | |
| 49 | + | user = MyPlexUser.signin(username, password) | |
| 50 | + | if not servername: | |
| 51 | + | info("Servers: " + ", ".join(a.name for a in user.resources())) | |
| 52 | + | 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 | |
| 53 | + | if servername: | |
| 54 | + | return user.getResource(servername).connect() | |
| 55 | + | else: | |
| 56 | + | info("OK, beginning the search process.") | |
| 57 | + | # necessary to match correct server | |
| 58 | + | if uri.count(":") >= 2: | |
| 59 | + | ip = ":".join(urlparse(uri).netloc.split(":")[:-1]) | |
| 60 | + | else: | |
| 61 | + | ip = urlparse(uri).netloc | |
| 62 | + | info("Getting IP for {}".format(ip)) | |
| 63 | + | ip = gethostbyname(ip) | |
| 64 | + | info("Got IP from hostname: {}".format(ip) if ip not in uri else "Searching for {}".format(ip)) | |
| 65 | + | for srv in user.resources(): | |
| 66 | + | try: | |
| 67 | + | server = srv.connect() | |
| 68 | + | if ip in server.baseuri: | |
| 69 | + | info("Found server: {}".format(srv.name)) | |
| 70 | + | return server | |
| 71 | + | except NotFound: | |
| 72 | + | info("Couldn't connect to {}".format(srv.name)) | |
| 73 | + | info("Couldn't find server in your user's server list.") | |
| 74 | + | return None | |
| 21 | 75 | ||
| 22 | 76 | def lookup_movie(server, movie): | |
| 23 | 77 | return server.library.section("Movies").get(movie) | |
| @@ -31,22 +85,28 @@ def main(): | |||
| 31 | 85 | group.add_argument("-m", "--movie", help="Specify movie. Must be exact title.") | |
| 32 | 86 | group.add_argument("-s", "--show", help="Specify show. Must be exact title.") | |
| 33 | 87 | parser.add_argument("-e", "--episode", help="Specify episode. Get list of episodes by specifying show") | |
| 34 | - | parser.add_argument("-S", "--server", nargs="?", help="Specify server. Defaults to {}".format(DEFAULT_URI), default=DEFAULT_URI) | |
| 88 | + | parser.add_argument("-S", "--server", help="Specify server. Defaults to {}".format(DEFAULT_URI), default=DEFAULT_URI) | |
| 89 | + | parser.add_argument("-u", "--username", help="Specify username. Used for Plex authentication") | |
| 90 | + | parser.add_argument("-p", "--password", help="Specify password. Provided for convenience only, preferred method is to omit this and enter password at the prompt.") | |
| 91 | + | parser.add_argument("--servername", help="Specify server name. Used with -u above, for Plex authentication.") | |
| 35 | 92 | args = parser.parse_args() | |
| 36 | - | server = get_server(args.server) | |
| 93 | + | server = get_server(args.server, username=args.username, password=args.password, servername=args.servername) | |
| 94 | + | if not server: | |
| 95 | + | info("Aborting.") | |
| 96 | + | return | |
| 37 | 97 | if args.movie is not None: | |
| 38 | 98 | if args.movie is "": | |
| 39 | - | print fmtcols([u"{}".format(movie.title) for movie in server.library.section("Movies").all()]) | |
| 99 | + | print(fmtcols([u"{}".format(movie.title) for movie in server.library.section("Movies").all()])) | |
| 40 | 100 | else: | |
| 41 | - | print lookup_movie(server, args.movie).getStreamUrl() | |
| 101 | + | print(lookup_movie(server, args.movie).getStreamUrl()) | |
| 42 | 102 | elif args.show is not None: | |
| 43 | 103 | if args.show is "": | |
| 44 | - | print fmtcols([u"{}".format(show.title) for show in server.library.section("TV Shows").all()]) | |
| 104 | + | print(fmtcols([u"{}".format(show.title) for show in server.library.section("TV Shows").all()])) | |
| 45 | 105 | else: | |
| 46 | 106 | if args.episode: | |
| 47 | - | print lookup_episode(server, args.show, args.episode).getStreamUrl() | |
| 107 | + | print(lookup_episode(server, args.show, args.episode).getStreamUrl()) | |
| 48 | 108 | else: | |
| 49 | - | 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()]) | |
| 109 | + | 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()])) | |
| 50 | 110 | ||
| 51 | 111 | if __name__ == "__main__": | |
| 52 | 112 | main() | |
Steven Smith revised this gist . Go to revision
1 file changed, 1 insertion
getplex.py
| @@ -1,3 +1,4 @@ | |||
| 1 | + | #!/usr/bin/env python2.7 | |
| 1 | 2 | from plexapi.server import PlexServer | |
| 2 | 3 | import argparse | |
| 3 | 4 | ||
Steven Smith revised this gist . Go to revision
1 file changed, 51 insertions
getplex.py(file created)
| @@ -0,0 +1,51 @@ | |||
| 1 | + | from plexapi.server import PlexServer | |
| 2 | + | import argparse | |
| 3 | + | ||
| 4 | + | DEFAULT_URI = "http://192.168.1.50:32400" | |
| 5 | + | ||
| 6 | + | def fmtcols(l): | |
| 7 | + | maxlen = max(len(i) for i in l) | |
| 8 | + | if len(l) % 2 != 0: | |
| 9 | + | l.append(" ") | |
| 10 | + | split = len(l)/2 | |
| 11 | + | l1 = l[0:split] | |
| 12 | + | l2 = l[split:] | |
| 13 | + | o = [] | |
| 14 | + | for key, value in zip(l1,l2): | |
| 15 | + | o.append(u"{0:<{2}s} {1}".format(key, value, maxlen)) | |
| 16 | + | return u"\n".join(o) | |
| 17 | + | ||
| 18 | + | def get_server(uri=DEFAULT_URI): | |
| 19 | + | return PlexServer(uri) | |
| 20 | + | ||
| 21 | + | def lookup_movie(server, movie): | |
| 22 | + | return server.library.section("Movies").get(movie) | |
| 23 | + | ||
| 24 | + | def lookup_episode(server, show, episode): | |
| 25 | + | return server.library.section("TV Shows").get(show).episode(episode) | |
| 26 | + | ||
| 27 | + | def main(): | |
| 28 | + | parser = argparse.ArgumentParser() | |
| 29 | + | group = parser.add_mutually_exclusive_group() | |
| 30 | + | group.add_argument("-m", "--movie", help="Specify movie. Must be exact title.") | |
| 31 | + | group.add_argument("-s", "--show", help="Specify show. Must be exact title.") | |
| 32 | + | parser.add_argument("-e", "--episode", help="Specify episode. Get list of episodes by specifying show") | |
| 33 | + | parser.add_argument("-S", "--server", nargs="?", help="Specify server. Defaults to {}".format(DEFAULT_URI), default=DEFAULT_URI) | |
| 34 | + | args = parser.parse_args() | |
| 35 | + | server = get_server(args.server) | |
| 36 | + | if args.movie is not None: | |
| 37 | + | if args.movie is "": | |
| 38 | + | print fmtcols([u"{}".format(movie.title) for movie in server.library.section("Movies").all()]) | |
| 39 | + | else: | |
| 40 | + | print lookup_movie(server, args.movie).getStreamUrl() | |
| 41 | + | elif args.show is not None: | |
| 42 | + | if args.show is "": | |
| 43 | + | print fmtcols([u"{}".format(show.title) for show in server.library.section("TV Shows").all()]) | |
| 44 | + | else: | |
| 45 | + | if args.episode: | |
| 46 | + | print lookup_episode(server, args.show, args.episode).getStreamUrl() | |
| 47 | + | else: | |
| 48 | + | 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()]) | |
| 49 | + | ||
| 50 | + | if __name__ == "__main__": | |
| 51 | + | main() | |