initialize.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. import argparse
  2. import configparser
  3. import logging
  4. import os.path
  5. import sys
  6. import subprocess
  7. import time
  8. from .auth import login
  9. from .logger import log, seperator, supports_color
  10. from .downloader import main
  11. from .settings import settings
  12. script_version = "2.3.5"
  13. python_version = sys.version.split(' ')[0]
  14. bool_values = {'True', 'False'}
  15. def check_ffmpeg():
  16. try:
  17. FNULL = open(os.devnull, 'w')
  18. subprocess.call(["ffmpeg"], stdout=FNULL, stderr=subprocess.STDOUT)
  19. return True
  20. except OSError as e:
  21. return False
  22. def check_config_validity(config):
  23. try:
  24. has_thrown_errors = False
  25. settings.username = config.get('pyinstalive', 'username')
  26. settings.password = config.get('pyinstalive', 'password')
  27. try:
  28. settings.show_cookie_expiry = config.get('pyinstalive', 'show_cookie_expiry').title()
  29. if not settings.show_cookie_expiry in bool_values:
  30. log("[W] Invalid or missing setting detected for 'show_cookie_expiry', using default value (True)", "YELLOW")
  31. settings.show_cookie_expiry = 'true'
  32. has_thrown_errors = True
  33. except:
  34. log("[W] Invalid or missing setting detected for 'show_cookie_expiry', using default value (True)", "YELLOW")
  35. settings.show_cookie_expiry = 'true'
  36. has_thrown_errors = True
  37. try:
  38. settings.clear_temp_files = config.get('pyinstalive', 'clear_temp_files').title()
  39. if not settings.clear_temp_files in bool_values:
  40. log("[W] Invalid or missing setting detected for 'clear_temp_files', using default value (True)", "YELLOW")
  41. settings.clear_temp_files = 'true'
  42. has_thrown_errors = True
  43. except:
  44. log("[W] Invalid or missing setting detected for 'clear_temp_files', using default value (True)", "YELLOW")
  45. settings.clear_temp_files = 'true'
  46. has_thrown_errors = True
  47. try:
  48. settings.save_replays = config.get('pyinstalive', 'save_replays').title()
  49. if not settings.save_replays in bool_values:
  50. log("[W] Invalid or missing setting detected for 'save_replays', using default value (True)", "YELLOW")
  51. settings.save_replays = 'true'
  52. has_thrown_errors = True
  53. except:
  54. log("[W] Invalid or missing setting detected for 'save_replays', using default value (True)", "YELLOW")
  55. settings.save_replays = 'true'
  56. has_thrown_errors = True
  57. try:
  58. settings.run_at_start = config.get('pyinstalive', 'run_at_start')
  59. if (settings.run_at_start):
  60. if not os.path.isfile(settings.run_at_start):
  61. log("[W] Path to file given for 'run_at_start' does not exist, using default value (None)", "YELLOW")
  62. settings.run_at_start = "None"
  63. has_thrown_errors = True
  64. else:
  65. if not settings.run_at_start.split('.')[-1] == 'py':
  66. log("[W] File given for 'run_at_start' is not a Python script, using default value (None)", "YELLOW")
  67. settings.run_at_start = "None"
  68. has_thrown_errors = True
  69. else:
  70. settings.run_at_start = "None"
  71. except:
  72. log("[W] Invalid or missing settings detected for 'run_at_start', using default value (None)", "YELLOW")
  73. settings.run_at_start = "None"
  74. has_thrown_errors = True
  75. try:
  76. settings.run_at_finish = config.get('pyinstalive', 'run_at_finish')
  77. if (settings.run_at_finish):
  78. if not os.path.isfile(settings.run_at_finish):
  79. log("[W] Path to file given for 'run_at_finish' does not exist, using default value (None)", "YELLOW")
  80. settings.run_at_finish = "None"
  81. has_thrown_errors = True
  82. else:
  83. if not settings.run_at_finish.split('.')[-1] == 'py':
  84. log("[W] File given for 'run_at_finish' is not a Python script, using default value (None)", "YELLOW")
  85. settings.run_at_finish = "None"
  86. has_thrown_errors = True
  87. else:
  88. settings.run_at_finish = "None"
  89. except:
  90. log("[W] Invalid or missing settings detected for 'run_at_finish', using default value (None)", "YELLOW")
  91. settings.run_at_finish = "None"
  92. has_thrown_errors = True
  93. try:
  94. settings.save_comments = config.get('pyinstalive', 'save_comments').title()
  95. if sys.version.split(' ')[0].startswith('2') and settings.save_comments == "True":
  96. log("[W] Comment saving is not supported in Python 2 and will be ignored.", "YELLOW")
  97. settings.save_comments = 'false'
  98. has_thrown_errors = True
  99. else:
  100. if not settings.show_cookie_expiry in bool_values:
  101. log("[W] Invalid or missing setting detected for 'save_comments', using default value (False)", "YELLOW")
  102. settings.save_comments = 'false'
  103. has_thrown_errors = True
  104. except:
  105. log("[W] Invalid or missing setting detected for 'save_comments', using default value (False)", "YELLOW")
  106. settings.save_comments = 'false'
  107. has_thrown_errors = True
  108. try:
  109. settings.save_path = config.get('pyinstalive', 'save_path')
  110. if (os.path.exists(settings.save_path)):
  111. pass
  112. else:
  113. log("[W] Invalid or missing setting detected for 'save_path', falling back to path: " + os.getcwd(), "YELLOW")
  114. settings.save_path = os.getcwd()
  115. has_thrown_errors = True
  116. if not settings.save_path.endswith('/'):
  117. settings.save_path = settings.save_path + '/'
  118. except:
  119. log("[W] Invalid or missing setting detected for 'save_path', falling back to path: " + os.getcwd(), "YELLOW")
  120. settings.save_path = os.getcwd()
  121. has_thrown_errors = True
  122. if has_thrown_errors:
  123. seperator("GREEN")
  124. if not (len(settings.username) > 0):
  125. log("[E] Invalid or missing setting detected for 'username'.", "RED")
  126. return False
  127. if not (len(settings.password) > 0):
  128. log("[E] Invalid or missing setting detected for 'password'.", "RED")
  129. return False
  130. return True
  131. except Exception as e:
  132. return False
  133. def show_info(config):
  134. if os.path.exists('pyinstalive.ini'):
  135. try:
  136. config.read('pyinstalive.ini')
  137. except Exception:
  138. log("[E] Could not read configuration file.", "RED")
  139. seperator("GREEN")
  140. else:
  141. new_config()
  142. sys.exit(1)
  143. if not check_config_validity(config):
  144. log("[W] Config file is not valid, some information may be inaccurate.", "YELLOW")
  145. log("", "GREEN")
  146. cookie_files = []
  147. cookie_from_config = ''
  148. try:
  149. for file in os.listdir(os.getcwd()):
  150. if file.endswith(".json"):
  151. cookie_files.append(file)
  152. if settings.username == file.replace(".json", ''):
  153. cookie_from_config = file
  154. except Exception as e:
  155. log("[W] Could not check for cookie files: " + str(e), "YELLOW")
  156. log("", "ENDC")
  157. log("[I] To see all the available flags, use the -h flag.", "BLUE")
  158. log("", "GREEN")
  159. log("[I] PyInstaLive version: " + script_version, "GREEN")
  160. log("[I] Python version: " + python_version, "GREEN")
  161. if check_ffmpeg() == False:
  162. log("[E] FFmpeg framework: Not found", "RED")
  163. else:
  164. log("[I] FFmpeg framework: Available", "GREEN")
  165. if (len(cookie_from_config) > 0):
  166. log("[I] Cookie files: {} ({} matches config user)".format(str(len(cookie_files)), cookie_from_config), "GREEN")
  167. elif len(cookie_files) > 0:
  168. log("[I] Cookie files: {}".format(str(len(cookie_files))), "GREEN")
  169. else:
  170. log("[W] Cookie files: None found", "YELLOW")
  171. log("[I] CLI supports color: " + str(supports_color()), "GREEN")
  172. log("[I] File to run at start: " + settings.run_at_start, "GREEN")
  173. log("[I] File to run at finish: " + settings.run_at_finish, "GREEN")
  174. log("", "GREEN")
  175. if os.path.exists('pyinstalive.ini'):
  176. log("[I] Config file:", "GREEN")
  177. log("", "GREEN")
  178. with open('pyinstalive.ini') as f:
  179. for line in f:
  180. log(" " + line.rstrip(), "YELLOW")
  181. else:
  182. log("[E] Config file: Not found", "RED")
  183. log("", "GREEN")
  184. log("[I] End of PyInstaLive information screen.", "GREEN")
  185. seperator("GREEN")
  186. def new_config():
  187. try:
  188. if os.path.exists('pyinstalive.ini'):
  189. log("[I] A configuration file is already present:", "GREEN")
  190. log("", "GREEN")
  191. with open('pyinstalive.ini') as f:
  192. for line in f:
  193. log(" " + line.rstrip(), "YELLOW")
  194. log("", "GREEN")
  195. log("[W] To create a default config file, delete 'pyinstalive.ini' and ", "YELLOW")
  196. log(" run this script again.", "YELLOW")
  197. seperator("GREEN")
  198. else:
  199. try:
  200. log("[W] Could not find configuration file, creating a default one...", "YELLOW")
  201. config_template = "[pyinstalive]\nusername = johndoe\npassword = grapefruits\nsave_path = " + os.getcwd() + "\nshow_cookie_expiry = true\nclear_temp_files = false\nsave_replays = true\nrun_at_start = \nrun_at_finish = \n"
  202. config_file = open("pyinstalive.ini", "w")
  203. config_file.write(config_template)
  204. config_file.close()
  205. log("[W] Edit the created 'pyinstalive.ini' file and run this script again.", "YELLOW")
  206. seperator("GREEN")
  207. sys.exit(0)
  208. except Exception as e:
  209. log("[E] Could not create default config file: " + str(e), "RED")
  210. log("[W] You must manually create and edit it with the following template: ", "YELLOW")
  211. log("", "GREEN")
  212. log(config_template, "YELLOW")
  213. log("", "GREEN")
  214. log("[W] Save it as 'pyinstalive.ini' and run this script again.", "YELLOW")
  215. seperator("GREEN")
  216. except Exception as e:
  217. log("[E] An error occurred: " + str(e), "RED")
  218. log("[W] If you don't have a configuration file, you must", "YELLOW")
  219. log(" manually create and edit it with the following template: ", "YELLOW")
  220. log("", "GREEN")
  221. log(config_template, "YELLOW")
  222. log("", "GREEN")
  223. log("[W] Save it as 'pyinstalive.ini' and run this script again.", "YELLOW")
  224. seperator("GREEN")
  225. def run():
  226. seperator("GREEN")
  227. log('PYINSTALIVE (SCRIPT V{} - PYTHON V{}) - {}'.format(script_version, python_version, time.strftime('%I:%M:%S %p')), "GREEN")
  228. seperator("GREEN")
  229. logging.disable(logging.CRITICAL)
  230. config = configparser.ConfigParser()
  231. parser = argparse.ArgumentParser(description='You are running PyInstaLive ' + script_version + " using Python " + python_version)
  232. parser.add_argument('-u', '--username', dest='username', type=str, required=False, help="Instagram username to login with.")
  233. parser.add_argument('-p', '--password', dest='password', type=str, required=False, help="Instagram password to login with.")
  234. parser.add_argument('-r', '--record', dest='record', type=str, required=False, help="The username of the user whose livestream or replay you want to save.")
  235. parser.add_argument('-i', '--info', dest='info', action='store_true', help="View information about PyInstaLive.")
  236. parser.add_argument('-c', '--config', dest='config', action='store_true', help="Create a default configuration file if it doesn't exist.")
  237. parser.add_argument('-nr', '--noreplays', dest='noreplays', action='store_true', help="When used, do not check for any available replays.")
  238. # Workaround to 'disable' argument abbreviations
  239. parser.add_argument('--usernamx', help=argparse.SUPPRESS, metavar='IGNORE')
  240. parser.add_argument('--passworx', help=argparse.SUPPRESS, metavar='IGNORE')
  241. parser.add_argument('--recorx', help=argparse.SUPPRESS, metavar='IGNORE')
  242. parser.add_argument('--infx', help=argparse.SUPPRESS, metavar='IGNORE')
  243. parser.add_argument('--confix', help=argparse.SUPPRESS, metavar='IGNORE')
  244. parser.add_argument('--noreplayx', help=argparse.SUPPRESS, metavar='IGNORE')
  245. # Erase line that tells the user the error has to do with ambiguous arguments
  246. try:
  247. args = parser.parse_args()
  248. except SystemExit as e:
  249. args_raw = sys.argv[1:]
  250. if "-h" not in args_raw and "--help" not in args_raw:
  251. CURSOR_UP_ONE = '\x1b[1A'
  252. ERASE_LINE = '\x1b[2K'
  253. log(CURSOR_UP_ONE + ERASE_LINE + CURSOR_UP_ONE + "[E] Invalid argument(s) were provided in command: " + ' ' * 50, "RED")
  254. log(" pyinstalive " + ' '.join(args_raw), "YELLOW")
  255. log("\n[I] Usage for PyInstaLive is printed below.\n", "GREEN")
  256. parser.print_help()
  257. sys.exit(1)
  258. else:
  259. sys.exit(0)
  260. if (args.username == None
  261. and args.password == None
  262. and args.record == None
  263. and args.info == False
  264. and args.config == False) or (args.info != False):
  265. show_info(config)
  266. sys.exit(0)
  267. if (args.config == True):
  268. new_config()
  269. sys.exit(0)
  270. if os.path.exists('pyinstalive.ini'):
  271. try:
  272. config.read('pyinstalive.ini')
  273. except Exception:
  274. log("[E] Could not read configuration file. Try passing the required arguments manually.", "RED")
  275. seperator("GREEN")
  276. else:
  277. new_config()
  278. sys.exit(1)
  279. if check_config_validity(config):
  280. if check_ffmpeg() == False:
  281. log("[E] Could not find ffmpeg, the script will now exit. ", "RED")
  282. seperator("GREEN")
  283. sys.exit(1)
  284. if (args.record == None):
  285. log("[E] Missing --record argument. Please specify an Instagram username.", "RED")
  286. seperator("GREEN")
  287. sys.exit(1)
  288. if (args.noreplays == True):
  289. settings.save_replays = "false"
  290. if (args.username is not None) and (args.password is not None):
  291. api = login(args.username, args.password, settings.show_cookie_expiry, True)
  292. else:
  293. if (args.username is not None) or (args.password is not None):
  294. log("[W] Missing -u or -p arguments, falling back to config login...", "YELLOW")
  295. api = login(settings.username, settings.password, settings.show_cookie_expiry, False)
  296. main(api, args.record, settings)
  297. else:
  298. log("[E] The configuration file is not valid. Please check your configuration settings and try again.", "RED")
  299. seperator("GREEN")
  300. sys.exit(0)