--- allow_origins: - '*' allow_xss: false alt_top_banner: '' auto_reload: false auto_reload_interval: 5.0 code: "__doc__= \"#Python Code here runs every page load\"\r\n\r\nif 'starttime' in\ \ kwargs:\r\n starttime = datetime.datetime.fromisoformat(kwargs['starttime'])\r\ \nelse:\r\n starttime= datetime.datetime.fromisoformat('1900-01-01'+\"+00:00\"\ ).replace(tzinfo=datetime.timezone.utc)\r\n\r\ndirs = []\r\nresult = []\r\n\r\n\ l=''\r\n\r\ndef parse(s):\r\n if not \"Z\" in s and not '+' in s:\r\n x= datetime.datetime.fromisoformat(s+\"\ +00:00\")\r\n else:\r\n x= datetime.datetime.fromisoformat(s.replace(\"Z\",\"\ +00:00\"))\r\n\r\n if x.tzinfo is None:\r\n x=x.replace(tzinfo=datetime.timezone.utc)\r\ \n return x\r\n\r\nfor i in all_devices:\r\n if all_devices[i].device_type_name\ \ in ['NVRChannel']:\r\n canDo=True\r\n for j in all_devices[i].config.get(\"\ kaithem.read_perms\",'').strip().split(\",\"):\r\n if not web.has_permission(j.strip()):\r\ \n canDo=False\r\n if canDo:\r\n if not 'filter' in kwargs or not\ \ kwargs['filter'].strip() or kwargs['filter'].strip().lower() in i.lower():\r\n\ \ dirs.append((os.path.join(os.path.expanduser(all_devices[i].config['device.storage_dir']),i,'recordings'),\ \ i))\r\n\r\n\r\nenough = 0\r\n\r\nfor t in dirs:\r\n i=t[0]\r\n if not os.path.isdir(i):\r\ \n continue\r\n for j in os.listdir(i):\r\n j2 = os.path.join(i,j)\r\n \ \ if not os.path.isdir(j2):\r\n continue\r\n \r\n #Parse the day folders\r\ \n try:\r\n jt = parse(j)\r\n except:\r\n print(traceback.format_exc)\r\ \n continue\r\n\r\n # Only look in the correct top level dir.\r\n if\ \ (jt- starttime).total_seconds() > (3600 * 25):\r\n if enough:\r\n \ \ continue\r\n\r\n\r\n # Only look in the correct top level dir.\r\n if jt (3600 * 25):\r\n continue\r\n\r\n\r\ \n for k in os.listdir(j2):\r\n k2 = os.path.join(j2,k)\r\n # Date\ \ range filter\r\n # Always get everything from exact day, limit count from\ \ next day\r\n if (parse(k)>starttime and (parse(k)-starttime).total_seconds()\ \ < ((24*3600)+60)) or((not enough) and parse(k)>starttime):\r\n if not\ \ os.path.isfile(os.path.join(k2, \"playlist.m3u8\")):\r\n continue\r\n\ \ \r\n fn = os.path.join(t[1],'recordings',j,k)\r\n title\ \ = ''\r\n\r\n try:\r\n regex = '^#EXTALB:(.*)$'\r\n with\ \ open(os.path.join(k2, \"playlist.m3u8\")) as f:\r\n fd = f.read()\r\ \n \r\n x = re.search(regex, fd, re.MULTILINE)\r\n if\ \ x:\r\n title = x.group(1)\r\n\r\n except Exception as e:\r\n\ \ print(e)\r\n\r\n \r\n result.append((k,fn, t[1], title))\r\ \n\r\n if len(result)>500:\r\n enough=1\r\noutput = json.dumps(list(sorted(result)))\r\ \n" mimetype: text/html no_header: true no_navheader: true require_method: - GET - POST require_permissions: - view_nvr resource_timestamp: 1713106900940510 resource_type: page setupcode: "#Code Here runs once when page is first rendered. Good place for import\ \ statements.\r\nimport json\r\nimport os\r\nimport datetime\r\nimport traceback\r\ \nimport re\r\nfrom kaithem.api.devices import all_devices\r\nfrom kaithem.api import\ \ web" streaming_response: false template_engine: jinja2 theme_css_url: '' --- {{output}}