[mirror of https://git.0x0.st/mia/0x0] No-bullshit file hosting and URL shortening service https://0x0.st
at master 91 lines 3.1 kB view raw
1from textual.widgets import DataTable, Static 2from textual.reactive import Reactive 3from textual.message import Message 4from textual import events, log 5from jinja2.filters import do_filesizeformat 6 7from fhost import File 8from modui import mime 9 10 11class FileTable(DataTable): 12 query = Reactive(None) 13 order_col = Reactive(0) 14 order_desc = Reactive(True) 15 limit = 10000 16 colmap = [File.id, File.removed, File.nsfw_score, None, File.ext, 17 File.size, File.mime] 18 19 def __init__(self, **kwargs): 20 super().__init__(**kwargs) 21 self.add_columns("#", "☣️", "🔞", "📂", "name", "size", "mime") 22 self.base_query = File.query.filter(File.size != None) 23 self.query = self.base_query 24 25 class Selected(Message): 26 def __init__(self, f: File) -> None: 27 self.file = f 28 super().__init__() 29 30 def watch_order_col(self, old, value) -> None: 31 self.watch_query(None, None) 32 33 def watch_order_desc(self, old, value) -> None: 34 self.watch_query(None, None) 35 36 def watch_query(self, old, value) -> None: 37 def fmt_file(f: File) -> tuple: 38 mimemoji = mime.mimemoji.get(f.mime.split('/')[0], 39 mime.mimemoji.get(f.mime)) or ' ' 40 return ( 41 str(f.id), 42 "🔴" if f.removed else " ", 43 "🚩" if f.is_nsfw else " ", 44 "👻" if not f.getpath().is_file() else " ", 45 f.getname(), 46 do_filesizeformat(f.size, True), 47 f"{mimemoji} {f.mime}", 48 ) 49 50 if (self.query): 51 order = FileTable.colmap[self.order_col] 52 q = self.query 53 if order: 54 q = q.order_by(order.desc() if self.order_desc 55 else order, File.id) 56 qres = list(map(fmt_file, q.limit(self.limit))) 57 58 ri = 0 59 row = self.cursor_coordinate.row 60 if row < self.row_count and row >= 0: 61 ri = int(self.get_row_at(row)[0]) 62 63 self.clear() 64 self.add_rows(qres) 65 66 for i, v in enumerate(qres): 67 if int(v[0]) == ri: 68 self.move_cursor(row=i) 69 break 70 71 self.on_selected() 72 73 def on_selected(self) -> Selected: 74 row = self.cursor_coordinate.row 75 if row < self.row_count and row >= 0: 76 f = File.query.get(int(self.get_row_at(row)[0])) 77 self.post_message(self.Selected(f)) 78 79 def watch_cursor_coordinate(self, old, value) -> None: 80 super().watch_cursor_coordinate(old, value) 81 if old != value: 82 self.on_selected() 83 84 def on_click(self, event: events.Click) -> None: 85 meta = self.get_style_at(event.x, event.y).meta 86 if meta: 87 if meta["row"] == -1: 88 qi = FileTable.colmap[meta["column"]] 89 if meta["column"] == self.order_col: 90 self.order_desc = not self.order_desc 91 self.order_col = meta["column"]