[mirror of https://git.0x0.st/mia/0x0] No-bullshit file hosting and URL shortening service https://0x0.st
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"]