Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

3 changed files with 53 additions and 56 deletions

16
mod.css
View File

@ -1,6 +1,5 @@
#ftable {
width: 1fr;
height: 100%;
}
#infopane {
@ -11,7 +10,7 @@
#finfo {
background: $boost;
height: 14;
height: 12;
width: 1fr;
box-sizing: content-box;
}
@ -28,9 +27,20 @@
width: 1fr;
}
#filter_container {
height: auto;
display: none;
}
#filter_label {
content-align: right middle;
height: 1fr;
width: 20%;
margin: 0 1 0 2;
}
#filter_input {
width: 1fr;
display: none;
}
Notification {

49
mod.py
View File

@ -5,7 +5,7 @@ from sys import stdout
import time
from textual.app import App, ComposeResult
from textual.widgets import DataTable, Header, Footer, RichLog, Static, Input
from textual.widgets import DataTable, Header, Footer, TextLog, Static, Input
from textual.containers import Horizontal, Vertical
from textual.screen import Screen
from textual import log
@ -20,13 +20,13 @@ fhost_app.app_context().push()
class NullptrMod(Screen):
BINDINGS = [
("q", "quit_app", "Quit"),
("f1", "filter(1, 'Name')", "Lookup name"),
("f2", "filter(2, 'IP address')", "Filter IP"),
("f3", "filter(3, 'MIME Type')", "Filter MIME"),
("f4", "filter(4, 'Extension')", "Filter Ext."),
("f1", "filter(1, 'Lookup name:')", "Lookup name"),
("f2", "filter(2, 'Filter IP address:')", "Filter IP"),
("f3", "filter(3, 'Filter MIME Type:')", "Filter MIME"),
("f4", "filter(4, 'Filter extension:')", "Filter Ext."),
("f5", "refresh", "Refresh"),
("f6", "filter_clear", "Clear filter"),
("f7", "filter(5, 'User agent')", "Filter UA"),
("f7", "filter(5, 'Filter user agent:')", "Filter UA"),
("r", "remove_file(False)", "Remove file"),
("ctrl+r", "remove_file(True)", "Ban file"),
("p", "ban_ip(False)", "Ban IP"),
@ -42,28 +42,29 @@ class NullptrMod(Screen):
ftable.watch_query(None, None)
def action_filter_clear(self):
self.finput.display = False
self.query_one("#filter_container").display = False
ftable = self.query_one("#ftable")
ftable.focus()
ftable.query = ftable.base_query
def action_filter(self, fcol: int, label: str):
self.finput.placeholder = label
self.finput.display = True
self.finput.focus()
self.query_one("#filter_label").update(label)
finput = self.query_one("#filter_input")
self.filter_col = fcol
self.query_one("#filter_container").display = True
finput.focus()
self._refresh_layout()
if self.current_file:
match fcol:
case 1: self.finput.value = ""
case 2: self.finput.value = self.current_file.addr
case 3: self.finput.value = self.current_file.mime
case 4: self.finput.value = self.current_file.ext
case 5: self.finput.value = self.current_file.ua or ""
case 1: finput.value = ""
case 2: finput.value = self.current_file.addr
case 3: finput.value = self.current_file.mime
case 4: finput.value = self.current_file.ext
case 5: finput.value = self.current_file.ua or ""
def on_input_submitted(self, message: Input.Submitted) -> None:
self.finput.display = False
self.query_one("#filter_container").display = False
ftable = self.query_one("#ftable")
ftable.focus()
@ -121,13 +122,13 @@ class NullptrMod(Screen):
def compose(self) -> ComposeResult:
yield Header()
yield Horizontal(
FileTable(id="ftable", zebra_stripes=True, cursor_type="row"),
FileTable(id="ftable", zebra_stripes=True),
Vertical(
DataTable(id="finfo", show_header=False, cursor_type="none"),
DataTable(id="finfo", show_header=False),
MpvWidget(id="mpv"),
RichLog(id="ftextlog", auto_scroll=False),
TextLog(id="ftextlog"),
id="infopane"))
yield Input(id="filter_input")
yield Horizontal(Static("Filter:", id="filter_label"), Input(id="filter_input"), id="filter_container")
yield Footer()
def on_mount(self) -> None:
@ -142,8 +143,6 @@ class NullptrMod(Screen):
self.mpvw = self.query_one("#mpv")
self.ftlog = self.query_one("#ftextlog")
self.finput = self.query_one("#filter_input")
self.mimehandler = mime.MIMEHandler()
self.mimehandler.register(mime.MIMECategory.Archive, self.handle_libarchive)
self.mimehandler.register(mime.MIMECategory.Text, self.handle_text)
@ -262,11 +261,13 @@ class NullptrMod(Screen):
])
self.mpvw.stop_mpv(True)
self.ftlog.clear()
self.ftlog.remove()
self.query_one("#infopane").mount(TextLog(id="ftextlog"))
self.ftlog = self.query_one("#ftextlog")
if f.getpath().is_file():
self.mimehandler.handle(f.mime, f.ext)
self.ftlog.scroll_to(x=0, y=0, animate=False)
self.ftlog.scroll_home(animate=False)
class NullptrModApp(App):
CSS_PATH = "mod.css"

View File

@ -1,6 +1,6 @@
from textual.widgets import DataTable, Static
from textual.reactive import Reactive
from textual.message import Message
from textual.message import Message, MessageTarget
from textual import events, log
from jinja2.filters import do_filesizeformat
@ -21,9 +21,9 @@ class FileTable(DataTable):
self.query = self.base_query
class Selected(Message):
def __init__(self, f: File) -> None:
def __init__(self, sender: MessageTarget, f: File) -> None:
self.file = f
super().__init__()
super().__init__(sender)
def watch_order_col(self, old, value) -> None:
self.watch_query(None, None)
@ -44,39 +44,25 @@ class FileTable(DataTable):
)
if (self.query):
self.clear()
order = FileTable.colmap[self.order_col]
q = self.query
if order: q = q.order_by(order.desc() if self.order_desc else order, File.id)
qres = list(map(fmt_file, q.limit(self.limit)))
self.add_rows(map(fmt_file, q.limit(self.limit)))
ri = 0
row = self.cursor_coordinate.row
if row < self.row_count and row >= 0:
ri = int(self.get_row_at(row)[0])
def _scroll_cursor_in_to_view(self, animate: bool = False) -> None:
region = self._get_cell_region(self.cursor_row, 0)
spacing = self._get_cell_border()
self.scroll_to_region(region, animate=animate, spacing=spacing)
self.clear()
self.add_rows(qres)
for i, v in enumerate(qres):
if int(v[0]) == ri:
self.move_cursor(row=i)
break
self.on_selected()
def on_selected(self) -> Selected:
row = self.cursor_coordinate.row
if row < self.row_count and row >= 0:
f = File.query.get(int(self.get_row_at(row)[0]))
self.post_message(self.Selected(f))
def watch_cursor_coordinate(self, old, value) -> None:
super().watch_cursor_coordinate(old, value)
if old != value:
self.on_selected()
async def watch_cursor_cell(self, old, value) -> None:
super().watch_cursor_cell(old, value)
if value[0] < len(self.data) and value[0] >= 0:
f = File.query.get(int(self.data[value[0]][0]))
await self.emit(self.Selected(self, f))
def on_click(self, event: events.Click) -> None:
super().on_click(event)
meta = self.get_style_at(event.x, event.y).meta
if meta:
if meta["row"] == -1: