initialize.py 13 KB

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