annotate video_file_store.py @ 26:20fa84102643

add loginbar
author drewp@bigasterisk.com
date Thu, 29 Jun 2023 13:57:47 -0700
parents cf6842952e13
children ed16fdbb3996
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
15
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
1 import asyncio
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
2 import hashlib
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
3 import re
20
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
4 import os
15
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
5 from dataclasses import dataclass
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
6 from pathlib import Path
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
7 from typing import Iterable, Iterator, NewType
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
8
20
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
9 IGNORE = {'_thumb'}
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
10
15
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
11
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
12 @dataclass
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
13 class VideoFile:
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
14 diskPath: Path
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
15 webRelPath: str
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
16 label: str
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
17 # perms, playlists, req by/when
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
18
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
19
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
20 def vf(p: Path, label: str):
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
21 return VideoFile(p, './files/' + str(p.relative_to('/data')), label)
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
22
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
23
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
24 def thumbWebPath(rel: str) -> str:
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
25 return './files/' + rel
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
26
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
27
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
28 @dataclass
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
29 class VideoFileStore:
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
30 top: Path
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
31
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
32 def findInDir(self, subdir: str) -> Iterable[VideoFile]:
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
33 if subdir[0] != '/': raise ValueError
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
34 here = self.top / subdir[1:]
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
35 manifests = list(here.glob('*.mpd'))
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
36 if manifests:
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
37 p = manifests[0]
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
38 label = p.parent.name
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
39 yield vf(p, label)
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
40 return
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
41 for p in sorted(list(here.glob('*.mp4')) + list(here.glob('*.webm'))):
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
42 label = re.sub(r' \[[^\]]+\]\.\w+', '', p.name)
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
43 yield vf(p, label)
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
44
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
45 def findSubdirs(self, subdir: str) -> Iterable:
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
46 if subdir[0] != '/': raise ValueError
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
47 here = self.top / subdir[1:]
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
48 for p in here.iterdir():
20
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
49 if p.is_dir() and p.name not in IGNORE:
15
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
50 yield {
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
51 'label': p.name,
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
52 'path': '/' + str(p.relative_to(self.top))
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
53 }
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
54
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
55 def thumbPath(self, vf: VideoFile) -> str:
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
56 sha256 = hashlib.sha256()
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
57 with open(vf.diskPath, 'rb') as f:
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
58 firstMb = f.read(1 << 20)
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
59 sha256.update(firstMb)
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
60 cksum = sha256.hexdigest()
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
61 return f'_thumb/{cksum}.jpg'
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
62
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
63 async def getOrCreateThumb(self, vf: VideoFile) -> str:
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
64 p = self.top / self.thumbPath(vf)
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
65 if not p.exists():
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
66 sp = asyncio.create_subprocess_exec('ffmpegthumbnailer',
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
67 '-s', '250', '-i',
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
68 str(vf.diskPath), '-o', str(p))
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
69 await sp
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
70 return thumbWebPath(str(p.relative_to(self.top)))
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
71
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
72 async def save(self, name: str, chunks: Iterator[bytes]):
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
73 p = self.top / name
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
74 if p.exists():
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
75 raise ValueError(f'{p} exists')
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
76 data = b''
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
77 for c in chunks:
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
78 data += c
53d99454f394 support dropping url or file
drewp@bigasterisk.com
parents:
diff changeset
79 p.write_bytes(data)
20
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
80
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
81 def folderTree(self):
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
82 out = {'name': 'TOP'}
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
83
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
84 def fill(node: dict, pathToHere: Path):
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
85 for subName in sorted(os.listdir(pathToHere)):
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
86 if subName in IGNORE:
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
87 continue
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
88 subDir = pathToHere / subName
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
89 if subDir.is_dir():
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
90 subNode = {'name': subName}
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
91 node.setdefault('children', []).append(subNode)
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
92 fill(subNode, subDir)
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
93
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
94 fill(out, self.top)
cf6842952e13 serve api/folderTree
drewp@bigasterisk.com
parents: 15
diff changeset
95 return out