mirror of
https://gitlab.gnome.org/jpu/cambalache.git
synced 2025-06-25 00:02:51 -04:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ae11d6485a | ||
|
a69df48d17 | ||
|
090ef7f633 | ||
|
4cce14ea3f | ||
|
7ebfa1999c | ||
|
d81f8ee7fd | ||
|
aef72f38cc | ||
|
3527266b4a | ||
|
d8f59a9144 | ||
|
c8a3f36641 |
13
.local.env
13
.local.env
@ -1,13 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
SCRIPT=$(readlink -f $0)
|
||||
DIRNAME=$(dirname $SCRIPT)
|
||||
ARCH_TRIPLET=$(cc -dumpmachine)
|
||||
export LIBDIR=$DIRNAME/.local/lib/$ARCH_TRIPLET
|
||||
export LD_LIBRARY_PATH=$LIBDIR:$LIBDIR/cambalache:$LIBDIR/cmb_catalog_gen:$LD_LIBRARY_PATH
|
||||
export GI_TYPELIB_PATH=$LIBDIR/girepository-1.0:$LIBDIR/cambalache:$LIBDIR/cmb_catalog_gen:$GI_TYPELIB_PATH
|
||||
export PKG_CONFIG_PATH=$LIBDIR/pkgconfig:$PKG_CONFIG_PATH
|
||||
export GSETTINGS_SCHEMA_DIR=$DIRNAME/.local/share/glib-2.0/schemas:$GSETTINGS_SCHEMA_DIR
|
||||
export XDG_DATA_DIRS=$DIRNAME/.local/share:$XDG_DATA_DIRS
|
||||
export PYTHONPATH=$DIRNAME/.local/lib/python3/dist-packages:$PYTHONPATH
|
||||
export PATH=$DIRNAME/.local/bin:$PATH
|
@ -9,6 +9,11 @@ Cambalache used even/odd minor numbers to differentiate between stable and
|
||||
development releases.
|
||||
|
||||
|
||||
## 0.96.1
|
||||
|
||||
- Fix/improve GResource list model update
|
||||
- Fix removing custom class data like styles
|
||||
|
||||
## 0.96.0
|
||||
|
||||
- Add GResource support
|
||||
|
@ -152,7 +152,7 @@ cambalache under .local directoy and set up all environment variables needed to
|
||||
run the app from the source directory. (Follow manual installation to ensure
|
||||
you have everything needed)
|
||||
|
||||
`./run-dev.sh`
|
||||
`./run-dev.py`
|
||||
|
||||
This is meant for Cambalache development only.
|
||||
|
||||
|
@ -221,7 +221,10 @@
|
||||
<ui template-class="CmbContextMenu" filename="cmb_context_menu.ui" sha256="81eba3adf715348a5c03ef4cbc151eebd5d9aa8b5a14c5968232f68a61ae573c"/>
|
||||
<ui template-class="CmbDBInspector" filename="cmb_db_inspector.ui" sha256="4451cdb08d24bd4a802ea692c0ebb4ef46af13152984c0b435d29bf4eb7dab55"/>
|
||||
<ui filename="app/cmb_shortcuts.ui" sha256="d7ac37fd2430788a9e210ed4bc84dcfeba5609bdcc801afb192bfd900c7a8883"/>
|
||||
<ui template-class="CmbFileButton" filename="control/cmb_file_button.ui" sha256="f859b4f85d7c80c1fef69b68ebb9129423d9c72fdb38d304132784f7361cbbfd"/>
|
||||
<ui template-class="CmbFileButton" filename="control/cmb_file_button.ui" sha256="f859b4f85d7c80c1fef69b68ebb9129423d9c72fdb38d304132784f7361cbbfd">
|
||||
<property id="dialog_title" type-id="gchararray" disable-inline-object="0" required="0" disabled="0"/>
|
||||
<property id="use_open" type-id="gboolean" disable-inline-object="0" required="0" disabled="0"/>
|
||||
</ui>
|
||||
<ui template-class="CmbNotificationListView" filename="cmb_notification_list_view.ui" sha256="13622645038ef2aaa154f74cd300f9c0fa0dccf69d45d6c9376f9034e6ee57fb"/>
|
||||
<ui template-class="CmbVersionNotificationView" filename="cmb_version_notification_view.ui" sha256="9a3ced46b90eb7e425d1c345853c4e8e908870c61c75475f7e20ce3c9ee8cec6"/>
|
||||
<ui template-class="CmbMessageNotificationView" filename="cmb_message_notification_view.ui" sha256="debeffd184e225d82ed29ac590654b8160363e8d5606366dc8acb3ff9840fee3"/>
|
||||
|
@ -2023,7 +2023,7 @@ class CmbDB(GObject.GObject):
|
||||
self.__unknown_tag(child, root, child.tag)
|
||||
continue
|
||||
|
||||
prefix, = self.__node_get(child, "prefix")
|
||||
prefix, = self.__node_get(child, ["prefix"])
|
||||
|
||||
resource_id = self.add_gresource("gresource", parent_id=gresource_id, gresource_prefix=prefix)
|
||||
|
||||
@ -3034,6 +3034,20 @@ class CmbDB(GObject.GObject):
|
||||
(ui_id, ) if parent_id is None else (ui_id, parent_id)
|
||||
)
|
||||
|
||||
def update_gresource_children_position(self, gresource_id):
|
||||
self.execute(
|
||||
"""
|
||||
UPDATE gresource SET position=new.position - 1
|
||||
FROM (
|
||||
SELECT row_number() OVER (PARTITION BY parent_id ORDER BY position) position, parent_id, gresource_id
|
||||
FROM gresource
|
||||
WHERE parent_id=?
|
||||
) AS new
|
||||
WHERE gresource.parent_id=new.parent_id AND gresource.gresource_id=new.gresource_id;
|
||||
""",
|
||||
(gresource_id, )
|
||||
)
|
||||
|
||||
|
||||
# Function used in SQLite
|
||||
|
||||
|
@ -36,6 +36,8 @@ class CmbGResource(CmbBaseGResource, Gio.ListModel):
|
||||
path_parent = GObject.Property(type=CmbPath, flags=GObject.ParamFlags.READWRITE)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self._last_known = None
|
||||
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.connect("notify", self.__on_notify)
|
||||
@ -47,6 +49,13 @@ class CmbGResource(CmbBaseGResource, Gio.ListModel):
|
||||
return f"CmbGResource<{self.resource_type}> id={self.gresource_id}"
|
||||
|
||||
def __on_notify(self, obj, pspec):
|
||||
resource_type = self.resource_type
|
||||
|
||||
if (resource_type == "gresources" and pspec.name == "gresources-filename") or \
|
||||
(resource_type == "gresource" and pspec.name == "gresource-prefix") or \
|
||||
(resource_type == "file" and pspec.name == "file-filename"):
|
||||
obj.notify("display-name")
|
||||
|
||||
self.project._gresource_changed(self, pspec.name)
|
||||
|
||||
@GObject.Property(type=CmbBaseGResource)
|
||||
@ -84,6 +93,34 @@ class CmbGResource(CmbBaseGResource, Gio.ListModel):
|
||||
file_filename = self.file_filename
|
||||
return file_filename if file_filename else _("Unnamed file {id}").format(id=self.gresource_id)
|
||||
|
||||
# GListModel helpers
|
||||
def _save_last_known_parent_and_position(self):
|
||||
self._last_known = (self.parent, self.position)
|
||||
|
||||
def _update_new_parent(self):
|
||||
parent = self.parent
|
||||
position = self.position
|
||||
|
||||
# Emit GListModel signal to update model
|
||||
if parent:
|
||||
parent.items_changed(position, 0, 1)
|
||||
parent.notify("n-items")
|
||||
|
||||
self._last_known = None
|
||||
|
||||
def _remove_from_old_parent(self):
|
||||
if self._last_known is None:
|
||||
return
|
||||
|
||||
parent, position = self._last_known
|
||||
|
||||
# Emit GListModel signal to update model
|
||||
if parent:
|
||||
parent.items_changed(position, 1, 0)
|
||||
parent.notify("n-items")
|
||||
|
||||
self._last_known = None
|
||||
|
||||
# GListModel iface
|
||||
def do_get_item(self, position):
|
||||
gresource_id = self.gresource_id
|
||||
|
@ -221,6 +221,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="CmbFileButton" id="file_filename">
|
||||
<property name="use-open">True</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="column-span">1</property>
|
||||
|
@ -30,6 +30,7 @@ import http.client
|
||||
import time
|
||||
import platform
|
||||
|
||||
from uuid import uuid4
|
||||
from urllib.parse import urlparse
|
||||
from .config import VERSION
|
||||
from gi.repository import GObject, GLib, Gio, Gdk, Gtk, Adw, HarfBuzz
|
||||
@ -130,7 +131,7 @@ class CmbNotificationCenter(GObject.GObject):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.retry_interval = 1
|
||||
self.retry_interval = 2
|
||||
self.user_agent = self.__get_user_agent()
|
||||
self.store = Gio.ListStore(item_type=CmbNotification)
|
||||
self.settings = Gio.Settings(schema_id="ar.xjuan.Cambalache.notification")
|
||||
@ -156,6 +157,10 @@ class CmbNotificationCenter(GObject.GObject):
|
||||
logger.warning(f"{backend.scheme} is not supported, only HTTPS")
|
||||
return
|
||||
|
||||
# Ensure we have a UUID
|
||||
if not self.uuid:
|
||||
self.uuid = str(uuid4())
|
||||
|
||||
logger.info(f"User Agent: {self.user_agent}")
|
||||
logger.info(f"UUID: {self.uuid}")
|
||||
|
||||
@ -248,9 +253,6 @@ class CmbNotificationCenter(GObject.GObject):
|
||||
def __get_notification_idle(self, data):
|
||||
logger.debug(f"Got notification response {json.dumps(data, indent=2, sort_keys=True)}")
|
||||
|
||||
if "uuid" in data:
|
||||
self.uuid = data["uuid"]
|
||||
|
||||
if "notification" in data:
|
||||
notification = self.__notification_from_dict(data["notification"])
|
||||
self.store.insert(0, notification)
|
||||
@ -264,10 +266,10 @@ class CmbNotificationCenter(GObject.GObject):
|
||||
return GLib.SOURCE_REMOVE
|
||||
|
||||
def __get_notification_thread(self):
|
||||
headers = {"User-Agent": self.user_agent}
|
||||
|
||||
if self.uuid:
|
||||
headers["x-cambalache-uuid"] = self.uuid
|
||||
headers = {
|
||||
"User-Agent": self.user_agent,
|
||||
"x-cambalache-uuid": self.uuid,
|
||||
}
|
||||
|
||||
try:
|
||||
logger.info(f"GET /notification {headers=}")
|
||||
@ -277,7 +279,7 @@ class CmbNotificationCenter(GObject.GObject):
|
||||
assert response.status == 200
|
||||
|
||||
# Reset retry interval
|
||||
self.retry_interval = 1
|
||||
self.retry_interval = 2
|
||||
|
||||
data = response.read().decode()
|
||||
|
||||
@ -318,19 +320,19 @@ class CmbNotificationCenter(GObject.GObject):
|
||||
def __poll_vote_idle(self, data):
|
||||
logger.debug(f"Got vote response {data}")
|
||||
|
||||
uuid = data["uuid"]
|
||||
poll_uuid = data["uuid"]
|
||||
results = data["results"]
|
||||
|
||||
for notification in self.store:
|
||||
if isinstance(notification, CmbPollNotification) and notification.poll.id == uuid:
|
||||
if isinstance(notification, CmbPollNotification) and notification.poll.id == poll_uuid:
|
||||
notification.results = CmbPollResult(**results)
|
||||
self.__save_notifications()
|
||||
break
|
||||
return GLib.SOURCE_REMOVE
|
||||
|
||||
def __poll_vote_exception_idle(self, uuid):
|
||||
def __poll_vote_exception_idle(self, poll_uuid):
|
||||
for notification in self.store:
|
||||
if isinstance(notification, CmbPollNotification) and notification.poll.id == uuid:
|
||||
if isinstance(notification, CmbPollNotification) and notification.poll.id == poll_uuid:
|
||||
notification.my_votes = []
|
||||
break
|
||||
return GLib.SOURCE_REMOVE
|
||||
|
@ -70,7 +70,10 @@ class CmbObjectDataEditor(Gtk.Box):
|
||||
if self.info:
|
||||
self.object.remove_data(self.__data)
|
||||
else:
|
||||
self.__data.parent.remove_data(self.__data)
|
||||
if self.__data.parent:
|
||||
self.__data.parent.remove_data(self.__data)
|
||||
else:
|
||||
self.__data.object.remove_data(self.__data)
|
||||
|
||||
@GObject.Property(type=GObject.Object)
|
||||
def object(self):
|
||||
@ -133,13 +136,11 @@ class CmbObjectDataEditor(Gtk.Box):
|
||||
self.__update_arg(key)
|
||||
|
||||
def __on_data_added(self, obj, data):
|
||||
if self.info and self.data is None and self.info == data.info:
|
||||
self.data = data
|
||||
self.__update_view()
|
||||
self.data = data
|
||||
self.__update_view()
|
||||
|
||||
def __on_data_removed(self, obj, data):
|
||||
if self.object and self.info:
|
||||
self.__remove_data_editor(data)
|
||||
self.__remove_data_editor(data)
|
||||
|
||||
def __ensure_object_data(self, history_message):
|
||||
if self.data:
|
||||
|
@ -999,33 +999,41 @@ class CmbProject(GObject.Object, Gio.ListModel):
|
||||
self.db.commit()
|
||||
self.history_pop()
|
||||
except Exception:
|
||||
logger.warning("Tried to add GResource", exc_info=True)
|
||||
return None
|
||||
else:
|
||||
return self.__add_gresource(True, gresource_id, resource_type)
|
||||
finally:
|
||||
gresource = self.__add_gresource(True, gresource_id, resource_type)
|
||||
gresource._update_new_parent()
|
||||
return gresource
|
||||
|
||||
def __remove_gresource(self, gresource):
|
||||
if gresource is None:
|
||||
logger.warning("Tried to remove a None GResource", exc_info=True)
|
||||
return
|
||||
|
||||
print("__remove_gresource", gresource, self.__gresource_id.get(gresource.gresource_id, None))
|
||||
|
||||
self.__gresource_id.pop(gresource.gresource_id, None)
|
||||
|
||||
self.__selection_remove(gresource)
|
||||
print("SELECTION", self.__selection)
|
||||
self.__gresource_id.pop(gresource.gresource_id, None)
|
||||
self.emit("gresource-removed", gresource)
|
||||
|
||||
def remove_gresource(self, gresource):
|
||||
try:
|
||||
print("remove_gresource", gresource)
|
||||
parent_id = gresource.parent_id
|
||||
|
||||
gresource._save_last_known_parent_and_position()
|
||||
self.history_push(_('Remove GResource "{name}"').format(name=gresource.display_name))
|
||||
self.db.execute("DELETE FROM gresource WHERE gresource_id=?;", (gresource.gresource_id,))
|
||||
|
||||
# Update position
|
||||
if parent_id:
|
||||
self.db.update_gresource_children_position(parent_id)
|
||||
|
||||
self.history_pop()
|
||||
self.db.commit()
|
||||
self.__remove_gresource(gresource)
|
||||
except Exception as e:
|
||||
logger.warning(f"Error removing gresource {e}", exc_info=True)
|
||||
finally:
|
||||
self.__remove_gresource(gresource)
|
||||
gresource._remove_from_old_parent()
|
||||
|
||||
def get_css_providers(self):
|
||||
return list(self.__css_id.values())
|
||||
@ -1117,7 +1125,7 @@ class CmbProject(GObject.Object, Gio.ListModel):
|
||||
except Exception as e:
|
||||
logger.warning(f"Error adding object {obj_name}: {e}")
|
||||
return None
|
||||
else:
|
||||
finally:
|
||||
obj = self.__add_object(True, ui_id, object_id, obj_type, name, parent_id, position=position)
|
||||
obj._update_new_parent()
|
||||
return obj
|
||||
@ -1283,10 +1291,17 @@ class CmbProject(GObject.Object, Gio.ListModel):
|
||||
obj._property_changed(p)
|
||||
|
||||
def __undo_redo_do(self, undo, update_objects=None):
|
||||
def get_object_position(c, row):
|
||||
ui_id, parent_id, position = row[0], row[4], row[8]
|
||||
parent = self.get_object_by_id(ui_id, parent_id)
|
||||
return parent, position
|
||||
def get_object_position(table, row):
|
||||
if table == "object":
|
||||
ui_id, parent_id, position = row[0], row[4], row[8]
|
||||
parent = self.get_object_by_id(ui_id, parent_id)
|
||||
return parent, position
|
||||
elif table == "gresource":
|
||||
parent_id, position = row[2], row[3]
|
||||
parent = self.get_gresource_by_id(parent_id)
|
||||
return parent, position
|
||||
|
||||
return None, None
|
||||
|
||||
c = self.db.cursor()
|
||||
|
||||
@ -1303,8 +1318,8 @@ class CmbProject(GObject.Object, Gio.ListModel):
|
||||
|
||||
# Undo or Redo command
|
||||
if command == "INSERT":
|
||||
if table == "object":
|
||||
parent, position = get_object_position(c, new_values)
|
||||
if table in ["object", "gresource"]:
|
||||
parent, position = get_object_position(table, new_values)
|
||||
|
||||
if undo:
|
||||
update_objects.append((parent, position, 1, 0))
|
||||
@ -1318,8 +1333,8 @@ class CmbProject(GObject.Object, Gio.ListModel):
|
||||
|
||||
self.__undo_redo_update_insert_delete(c, undo, command, table, columns, table_pk, old_values, new_values)
|
||||
elif command == "DELETE":
|
||||
if table == "object":
|
||||
parent, position = get_object_position(c, old_values)
|
||||
if table in ["object", "gresource"]:
|
||||
parent, position = get_object_position(table, old_values)
|
||||
|
||||
if undo:
|
||||
update_objects.append((parent, position, 0, 1))
|
||||
@ -1335,8 +1350,8 @@ class CmbProject(GObject.Object, Gio.ListModel):
|
||||
elif command == "UPDATE":
|
||||
# parent_id and position have to change together because their are part of a unique index
|
||||
if update_objects is not None and table == "object" and "position" in columns and "parent_id" in columns:
|
||||
old_parent, old_position = get_object_position(c, old_values)
|
||||
new_parent, new_position = get_object_position(c, new_values)
|
||||
old_parent, old_position = get_object_position(table, old_values)
|
||||
new_parent, new_position = get_object_position(table, new_values)
|
||||
|
||||
if undo:
|
||||
if old_position >= 0:
|
||||
@ -1348,6 +1363,9 @@ class CmbProject(GObject.Object, Gio.ListModel):
|
||||
update_objects.append((new_parent, new_position, 0, 1))
|
||||
if old_position >= 0:
|
||||
update_objects.append((old_parent, old_position, 1, 0))
|
||||
elif table == "gresource":
|
||||
# TODO
|
||||
pass
|
||||
|
||||
if undo:
|
||||
self.db.history_update(table, columns, table_pk, old_values)
|
||||
@ -1476,12 +1494,27 @@ class CmbProject(GObject.Object, Gio.ListModel):
|
||||
else:
|
||||
obj._remove_data(data)
|
||||
else:
|
||||
parent = obj.data_dict.get(f"{row[2]}.{row[6]}", None)
|
||||
owner_id, data_id, id, parent_id = row[2], row[3], row[4], row[6]
|
||||
|
||||
parent = obj.data_dict.get(f"{owner_id}.{parent_id}", None)
|
||||
|
||||
if parent:
|
||||
parent._add_child(row[2], row[3], row[4])
|
||||
parent._add_child(owner_id, data_id, id)
|
||||
else:
|
||||
obj._add_data(row[2], row[3], row[4])
|
||||
info = self.type_info.get(owner_id)
|
||||
taginfo = None
|
||||
|
||||
if info:
|
||||
r = self.db.execute(
|
||||
"SELECT key FROM type_data WHERE owner_id=? AND data_id=?;",
|
||||
(owner_id, data_id)
|
||||
).fetchone()
|
||||
|
||||
data_key = r[0] if r else None
|
||||
if data_key:
|
||||
taginfo = info.get_data_info(data_key)
|
||||
|
||||
obj._add_data(owner_id, data_id, id, info=taginfo)
|
||||
elif table == "object_data_arg":
|
||||
obj = self.get_object_by_id(pk[0], pk[1])
|
||||
if obj:
|
||||
|
@ -49,4 +49,9 @@ class CmbVersionNotificationView(Gtk.Box):
|
||||
notification = self.notification
|
||||
self.version_label.props.label = _("<b>Version {version} is available</b>").format(version=notification.version)
|
||||
self.release_notes_label.props.label = notification.release_notes
|
||||
self.read_more_button.props.uri = notification.read_more_url
|
||||
|
||||
if notification.read_more_url:
|
||||
self.read_more_button.props.uri = notification.read_more_url
|
||||
self.read_more_button.show()
|
||||
else:
|
||||
self.read_more_button.hide()
|
||||
|
@ -35,6 +35,7 @@ class CmbFileButton(Gtk.Button):
|
||||
|
||||
dirname = GObject.Property(type=str, flags=GObject.ParamFlags.READWRITE)
|
||||
dialog_title = GObject.Property(type=str, default=_("Select filename"), flags=GObject.ParamFlags.READWRITE)
|
||||
use_open = GObject.Property(type=bool, default=False, flags=GObject.ParamFlags.READWRITE)
|
||||
|
||||
label = Gtk.Template.Child()
|
||||
|
||||
@ -59,12 +60,15 @@ class CmbFileButton(Gtk.Button):
|
||||
|
||||
def dialog_callback(dialog, res):
|
||||
try:
|
||||
file = dialog.save_finish(res)
|
||||
file = dialog.open_finish(res) if self.use_open else dialog.save_finish(res)
|
||||
self.cmb_value = os.path.relpath(file.get_path(), start=self.dirname)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
dialog.save(self.get_root(), None, dialog_callback)
|
||||
if self.use_open:
|
||||
dialog.open(self.get_root(), None, dialog_callback)
|
||||
else:
|
||||
dialog.save(self.get_root(), None, dialog_callback)
|
||||
|
||||
@GObject.Property(type=str)
|
||||
def cmb_value(self):
|
||||
|
@ -1,11 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
source .local.env
|
||||
SCRIPT=$(readlink -f $0)
|
||||
DIRNAME=$(dirname $SCRIPT)
|
||||
export GSETTINGS_BACKEND=memory
|
||||
export HOME=$DIRNAME/.local/home
|
||||
mkdir -p $HOME/Projects
|
||||
|
||||
export COVERAGE_PROCESS_START=$DIRNAME/pyproject.toml
|
||||
|
@ -14,6 +14,15 @@
|
||||
</p>
|
||||
</description>
|
||||
<releases>
|
||||
<release date="2025-05-16" version="0.96.1">
|
||||
<description>
|
||||
<p>GResource First Bugfix Release!</p>
|
||||
<ul>
|
||||
<li>Fix/improve GResource list model update</li>
|
||||
<li>Fix removing custom class data like styles</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release date="2025-04-20" version="0.96.0">
|
||||
<description>
|
||||
<p>GResource Release!</p>
|
||||
|
@ -1,6 +1,6 @@
|
||||
project(
|
||||
'cambalache', 'c',
|
||||
version: '0.96.0',
|
||||
version: '0.96.1',
|
||||
meson_version: '>= 1.1.0',
|
||||
default_options: [
|
||||
'c_std=c11',
|
||||
|
39
run-dev.py
Executable file
39
run-dev.py
Executable file
@ -0,0 +1,39 @@
|
||||
#!/bin/python3
|
||||
#
|
||||
# run-dev - Script to run Cambalache from sources
|
||||
#
|
||||
# Copyright (C) 2025 Juan Pablo Ugarte
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; version 2 of the License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# Authors:
|
||||
# Juan Pablo Ugarte <juanpablougarte@gmail.com>
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import locale
|
||||
|
||||
from tools.cmb_init_dev import cmb_init_dev
|
||||
|
||||
# Compile deps and install things in .local
|
||||
cmb_init_dev()
|
||||
|
||||
basedir = os.path.join(os.path.split(os.path.dirname(__file__))[0])
|
||||
locale.bindtextdomain("cambalache", os.path.join(basedir, ".local", "share", "locale"))
|
||||
locale.textdomain("cambalache")
|
||||
|
||||
from cambalache.app import CmbApplication # noqa E402
|
||||
|
||||
CmbApplication().run(sys.argv)
|
16
run-dev.sh
16
run-dev.sh
@ -1,16 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
source .local.env
|
||||
|
||||
if python3 $DIRNAME/tools/cmb_init_dev.py; then
|
||||
python3 - $@ << EOF
|
||||
import sys
|
||||
import locale
|
||||
locale.bindtextdomain("cambalache", "$DIRNAME/.local/share/locale")
|
||||
locale.textdomain("cambalache")
|
||||
from cambalache.app import CmbApplication
|
||||
CmbApplication().run(sys.argv)
|
||||
EOF
|
||||
else
|
||||
echo Could not initialize dev environment
|
||||
fi
|
10
run-tests.sh
10
run-tests.sh
@ -1,10 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
source .local.env
|
||||
SCRIPT=$(readlink -f $0)
|
||||
DIRNAME=$(dirname $SCRIPT)
|
||||
export GSETTINGS_BACKEND=memory
|
||||
export HOME=$DIRNAME/.local/home
|
||||
mkdir -p $HOME/Projects
|
||||
|
||||
pytest $@
|
@ -1,5 +1,15 @@
|
||||
import os
|
||||
import gi
|
||||
|
||||
basedir = os.path.join(os.path.split(os.path.dirname(__file__))[0])
|
||||
|
||||
# Ensure home directory
|
||||
homedir = os.path.join(basedir, ".local", "home")
|
||||
os.makedirs(os.path.join(homedir, "Projects"), exist_ok=True)
|
||||
|
||||
os.environ["GSETTINGS_BACKEND"] = "memory"
|
||||
os.environ["HOME"] = homedir
|
||||
|
||||
gi.require_version("Gtk", "4.0")
|
||||
from gi.repository import Gtk # noqa E402
|
||||
from tools.cmb_init_dev import cmb_init_dev # noqa E402
|
||||
|
@ -13,7 +13,7 @@ from . import utils as test_utils
|
||||
|
||||
DAY = 3600 * 24
|
||||
now = utils.utcnow()
|
||||
CMB_UUID = str(uuid4())
|
||||
CMB_UUID = notification_center.uuid
|
||||
POLL_UUID = str(uuid4())
|
||||
|
||||
POLL_NOTIFICATION_BASE = {
|
||||
@ -44,16 +44,14 @@ def wait_for_all_threads():
|
||||
|
||||
|
||||
def test_cmb_notification_disabled():
|
||||
assert not notification_center.uuid
|
||||
assert notification_center.enabled is False
|
||||
assert len(notification_center.store) == 0
|
||||
notification_center.enabled = True
|
||||
|
||||
|
||||
@pytest.mark.parametrize("response, headers, n", [
|
||||
@pytest.mark.parametrize("response, n", [
|
||||
(
|
||||
{
|
||||
"uuid": CMB_UUID,
|
||||
"notification": {
|
||||
"type": "version",
|
||||
"start_date": now - DAY,
|
||||
@ -63,14 +61,10 @@ def test_cmb_notification_disabled():
|
||||
"read_more_url": "http://localhost"
|
||||
}
|
||||
},
|
||||
{
|
||||
'User-Agent': notification_center.user_agent
|
||||
},
|
||||
1
|
||||
),
|
||||
(
|
||||
{
|
||||
"uuid": CMB_UUID,
|
||||
"notification": {
|
||||
"type": "message",
|
||||
"start_date": now - DAY,
|
||||
@ -79,26 +73,16 @@ def test_cmb_notification_disabled():
|
||||
"message": "This is a message notification"
|
||||
}
|
||||
},
|
||||
{
|
||||
'User-Agent': notification_center.user_agent,
|
||||
'x-cambalache-uuid': CMB_UUID
|
||||
},
|
||||
2
|
||||
),
|
||||
(
|
||||
{
|
||||
"uuid": CMB_UUID,
|
||||
"notification": POLL_NOTIFICATION_BASE
|
||||
},
|
||||
{
|
||||
'User-Agent': notification_center.user_agent,
|
||||
'x-cambalache-uuid': CMB_UUID
|
||||
},
|
||||
3
|
||||
),
|
||||
(
|
||||
{
|
||||
"uuid": CMB_UUID,
|
||||
"notification": {
|
||||
**POLL_NOTIFICATION_BASE,
|
||||
"results": {
|
||||
@ -107,14 +91,10 @@ def test_cmb_notification_disabled():
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
'User-Agent': notification_center.user_agent,
|
||||
'x-cambalache-uuid': CMB_UUID
|
||||
},
|
||||
4
|
||||
)
|
||||
])
|
||||
def test_cmb_notification_get(mocker, response, headers, n):
|
||||
def test_cmb_notification_get(mocker, response, n):
|
||||
wait_for_all_threads()
|
||||
|
||||
mocker.patch(
|
||||
@ -137,7 +117,14 @@ def test_cmb_notification_get(mocker, response, headers, n):
|
||||
|
||||
test_utils.process_all_pending_gtk_events()
|
||||
|
||||
request_mock.assert_called_with("GET", "/notification", headers=headers)
|
||||
request_mock.assert_called_with(
|
||||
"GET",
|
||||
"/notification",
|
||||
headers={
|
||||
'User-Agent': notification_center.user_agent,
|
||||
'x-cambalache-uuid': CMB_UUID
|
||||
}
|
||||
)
|
||||
|
||||
assert notification_center.uuid == CMB_UUID
|
||||
on_new_notification.assert_called()
|
||||
|
@ -28,12 +28,29 @@ import signal
|
||||
import subprocess
|
||||
|
||||
basedir = os.path.join(os.path.split(os.path.dirname(__file__))[0])
|
||||
sys.path.insert(1, basedir)
|
||||
|
||||
cambalachedir = os.path.join(basedir, "cambalache")
|
||||
localdir = os.path.join(basedir, ".local")
|
||||
locallibdir = os.path.join(localdir, "lib", sys.implementation._multiarch)
|
||||
cambalachedir = os.path.join(basedir, "cambalache")
|
||||
localpkgdatadir = os.path.join(localdir, "share", "cambalache")
|
||||
catalogsdir = os.path.join(localpkgdatadir, "catalogs")
|
||||
localbindir = os.path.join(localdir, "bin")
|
||||
|
||||
for var, value in [
|
||||
("LD_LIBRARY_PATH", f"{locallibdir}:{locallibdir}/cambalache:{locallibdir}/cmb_catalog_gen"),
|
||||
("GI_TYPELIB_PATH", f"{locallibdir}/girepository-1.0:{locallibdir}/cambalache:{locallibdir}/cmb_catalog_gen"),
|
||||
("PKG_CONFIG_PATH", os.path.join(locallibdir, "pkgconfig")),
|
||||
("GSETTINGS_SCHEMA_DIR", os.path.join(localdir, "share", "glib-2.0", "schemas")),
|
||||
("XDG_DATA_DIRS", os.path.join(localdir, "share")),
|
||||
("PYTHONPATH", os.path.join(localdir, "lib", "python3", "dist-packages"))
|
||||
]:
|
||||
if var in os.environ:
|
||||
old_value = os.environ[var]
|
||||
os.environ[var] = f"{value}:{old_value}"
|
||||
else:
|
||||
os.environ[var] = value
|
||||
|
||||
sys.path.insert(1, basedir)
|
||||
sys.path.insert(1, localbindir)
|
||||
|
||||
from gi.repository import GLib # noqa: E402
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user