11#!/usr/bin/env python
2+ # Version 0.2.1 - Weston Nielson <wnielson@github>
3+ #
4+
25import json
36import logging
47import logging .config
1114import subprocess
1215import sys
1316import time
17+ import filecmp
1418#import requests
1519
1620from distutils .spawn import find_executable
7377LOAD_AVG_RE = re .compile (r"load averages: ([\d\.]+) ([\d\.]+) ([\d\.]+)" )
7478
7579__author__ = "Weston Nielson <wnielson@github>"
76- __version__ = "0.2.0"
80+ __version__ = "0.2.1"
81+
7782
7883def get_config ():
7984 path = os .path .expanduser ("~/.prt.conf" )
@@ -82,6 +87,7 @@ def get_config():
8287 except Exception , e :
8388 return DEFAULT_CONFIG .copy ()
8489
90+
8591def save_config (d ):
8692 path = os .path .expanduser ("~/.prt.conf" )
8793 try :
@@ -91,6 +97,7 @@ def save_config(d):
9197 print "Error loading config: %s" % str (e )
9298 return False
9399
100+
94101def get_system_load_local ():
95102 """
96103 Returns a list of float representing the percentage load of this machine.
@@ -99,6 +106,7 @@ def get_system_load_local():
99106 load = os .getloadavg ()
100107 return [l / nproc * 100 for l in load ]
101108
109+
102110def get_system_load_remote (host , port , user ):
103111 """
104112 Gets the result from ``get_system_load_local`` of a remote machine.
@@ -107,16 +115,19 @@ def get_system_load_remote(host, port, user):
107115 proc .wait ()
108116 return [float (i ) for i in proc .stdout .read ().strip ().split ()]
109117
118+
110119def setup_logging ():
111120 config = get_config ()
112121 logging .config .dictConfig (config ["logging" ])
113122
123+
114124def get_transcoder_path (name = NEW_TRANSCODER_NAME ):
115125 """
116126 Returns the full path to ``name`` located in ``TRANSCODER_DIR``.
117127 """
118128 return os .path .join (TRANSCODER_DIR , name )
119129
130+
120131def rename_transcoder ():
121132 """
122133 Moves the original transcoder "Plex New Transcoder" to the new name given
@@ -126,9 +137,9 @@ def rename_transcoder():
126137 new_path = get_transcoder_path (NEW_TRANSCODER_NAME )
127138
128139 if os .path .exists (new_path ):
129- print "Transcoder appears to have been renamed previously...not renaming"
140+ print "Transcoder appears to have been renamed previously...not renaming (try overwrite option) "
130141 return False
131-
142+
132143 try :
133144 os .rename (old_path , new_path )
134145 except Exception , e :
@@ -137,6 +148,7 @@ def rename_transcoder():
137148
138149 return True
139150
151+
140152def install_transcoder ():
141153 prt_remote = find_executable ("prt_remote" )
142154 if not prt_remote :
@@ -147,10 +159,41 @@ def install_transcoder():
147159 if rename_transcoder ():
148160 try :
149161 shutil .copyfile (prt_remote , get_transcoder_path (ORIGINAL_TRANSCODER_NAME ))
150- os .chmod (get_transcoder_path (ORIGINAL_TRANSCODER_NAME ), 0777 )
162+ os .chmod (get_transcoder_path (ORIGINAL_TRANSCODER_NAME ), 0755 )
151163 except Exception , e :
152164 print "Error installing new transcoder: %s" % str (e )
153165
166+
167+ # Overwrite_transcoder_after_upgrade function
168+ def overwrite_transcoder_after_upgrade ():
169+ """
170+ Moves the upgraded transcoder "Plex New Transcoder" to the new name given
171+ by ``TRANSCODER_NAME`` if the plex package has overwritten the old one.
172+ """
173+ old_path = get_transcoder_path (ORIGINAL_TRANSCODER_NAME )
174+ new_path = get_transcoder_path (NEW_TRANSCODER_NAME )
175+
176+ prt_remote = find_executable ("prt_remote" )
177+ if not prt_remote :
178+ print "Couldn't find `prt_remote` executable"
179+ sys .exit (2 )
180+ elif os .path .exists (new_path ):
181+ print "Transcoder appears to have been renamed previously...checking if it's been overwritten"
182+ if not filecmp .cmp (prt_remote , get_transcoder_path (ORIGINAL_TRANSCODER_NAME ), shallow = 1 ):
183+ try :
184+ shutil .copyfile (prt_remote , get_transcoder_path (ORIGINAL_TRANSCODER_NAME ))
185+ os .chmod (get_transcoder_path (ORIGINAL_TRANSCODER_NAME ), 0755 )
186+ except Exception , e :
187+ print "Error installing new transcoder: %s" % str (e )
188+ sys .exit (2 )
189+ else :
190+ print "Transcoder hasn't been overwritten by upgrade, nothing to do"
191+ sys .exit (1 )
192+ else :
193+ print "Transcoder hasn't been previously installed, please use install option"
194+ sys .exit (1 )
195+
196+
154197def transcode_local ():
155198 setup_logging ()
156199
@@ -167,6 +210,7 @@ def transcode_local():
167210 proc = subprocess .Popen (args )
168211 proc .wait ()
169212
213+
170214def transcode_remote ():
171215 setup_logging ()
172216
@@ -223,9 +267,9 @@ def transcode_remote():
223267 hostname , host = None , None
224268
225269 # Let's try to load-balance
226- min_load = None
270+ min_load = None
227271 for hostname , host in servers .items ():
228-
272+
229273 log .debug ("Getting load for host '%s'" % hostname )
230274 load = get_system_load_remote (hostname , host ["port" ], host ["user" ])
231275
@@ -244,7 +288,7 @@ def transcode_remote():
244288 if min_load is None :
245289 log .info ("No hosts found...using local" )
246290 return transcode_local ()
247-
291+
248292 # Select lowest-load host
249293 log .info ("Host with minimum load is '%s'" % min_load [0 ])
250294 hostname , host = min_load [0 ], servers [min_load [0 ]]
@@ -266,18 +310,39 @@ def transcode_remote():
266310 proc = subprocess .Popen (args )
267311 proc .wait ()
268312
313+
314+ def version ():
315+ print "Plex Remote Transcoder version %s, Copyright (C) %s\n " % (__version__ , __author__ )
316+
317+
318+ # Usage function
269319def usage ():
270- return
320+ __runningfile__ = os .path .basename (__file__ )
321+ print "Usage for Plex Remote Transcoder (prt)"
322+ print "%s [options]\n " % (__runningfile__ )
323+ print "Options:\n " \
324+ "usage, help, -h, ?\t shows usage page\n " \
325+ "get_load\t \t shows the load of the system\n " \
326+ "install\t \t \t installs PRT for the first time and then sets up configuration\n " \
327+ "overwrite\t \t fixes PRT after PMS has had a version update breaking PRT\n " \
328+ "add_host\t \t adds an extra host to the list of slaves PRT is to use\n " \
329+ "remove_host\t \t removes a host from the list of slaces PRT is to use\n "
330+
271331
272332def main ():
273- if len (sys .argv ) < 2 :
274- print "Plex Remote Transcoder version %s, Copyright (C) %s\n " % (__version__ , __author__ )
275- return usage ()
333+ # Specific usage options
334+ if any ( [len (sys .argv ) < 2 , sys .argv [1 ] == "usage" , sys .argv [1 ] == "help" , sys .argv [1 ] == "-h" ,
335+ sys .argv [1 ] == "?" ,] ):
336+ usage ()
337+ sys .exit (- 1 )
338+
339+ # TODO: get_load_all to show load currently across all nodes
340+ # TODO: show_hosts_status to show current status across all nodes
276341
277342 if sys .argv [1 ] == "get_load" :
278343 print " " .join ([str (i ) for i in get_system_load_local ()])
279344
280- if sys .argv [1 ] == "install" :
345+ elif sys .argv [1 ] == "install" :
281346 print "Installing Plex Remote Transcoder"
282347 config = get_config ()
283348 config ["ipaddress" ] = raw_input ("IP address of this machine: " )
@@ -312,7 +377,7 @@ def main():
312377 if raw_input ("Proceed: [y/n]" ).lower () == "y" :
313378 config = get_config ()
314379 config ["servers" ][host ] = {
315- "port" : port ,
380+ "port" : port ,
316381 "user" : user
317382 }
318383
@@ -326,3 +391,21 @@ def main():
326391 print "Host removed"
327392 except Exception , e :
328393 print "Error removing host: %s" % str (e )
394+
395+ # Added version option rather than just for no options
396+ elif any ( [sys .argv [1 ] == "version" , sys .argv [1 ] == "v" , sys .argv [1 ] == "V" ] ):
397+ version ()
398+ sys .exit (0 )
399+
400+ # Overwrite option (for after plex package update/upgrade)
401+ elif sys .argv [1 ] == "overwrite" :
402+ overwrite_transcoder_after_upgrade ()
403+ print "Transcoder overwritten successfully"
404+
405+ # Todo: list_hosts option to show current hosts to aid add/remove_host options - Liviynz
406+
407+ # Anything not listed shows usage
408+ else :
409+ usage ()
410+ sys .exit (- 1 )
411+
0 commit comments