diff --git a/, b/, new file mode 100644 index 0000000..640572f --- /dev/null +++ b/, @@ -0,0 +1,163 @@ +import get_meetings +import subprocess +import datetime +import os +import json +import time +import sys +from smb.SMBConnection import SMBConnection + +RECORD_PATH = "recordings" +LISTENING_VIDEO_PATH = "listening.mkv" +VIRTUAL_CAMERA_PATH = "/dev/video2" +PULSEAUDIO_INDEX = 5 +X_OFFSET = sys.argv[1] +PULSEAUDIO_INDEX = sys.argv[2] +AUTO_LOGIN = sys.argv[3] == 1 + +RECORD_TEMPLATE = ["ffmpeg", "-nostdin", "-video_size", "1920x1080", "-f", "x11grab", "-i", ":0.0+{},0".format(X_OFFSET), "-f", "pulse", "-ac", "2", "-i", str(PULSEAUDIO_INDEX), "-vcodec", "libx264", "-crf", "0", "-preset", "ultrafast", "-acodec", "pcm_s16le"] +CAMERA_TEMPLATE = ["ffmpeg", "-re", "-i", LISTENING_VIDEO_PATH, "-map", "0:v", "-f", "v4l2", VIRTUAL_CAMERA_PATH] +COMPRESSION_TEMPLATE = ["ffmpeg", "-i", None, "-vcodec", "libx265", "-crf", "28", None] + + +if not os.path.exists(VIRTUAL_CAMERA_PATH): + os.system("sudo modprobe -r v4l2loopback") + os.system("sudo modprobe v4l2loopback") + +if not os.path.exists(RECORD_PATH): + os.mkdir(RECORD_PATH) + +with open("config.json", "r") as f: + config = json.loads(f.read()) + creds = config["creds"] + backup_creds = config["backup"] + +next_day = datetime.datetime.today() + +def backup(directory): + conn = SMBConnection(backup_creds["user"], backup_creds["password"], + backup_creds["server_name"], backup_creds["server_name"], use_ntlm_v2 = True) + conn.connect(backup_creds["ip"]) + path = "/" + files = conn.listPath(backup_creds["share"], path) + for i in backup_creds["path"].split("/"): + exists = False + path += i + "/" + for f in files: + if f.filename == i: + if f.isDirectory: + exists = True + break + if not exists: + try: + conn.createDirectory(backup_creds["share"],path) + except Exception as e: + print(e) + return 1 + files = conn.listPath(backup_creds["share"], path) + + folder = conn.getAttributes(backup_creds["share"], backup_creds["path"]) + if folder.isReadOnly: + print("BACKUP PATH IS READONLY") + return 1 + + local_path = os.path.join(RECORD_PATH, directory) + remote_path = os.path.join(backup_creds["path"], directory) + files = conn.listPath(backup_creds["share"], backup_creds["path"]) + for f in files: + if f.filename == directory: + print("ALREADY BACKED UP") + return + conn.createDirectory(backup_creds["share"], remote_path) + print("STARTING BACKUP") + for i in os.listdir(local_path): + with open(os.path.join(local_path, i), "rb") as f: + print(i) + conn.storeFile(backup_creds["share"], + os.path.join(remote_path, i), + f) + conn.close() + print("DONE BACKING UP") + +while True: + now = datetime.datetime.today() + while now < next_day: + time.sleep(7200) + now = datetime.datetime.today() + print("NEW DAY") + print("GENERATING MEETING LIST") + meetings = get_meetings.get_meetings(creds["TC"], creds["passwd"]) + print("DONE\n") + if AUTO_LOGIN: + for m in meetings: + print("{}:{} {}".format(m["time"],m["class"],m["http_url"])) + + day = datetime.datetime.today().strftime("%d_%m_%Y") + next_day = datetime.datetime.strptime("{} 00:00:00".format(day), '%d_%m_%Y %H:%M:%S') + datetime.timedelta(days = 1) + if not os.path.exists(os.path.join(RECORD_PATH, day)): + os.mkdir(os.path.join(RECORD_PATH, day)) + video_recording = None + camera_mirroring = None + k = None + for k,i in enumerate(meetings): + now = datetime.datetime.today() + meeting_time = datetime.datetime.strptime("{} {}:00".format(day, i["time"]), '%d_%m_%Y %H:%M:%S') + end_time = datetime.datetime.strptime("{} {}:00".format(day, i["time"]), '%d_%m_%Y %H:%M:%S')+ datetime.timedelta(minutes = 30) + if meeting_time < now: + continue + if camera_mirroring: + while now < end_time: + time.sleep(30) + now = datetime.datetime.today() + print("CLASS FINISHED, TERMINATING PREVIOUS RECORDINGS\n") + if video_recording: + video_recording.terminate() + video_recording = None + camera_mirroring.terminate() + print(i["time"]) + print(i["class"]) + while now < meeting_time: + time.sleep(30) + now = datetime.datetime.today() + print("STARTING") + kill_proc = subprocess.Popen(["killall","-9","zoom"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + kill_proc.wait() # Kill all zoom instances before entering a new meeting + subprocess.Popen(["xdg-open", i["meeting_url"]], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + cmd = RECORD_TEMPLATE + [os.path.join(RECORD_PATH, day, "{}.{}.mkv".format(k, i["class"]))] + if os.path.exists(os.path.join(RECORD_PATH, day, "{}.{}.mkv".format(k, i["class"]))): + os.remove(os.path.join(RECORD_PATH, day, "{}.{}.mkv".format(k, i["class"]))) + blacklisted = False + for j in config["blacklisted"]: + if j in i["class"]: + blacklisted = True + if not blacklisted: + video_recording = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + camera_mirroring = subprocess.Popen(CAMERA_TEMPLATE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + if k: + end_time = datetime.datetime.strptime("{} {}:00".format(day, meetings[k]["time"]), '%d_%m_%Y %H:%M:%S')+ datetime.timedelta(minutes = 30) + while now < end_time: + time.sleep(30) + now = datetime.datetime.today() + print("CLASS FINISHED, TERMINATING PREVIOUS RECORDINGS\n") + if video_recording: + video_recording.terminate() + if camera_mirroring: + camera_mirroring.terminate() + print("\nALL CLASSES RECORDED\n") + todays_recordings_path = os.path.join(RECORD_PATH, day) + recordings = os.listdir(todays_recordings_path) + for r in recordings: + if r[-3:] != "mkv": + continue + COMPRESSION_TEMPLATE[2] = os.path.join(todays_recordings_path, r) + COMPRESSION_TEMPLATE[-1] = os.path.join(todays_recordings_path, r[:-3] + ".mp4") + print("COMPRESSING " + r) + compression_process = subprocess.Popen(COMPRESSION_TEMPLATE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + exit_code = compression_process.wait() + print("FFMPEG EXITED WITH STATUS CODE {}".format(exit_code)) + if exit_code == 0: + os.remove(COMPRESSION_TEMPLATE[2]) + + backup(day) + + diff --git a/.gradle/6.8/fileChanges/last-build.bin b/.gradle/6.8/fileChanges/last-build.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/6.8/fileChanges/last-build.bin differ diff --git a/.gradle/6.8/fileHashes/fileHashes.lock b/.gradle/6.8/fileHashes/fileHashes.lock new file mode 100644 index 0000000..337dd10 Binary files /dev/null and b/.gradle/6.8/fileHashes/fileHashes.lock differ diff --git a/.gradle/6.8/gc.properties b/.gradle/6.8/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/checksums/checksums.lock b/.gradle/checksums/checksums.lock new file mode 100644 index 0000000..84283cd Binary files /dev/null and b/.gradle/checksums/checksums.lock differ diff --git a/.gradle/configuration-cache/gc.properties b/.gradle/configuration-cache/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/get_meetings.py b/get_meetings.py index 695d191..645db7b 100644 --- a/get_meetings.py +++ b/get_meetings.py @@ -14,85 +14,90 @@ now = datetime.datetime.now() proxies = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"} headers = { -"Host":"portal.tedankara.k12.tr", -"User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0", -"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", -"Accept-Language":"en-US,en;q=0.5", -"Accept-Encoding":"gzip, deflate", -"Content-Type":"application/x-www-form-urlencoded", -"Origin":"https://portal.tedankara.k12.tr", -"Connection":"close", -"Referer":"https://portal.tedankara.k12.tr/login", -"DNT":"1" + "Host":"portal.tedankara.k12.tr", + "User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0", + "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + "Accept-Language":"en-US,en;q=0.5", + "Accept-Encoding":"gzip, deflate", + "Content-Type":"application/x-www-form-urlencoded", + "Origin":"https://portal.tedankara.k12.tr", + "Connection":"close", + "Referer":"https://portal.tedankara.k12.tr/login", + "DNT":"1" } class JDParser(HTMLParser): - def handle_starttag(self, tag, attrs): - self.attributes = {} - for attr in attrs: - self.attributes[attr[0]] = attr[1] + def handle_starttag(self, tag, attrs): + self.attributes = {} + for attr in attrs: + self.attributes[attr[0]] = attr[1] def get_meetings(uname, passwd): - url = "https://portal.tedankara.k12.tr/login" - r = requests.get(url,verify=False) + url = "https://portal.tedankara.k12.tr/login" + r = requests.get(url,verify=False) - cookies = r.cookies - content = r.content + cookies = r.cookies + content = r.content - lines = content.splitlines() - line = list(filter(lambda x: b'_token' in x, lines))[0].decode("utf-8") + lines = content.splitlines() + line = list(filter(lambda x: b'_token' in x, lines))[0].decode("utf-8") - parser = JDParser() - parser.feed(line) + parser = JDParser() + parser.feed(line) - parser.feed(line) - parser.close() - _token = parser.attributes["content"] + parser.feed(line) + parser.close() + _token = parser.attributes["content"] - data = "_token={}&kimlikno={}&sifre={}".format(_token,uname,passwd) - r = requests.post(url,data=data,cookies=cookies,headers=headers,verify=False) - cookies = r.cookies - r = requests.get("https://portal.tedankara.k12.tr/veli/zoom",cookies=cookies,verify=False, headers=headers) - content = r.json() - data = {"current_day": content["current_day"], - "current_class": content["current_class"], - "current_student": content["current_student"]} + data = "_token={}&kimlikno={}&sifre={}".format(_token,uname,passwd) + r = requests.post(url,data=data,cookies=cookies,headers=headers,verify=False) + cookies = r.cookies + r = requests.get("https://portal.tedankara.k12.tr/veli/zoom",cookies=cookies,verify=False, headers=headers) + content = r.json() + data = {"current_day": content["current_day"], + "current_class": content["current_class"], + "current_student": content["current_student"]} - headers2 = {"Host":"portal.tedankara.k12.tr", - "User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0", - "Accept":"application/json, text/plain, */*", - "Accept-Language":"en-US,en;q=0.5", - "Accept-Encoding":"gzip, deflate", - "X-Requested-With":"XMLHttpRequest", - "Content-Type":"application/json;charset=utf-8", - "Origin":"https://portal.tedankara.k12.tr", - "Connection":"close", - "Referer":"https://portal.tedankara.k12.tr/", - "DNT":"1"} - headers2["X-XSRF-TOKEN"] = r.cookies["XSRF-TOKEN"] - headers2["X-CSRF-TOKEN"] = _token - - r = requests.post("https://portal.tedankara.k12.tr/veli/zoom",cookies=r.cookies,verify=False, json=data, headers=headers2) - classes = r.json() - options = webdriver.ChromeOptions() - options.add_argument('--headless') - try: - client = webdriver.Chrome(options=options) - except: - pass - meetings = [] - for i in classes["meetings"]: - data = "_token={}&student={}&id={}".format(_token, content["students"][0],i["meeting_id"]) - r = requests.post("https://portal.tedankara.k12.tr/veli/yoklama",allow_redirects=False, cookies=cookies,verify=False, data=data, headers=headers) - if "Location" not in r.headers: - continue - invitation = r.headers["Location"] - client.get(invitation) - meeting_url = client.find_element_by_css_selector("a[launch='']").get_attribute("href") - meetings.append({"meeting_url": meeting_url, - "class": i["topic"], - "time":i["meeting_time"]}) - return meetings + headers2 = {"Host":"portal.tedankara.k12.tr", + "User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0", + "Accept":"application/json, text/plain, */*", + "Accept-Language":"en-US,en;q=0.5", + "Accept-Encoding":"gzip, deflate", + "X-Requested-With":"XMLHttpRequest", + "Content-Type":"application/json;charset=utf-8", + "Origin":"https://portal.tedankara.k12.tr", + "Connection":"close", + "Referer":"https://portal.tedankara.k12.tr/", + "DNT":"1"} + headers2["X-XSRF-TOKEN"] = r.cookies["XSRF-TOKEN"] + headers2["X-CSRF-TOKEN"] = _token + + r = requests.post("https://portal.tedankara.k12.tr/veli/zoom",cookies=r.cookies,verify=False, json=data, headers=headers2) + classes = r.json() + meetings = [] + for i in classes["meetings"]: + data = "_token={}&student={}&id={}".format(_token, content["students"][0],i["meeting_id"]) + r = requests.post("https://portal.tedankara.k12.tr/veli/yoklama",allow_redirects=False, cookies=cookies,verify=False, data=data, headers=headers) + data = r.content.decode() + if "Location" not in data: + continue + for j in data.split("\n"): + items = j.split(" ") + if items[0] == "Location:": + invitation = items[-1] + try: + m = re.compile("https:\/\/zoom\.us\/j\/([0-9]*)\?.*pwd=([^#]*)") + g = m.search(invitation) + meeting_url = f"zoommtg://zoom.us/join?confno={g.group(1)}&zc=0&browser=chrome&pwd={g.group(2)}" + http_url = f"https://zoom.us/j/{g.group(1)}?pwd={g.group(2)}" + meetings.append({"meeting_url": meeting_url, + "class": i["topic"], + "time":i["meeting_time"], + "http_url":http_url}) + except Exception as e: + print(e) + + return meetings diff --git a/main.py b/main.py index 0361791..cf3de54 100644 --- a/main.py +++ b/main.py @@ -5,6 +5,7 @@ import os import json import time import sys +import discord from smb.SMBConnection import SMBConnection RECORD_PATH = "recordings" @@ -13,22 +14,25 @@ VIRTUAL_CAMERA_PATH = "/dev/video2" PULSEAUDIO_INDEX = 5 X_OFFSET = sys.argv[1] PULSEAUDIO_INDEX = sys.argv[2] +AUTO_LOGIN = sys.argv[3] == 1 RECORD_TEMPLATE = ["ffmpeg", "-nostdin", "-video_size", "1920x1080", "-f", "x11grab", "-i", ":0.0+{},0".format(X_OFFSET), "-f", "pulse", "-ac", "2", "-i", str(PULSEAUDIO_INDEX), "-vcodec", "libx264", "-crf", "0", "-preset", "ultrafast", "-acodec", "pcm_s16le"] CAMERA_TEMPLATE = ["ffmpeg", "-re", "-i", LISTENING_VIDEO_PATH, "-map", "0:v", "-f", "v4l2", VIRTUAL_CAMERA_PATH] COMPRESSION_TEMPLATE = ["ffmpeg", "-i", None, "-vcodec", "libx265", "-crf", "28", None] + if not os.path.exists(VIRTUAL_CAMERA_PATH): - os.system("sudo modprobe -r v4l2loopback") - os.system("sudo modprobe v4l2loopback") + os.system("sudo modprobe -r v4l2loopback") + os.system("sudo modprobe v4l2loopback") if not os.path.exists(RECORD_PATH): - os.mkdir(RECORD_PATH) + os.mkdir(RECORD_PATH) with open("config.json", "r") as f: - config = json.loads(f.read()) - creds = config["creds"] - backup_creds = config["backup"] + config = json.loads(f.read()) + creds = config["creds"] + backup_creds = config["backup"] + DISCORD = config["discord"] next_day = datetime.datetime.today() @@ -36,101 +40,140 @@ def backup(directory): conn = SMBConnection(backup_creds["user"], backup_creds["password"], backup_creds["server_name"], backup_creds["server_name"], use_ntlm_v2 = True) conn.connect(backup_creds["ip"]) - files = conn.listPath(backup_creds["share"], "/") - exists = False - - for f in files: - if f.filename == backup_creds["path"]: - if f.isDirectory: - exists = True - break - else: - conn.close() + path = "/" + files = conn.listPath(backup_creds["share"], path) + for i in backup_creds["path"].split("/"): + exists = False + path += i + "/" + for f in files: + if f.filename == i: + if f.isDirectory: + exists = True + break + if not exists: + try: + conn.createDirectory(backup_creds["share"],path) + except Exception as e: + print(e) return 1 + files = conn.listPath(backup_creds["share"], path) - if not exists: - try: - conn.createDirectory(backup_creds["share"],backup_creds["path"]) - except Exception as e: - print(e) - return 1 folder = conn.getAttributes(backup_creds["share"], backup_creds["path"]) if folder.isReadOnly: print("BACKUP PATH IS READONLY") return 1 - local_path = os.path.join(RECORD_PATH, directory) + local_path = os.path.join(RECORD_PATH, directory) remote_path = os.path.join(backup_creds["path"], directory) - - conn.createDirectory(backup_creds["share"], remote_path) + files = conn.listPath(backup_creds["share"], backup_creds["path"]) + for f in files: + if f.filename == directory: + print("ALREADY BACKED UP") + return + conn.createDirectory(backup_creds["share"], remote_path) + print("STARTING BACKUP") for i in os.listdir(local_path): with open(os.path.join(local_path, i), "rb") as f: - conn.storeFile(backup_creds["share"], + print(i) + conn.storeFile(backup_creds["share"], os.path.join(remote_path, i), f) conn.close() + print("DONE BACKING UP") + +if(not AUTO_LOGIN): + client = discord.Client() + + @client.event + async def on_ready(): + print(f'{client.user} has connected to Discord!') + meetings = get_meetings.get_meetings(creds["TC"], creds["passwd"]) + msg = "" + for m in meetings: + msg += "{}: **{}** <{}>\n".format(m["time"],m["class"],m["http_url"]) + await client.get_guild(int(DISCORD["guild"])).get_channel(int(DISCORD["channel"])).send(msg) + await client.close() + + client.run(DISCORD["token"]) while True: - now = datetime.datetime.today() - while now < next_day: - time.sleep(7200) - now = datetime.datetime.today() - print("NEW DAY") - print("GENERATING MEETING LIST") - meetings = get_meetings.get_meetings(creds["TC"], creds["passwd"]) - print("DONE\n") - day = datetime.datetime.today().strftime("%d_%m_%Y") - next_day = datetime.datetime.strptime("{} 00:00:00".format(day), '%d_%m_%Y %H:%M:%S') + datetime.timedelta(days = 1) - if not os.path.exists(os.path.join(RECORD_PATH, day)): - os.mkdir(os.path.join(RECORD_PATH, day)) - video_recording = None - camera_mirroring = None - k = None - for k,i in enumerate(meetings): - now = datetime.datetime.today() - meeting_time = datetime.datetime.strptime("{} {}:00".format(day, i["time"]), '%d_%m_%Y %H:%M:%S') - if video_recording: - end_time = datetime.datetime.strptime("{} {}:00".format(day, meetings[k-1]["time"]), '%d_%m_%Y %H:%M:%S')+ datetime.timedelta(minutes = 30) - while now < end_time: - time.sleep(30) - now = datetime.datetime.today() - print("CLASS FINISHED, TERMINATING PREVIOUS RECORDINGS\n") - video_recording.terminate() - camera_mirroring.terminate() - print(i["time"]) - print(i["class"]) - while now < meeting_time: - time.sleep(30) - now = datetime.datetime.today() - print("STARTING") - subprocess.Popen(["xdg-open", i["meeting_url"]], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - cmd = RECORD_TEMPLATE + [os.path.join(RECORD_PATH, day, "{}.{}.mkv".format(k, i["class"]))] - if os.path.exists(os.path.join(RECORD_PATH, day, "{}.{}.mkv".format(k, i["class"]))): - os.remove(os.path.join(RECORD_PATH, day, "{}.{}.mkv".format(k, i["class"]))) -# print(" ".join(cmd)) - video_recording = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - camera_mirroring = subprocess.Popen(CAMERA_TEMPLATE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - if k: - end_time = datetime.datetime.strptime("{} {}:00".format(day, meetings[k]["time"]), '%d_%m_%Y %H:%M:%S')+ datetime.timedelta(minutes = 30) - while now < end_time: - time.sleep(30) - now = datetime.datetime.today() - print("CLASS FINISHED, TERMINATING PREVIOUS RECORDINGS\n") - video_recording.terminate() - camera_mirroring.terminate() - print("\nALL CLASSES RECORDED\n") - todays_recordings_path = os.path.join(RECORD_PATH, day) - recordings = os.listdir(todays_recordings_path) - for r in recordings: - COMPRESSION_TEMPLATE[2] = os.path.join(todays_recordings_path, r) - COMPRESSION_TEMPLATE[-1] = os.path.join(todays_recordings_path, r[:-3] + ".mp4") - print("COMPRESSING " + r) - compression_process = subprocess.Popen(COMPRESSION_TEMPLATE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - exit_code = compression_process.wait() - print("FFMPEG EXITED WITH STATUS CODE {}".format(exit_code)) - if exit_code == 0: - os.remove(COMPRESSION_TEMPLATE[2]) - - - - + if not AUTO_LOGIN: + break + now = datetime.datetime.today() + while now < next_day: + time.sleep(7200) + now = datetime.datetime.today() + print("NEW DAY") + print("GENERATING MEETING LIST") + meetings = get_meetings.get_meetings(creds["TC"], creds["passwd"]) + print("DONE\n") + + day = datetime.datetime.today().strftime("%d_%m_%Y") + next_day = datetime.datetime.strptime("{} 00:00:00".format(day), '%d_%m_%Y %H:%M:%S') + datetime.timedelta(days = 1) + if not os.path.exists(os.path.join(RECORD_PATH, day)): + os.mkdir(os.path.join(RECORD_PATH, day)) + video_recording = None + camera_mirroring = None + k = None + for k,i in enumerate(meetings): + now = datetime.datetime.today() + meeting_time = datetime.datetime.strptime("{} {}:00".format(day, i["time"]), '%d_%m_%Y %H:%M:%S') + end_time = datetime.datetime.strptime("{} {}:00".format(day, i["time"]), '%d_%m_%Y %H:%M:%S')+ datetime.timedelta(minutes = 30) + if meeting_time < now: + continue + if camera_mirroring: + while now < end_time: + time.sleep(30) + now = datetime.datetime.today() + print("CLASS FINISHED, TERMINATING PREVIOUS RECORDINGS\n") + if video_recording: + video_recording.terminate() + video_recording = None + camera_mirroring.terminate() + print(i["time"]) + print(i["class"]) + while now < meeting_time: + time.sleep(30) + now = datetime.datetime.today() + print("STARTING") + kill_proc = subprocess.Popen(["killall","-9","zoom"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + kill_proc.wait() # Kill all zoom instances before entering a new meeting + subprocess.Popen(["xdg-open", i["meeting_url"]], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + cmd = RECORD_TEMPLATE + [os.path.join(RECORD_PATH, day, "{}.{}.mkv".format(k, i["class"]))] + if os.path.exists(os.path.join(RECORD_PATH, day, "{}.{}.mkv".format(k, i["class"]))): + os.remove(os.path.join(RECORD_PATH, day, "{}.{}.mkv".format(k, i["class"]))) + blacklisted = False + for j in config["blacklisted"]: + if j in i["class"]: + blacklisted = True + if not blacklisted: + video_recording = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + camera_mirroring = subprocess.Popen(CAMERA_TEMPLATE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + if k: + end_time = datetime.datetime.strptime("{} {}:00".format(day, meetings[k]["time"]), '%d_%m_%Y %H:%M:%S')+ datetime.timedelta(minutes = 30) + while now < end_time: + time.sleep(30) + now = datetime.datetime.today() + print("CLASS FINISHED, TERMINATING PREVIOUS RECORDINGS\n") + if video_recording: + video_recording.terminate() + if camera_mirroring: + camera_mirroring.terminate() + print("\nALL CLASSES RECORDED\n") + todays_recordings_path = os.path.join(RECORD_PATH, day) + recordings = os.listdir(todays_recordings_path) + for r in recordings: + if r[-3:] != "mkv": + continue + COMPRESSION_TEMPLATE[2] = os.path.join(todays_recordings_path, r) + COMPRESSION_TEMPLATE[-1] = os.path.join(todays_recordings_path, r[:-3] + ".mp4") + print("COMPRESSING " + r) + compression_process = subprocess.Popen(COMPRESSION_TEMPLATE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + exit_code = compression_process.wait() + print("FFMPEG EXITED WITH STATUS CODE {}".format(exit_code)) + if exit_code == 0: + os.remove(COMPRESSION_TEMPLATE[2]) + + backup(day) + +