commit d9755f43205d01115ee9293e0bbda3f3f6ffc3a8
parent 995f34c06c222129bf0e738d4f0fb4c6b65b2900
Author: lash <dev@holbrook.no>
Date: Tue, 2 Sep 2025 14:47:31 +0100
Set up textview for description
Diffstat:
6 files changed, 101 insertions(+), 17 deletions(-)
diff --git a/ungana/attachment/attachment_manager.py b/ungana/attachment/attachment_manager.py
@@ -41,10 +41,11 @@ class AttachmentManager:
if ctx == "long" and not (mime_type and mime_type.startswith("text/")):
raise ValueError(f"Long attachment must be a text file, got {mime_type}")
+
def digest(self, file_path: str) -> str:
"""Return SHA256 digest of the file content."""
h = hashlib.sha256()
with open(file_path, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
h.update(chunk)
- return h.hexdigest()
-\ No newline at end of file
+ return h.hexdigest()
diff --git a/ungana/config.py b/ungana/config.py
@@ -7,7 +7,8 @@ __datadir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data")
def load():
cfg = confini.Config(__datadir)
cfg.process()
- if not cfg.have('BASE_DATAPATH'):
+ if not cfg.get('BASE_DATAPATH', None):
datapath = save_data_path('ungana')
cfg.add(datapath, 'BASE_DATAPATH')
+
return cfg
diff --git a/ungana/data/config.ini b/ungana/data/config.ini
@@ -1,4 +1,5 @@
[base]
domain = nondominium.org
zone = America/El_Salvador
+uuid = '968ece79-5ce7-4e97-8cbc-67c59419222a'
datapath =
diff --git a/ungana/gui/event.py b/ungana/gui/event.py
@@ -1,11 +1,18 @@
+import logging
+import zoneinfo
+
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gio
+from ungana.i18n import _
+
+logg = logging.getLogger("gui.event")
+
class EventWindow(Gtk.Window):
- def __init__(self, *args, **kwargs):
+ def __init__(self, zone=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.cal = None
@@ -34,7 +41,9 @@ class EventWindow(Gtk.Window):
title = Gtk.Label(label="Description")
self.box_main.append(title)
- entry = Gtk.Entry()
+ entry = Gtk.TextView()
+ entry.set_size_request(0, 100)
+ entry.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
self.box_main.append(entry)
title = Gtk.Label(label="Time zone")
@@ -47,7 +56,7 @@ class EventWindow(Gtk.Window):
i = 0
for v in sorted(zonedata):
zones.append(v)
- if v == self.get_application().cfg.get('BASE_ZONE'):
+ if v == zone:
entry.props.selected = i
logg.debug("timezone default: {}".format(v))
i += 1
@@ -85,6 +94,34 @@ class EventWindow(Gtk.Window):
entry.connect('clicked', self.show_open_dialog)
self.box_main.append(entry)
+ title = Gtk.Label(label="Geo coordinates")
+ self.box_main.append(title)
+ entry = Gtk.Entry(placeholder_text="lat")
+ entry.set_input_purpose(Gtk.InputPurpose.NUMBER)
+ self.entry_geo_lat = entry
+ self.box_main.append(entry)
+ entry = Gtk.Entry(placeholder_text="lon")
+ entry.set_input_purpose(Gtk.InputPurpose.NUMBER)
+ self.entry_geo_lon = entry
+ self.box_main.append(entry)
+
+ title = Gtk.Label(label="Host URL")
+ self.box_main.append(title)
+ entry = Gtk.Entry(placeholder_text="http://")
+ self.entry_url_host = entry
+ self.box_main.append(entry)
+
+ title = Gtk.Label(label="Presenter URL")
+ self.box_main.append(title)
+ entry = Gtk.Entry(placeholder_text="http://")
+ self.entry_url_presenter = entry
+ self.box_main.append(entry)
+
+ title = Gtk.Label(label="Location URL")
+ self.box_main.append(title)
+ entry = Gtk.Entry(placeholder_text="http://")
+ self.box_main.append(entry)
+
self.status = Gtk.Statusbar()
self.box_main.append(self.status)
@@ -101,11 +138,19 @@ class EventWindow(Gtk.Window):
except GLib.Error as e:
logg.error("error open: {}".format(e))
+
def load(self, fp):
self.cal = ICalManager()
self.cal.load_ical_file(fp)
ev = self.cal.get_first_event(self.cal.calendar)
+ status_id = self.status.get_context_id("ical")
+ self.status.push(status_id, "{} {:s}: {}@{}".format(_("Loaded event from ical file"), fp, uid, domain))
+
+ self.update(ev)
+
+
+ def update(self, ev):
v = ev.get('summary')
self.entry_summary.set_text(v)
@@ -114,7 +159,20 @@ class EventWindow(Gtk.Window):
self.entry_uuid.set_text(uid)
self.entry_domain.set_text(domain)
- status_id = self.status.get_context_id("ical")
- self.status.push(status_id, "{} {:s}: {}@{}".format(_("Loaded event from ical file"), fp, uid, domain))
-
-
+ v = ev.get('geo')
+ self.entry_geo_lat.set_text(str(v.latitude))
+ self.entry_geo_lon.set_text(str(v.longitude))
+
+ for v in ev.content_lines():
+ r = None
+ try:
+ r = v.parts()
+ except:
+ continue
+ if r[0] == 'URL':
+ for k in r[1].params():
+ if k == 'ROLE':
+ if r[1][k] == 'PRESENTER':
+ self.entry_url_presenter.set_text(r[2])
+ elif r[1][k] == 'HOST':
+ self.entry_url_host.set_text(r[2])
diff --git a/ungana/gui/main.py b/ungana/gui/main.py
@@ -59,4 +59,3 @@ class UnganaGui(Adw.Application):
logg.debug("config {} => {}".format(k, self.cfg.get(k)))
self.activate()
return 0
-
diff --git a/ungana/gui/win.py b/ungana/gui/win.py
@@ -11,10 +11,11 @@ import icalendar
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
-from gi.repository import Gtk, Adw, Gio, GObject
+from gi.repository import Gtk, Gdk, Adw, Gio, GObject
from ungana.i18n import _
from ungana.ical import ICalManager
+from .event import EventWindow
logg = logging.getLogger("gui.win")
@@ -49,7 +50,19 @@ class WindowEvent(GObject.GObject):
def when(self):
- return "fii"
+ s = None
+ for v in self.ev.decoded('dtstart'):
+ zone = v.tzinfo.tzname(v)
+ logg.debug("zz {} {}".format(zone, type(v)))
+ if s == None:
+ s = '{} (UTC)'.format(v.ctime())
+ elif zone != 'UTC':
+ s = '{} ({})'.format(v.ctime(), v.tzname())
+ return s
+
+
+ def event(self):
+ return self.ev
def event_item_setup(widget, item):
@@ -119,20 +132,32 @@ class MainWindow(Gtk.ApplicationWindow):
factory_date.connect("setup", event_item_setup)
factory_date.connect("bind", event_date_bind)
- rendererTxt = Gtk.CellRendererText()
+ #rendererTxt = Gtk.CellRendererText()
# TODO: is there a row equivalent to set up?
col = Gtk.ColumnViewColumn.new(_("Event"), factory_head)
#col = Gtk.TreeViewColumn(_("Events"), rendererTxt, text=0)
self.view.append_column(col)
+ col = Gtk.ColumnViewColumn.new(_("Date"), factory_date)
+ self.view.append_column(col)
col = Gtk.ColumnViewColumn.new(_("UUID"), factory_uuid)
self.view.append_column(col)
col = Gtk.ColumnViewColumn.new(_("Domain"), factory_domain)
self.view.append_column(col)
- col = Gtk.ColumnViewColumn.new(_("Date"), factory_date)
- self.view.append_column(col)
+ self.view.connect('activate', self.event_activate)
self.box_main.append(self.view)
-
+
+ def event_activate(self, widget, idx):
+ o = widget.get_model().get_selected_item()
+ ev = o.event()
+ cfg = self.get_application().cfg
+ win = EventWindow(zone=cfg.get("BASE_ZONE"))
+ win.set_transient_for(self)
+ win.set_size_request(800, 600)
+ win.update(ev)
+ win.present()
+
+
def add_event(self, ev):
logg.info("adding event {}".format(str(ev)))
o = WindowEvent(ev)