diff --git a/CHANGELOG.md b/CHANGELOG.md index d392b59..20691f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,23 +5,6 @@ All notable changes to WuttaFarm will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## v0.12.1 (2026-05-31) - -### Fix - -- allow null for `Quantity.measure` field - -## v0.12.0 (2026-05-30) - -### Feat - -- add support for Compost Assets - -### Fix - -- fix Location column for All Logs subgrid when viewing Asset -- sort related assets field when viewing a log - ## v0.11.4 (2026-05-30) ### Fix diff --git a/pyproject.toml b/pyproject.toml index 16c7c60..6956f88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "hatchling.build" [project] name = "WuttaFarm" -version = "0.12.1" +version = "0.11.4" description = "Web app to integrate with and extend farmOS" readme = "README.md" authors = [ diff --git a/src/wuttafarm/db/alembic/versions/a240a1449de9_add_compostasset.py b/src/wuttafarm/db/alembic/versions/a240a1449de9_add_compostasset.py deleted file mode 100644 index 902cf0c..0000000 --- a/src/wuttafarm/db/alembic/versions/a240a1449de9_add_compostasset.py +++ /dev/null @@ -1,102 +0,0 @@ -"""add CompostAsset - -Revision ID: a240a1449de9 -Revises: dd4d4142b96d -Create Date: 2026-05-30 21:12:36.464851 - -""" - -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -import wuttjamaican.db.util - - -# revision identifiers, used by Alembic. -revision: str = "a240a1449de9" -down_revision: Union[str, None] = "dd4d4142b96d" -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - - # asset_compost - op.create_table( - "asset_compost", - sa.Column("uuid", wuttjamaican.db.util.UUID(), nullable=False), - sa.ForeignKeyConstraint( - ["uuid"], ["asset.uuid"], name=op.f("fk_asset_compost_uuid_asset") - ), - sa.PrimaryKeyConstraint("uuid", name=op.f("pk_asset_compost")), - ) - op.create_table( - "asset_compost_version", - sa.Column( - "uuid", wuttjamaican.db.util.UUID(), autoincrement=False, nullable=False - ), - sa.Column( - "transaction_id", sa.BigInteger(), autoincrement=False, nullable=False - ), - sa.Column("end_transaction_id", sa.BigInteger(), nullable=True), - sa.Column("operation_type", sa.SmallInteger(), nullable=False), - sa.PrimaryKeyConstraint( - "uuid", "transaction_id", name=op.f("pk_asset_compost_version") - ), - ) - op.create_index( - op.f("ix_asset_compost_version_end_transaction_id"), - "asset_compost_version", - ["end_transaction_id"], - unique=False, - ) - op.create_index( - op.f("ix_asset_compost_version_operation_type"), - "asset_compost_version", - ["operation_type"], - unique=False, - ) - op.create_index( - "ix_asset_compost_version_pk_transaction_id", - "asset_compost_version", - ["uuid", sa.literal_column("transaction_id DESC")], - unique=False, - ) - op.create_index( - "ix_asset_compost_version_pk_validity", - "asset_compost_version", - ["uuid", "transaction_id", "end_transaction_id"], - unique=False, - ) - op.create_index( - op.f("ix_asset_compost_version_transaction_id"), - "asset_compost_version", - ["transaction_id"], - unique=False, - ) - - -def downgrade() -> None: - - # asset_compost - op.drop_index( - op.f("ix_asset_compost_version_transaction_id"), - table_name="asset_compost_version", - ) - op.drop_index( - "ix_asset_compost_version_pk_validity", table_name="asset_compost_version" - ) - op.drop_index( - "ix_asset_compost_version_pk_transaction_id", table_name="asset_compost_version" - ) - op.drop_index( - op.f("ix_asset_compost_version_operation_type"), - table_name="asset_compost_version", - ) - op.drop_index( - op.f("ix_asset_compost_version_end_transaction_id"), - table_name="asset_compost_version", - ) - op.drop_table("asset_compost_version") - op.drop_table("asset_compost") diff --git a/src/wuttafarm/db/alembic/versions/c30a725b54f9_allow_null_for_quantity_measure_id.py b/src/wuttafarm/db/alembic/versions/c30a725b54f9_allow_null_for_quantity_measure_id.py deleted file mode 100644 index 2c5952d..0000000 --- a/src/wuttafarm/db/alembic/versions/c30a725b54f9_allow_null_for_quantity_measure_id.py +++ /dev/null @@ -1,36 +0,0 @@ -"""allow null for quantity.measure_id - -Revision ID: c30a725b54f9 -Revises: a240a1449de9 -Create Date: 2026-05-30 22:14:21.056993 - -""" - -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -import wuttjamaican.db.util - - -# revision identifiers, used by Alembic. -revision: str = "c30a725b54f9" -down_revision: Union[str, None] = "a240a1449de9" -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - - # quantity - op.alter_column( - "quantity", "measure_id", existing_type=sa.VARCHAR(length=20), nullable=True - ) - - -def downgrade() -> None: - - # quantity - op.alter_column( - "quantity", "measure_id", existing_type=sa.VARCHAR(length=20), nullable=False - ) diff --git a/src/wuttafarm/db/model/__init__.py b/src/wuttafarm/db/model/__init__.py index 923f163..716fd1c 100644 --- a/src/wuttafarm/db/model/__init__.py +++ b/src/wuttafarm/db/model/__init__.py @@ -53,7 +53,6 @@ from .asset_plant import ( PlantAssetSeason, ) from .asset_water import WaterAsset -from .asset_compost import CompostAsset from .log import LogType, Log, LogAsset, LogGroup, LogLocation, LogQuantity, LogOwner from .log_activity import ActivityLog from .log_harvest import HarvestLog diff --git a/src/wuttafarm/db/model/asset_compost.py b/src/wuttafarm/db/model/asset_compost.py deleted file mode 100644 index 37b5bb5..0000000 --- a/src/wuttafarm/db/model/asset_compost.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8; -*- -################################################################################ -# -# WuttaFarm --Web app to integrate with and extend farmOS -# Copyright © 2026 Lance Edgar -# -# This file is part of WuttaFarm. -# -# WuttaFarm 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, either version 3 of the License, or (at your option) any later -# version. -# -# WuttaFarm 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 -# WuttaFarm. If not, see . -# -################################################################################ -""" -Model definition for Compost -""" - -from wuttjamaican.db import model - -from wuttafarm.db.model.asset import AssetMixin, add_asset_proxies - - -class CompostAsset(AssetMixin, model.Base): - """ - Represents an compost asset from farmOS - """ - - __tablename__ = "asset_compost" - __versioned__ = {} - __wutta_hint__ = { - "model_title": "Compost Asset", - "model_title_plural": "Compost Assets", - "farmos_asset_type": "compost", - } - - -add_asset_proxies(CompostAsset) diff --git a/src/wuttafarm/db/model/quantities.py b/src/wuttafarm/db/model/quantities.py index c04f85b..4fa92af 100644 --- a/src/wuttafarm/db/model/quantities.py +++ b/src/wuttafarm/db/model/quantities.py @@ -109,7 +109,7 @@ class Quantity(model.Base): measure_id = sa.Column( sa.String(length=20), sa.ForeignKey("measure.drupal_id"), - nullable=True, + nullable=False, doc=""" Measure for the quantity. """, @@ -192,12 +192,7 @@ class Quantity(model.Base): app = config.get_app() value = app.render_quantity(value) units = str(self.units or "") - - if measure: - return f"( {measure} ) {value} {units}" - - label = self.label or "" - return f"{label} {value} {units}" + return f"( {measure} ) {value} {units}" def __str__(self): return self.render_as_text() diff --git a/src/wuttafarm/farmos/importing/model.py b/src/wuttafarm/farmos/importing/model.py index f351d37..e7ebe23 100644 --- a/src/wuttafarm/farmos/importing/model.py +++ b/src/wuttafarm/farmos/importing/model.py @@ -574,21 +574,6 @@ class WaterAssetImporter(ToFarmOSAsset): ] -class CompostAssetImporter(ToFarmOSAsset): - - model_title = "CompostAsset" - farmos_asset_type = "compost" - - supported_fields = [ - "uuid", - "asset_name", - "is_location", - "is_fixed", - "notes", - "archived", - ] - - ############################## # quantity importers ############################## diff --git a/src/wuttafarm/farmos/importing/wuttafarm.py b/src/wuttafarm/farmos/importing/wuttafarm.py index 9792278..d60a96f 100644 --- a/src/wuttafarm/farmos/importing/wuttafarm.py +++ b/src/wuttafarm/farmos/importing/wuttafarm.py @@ -99,7 +99,6 @@ class FromWuttaFarmToFarmOS(FromWuttaFarmHandler, ToFarmOSHandler): importers["LandAsset"] = LandAssetImporter importers["StructureAsset"] = StructureAssetImporter importers["WaterAsset"] = WaterAssetImporter - importers["CompostAsset"] = CompostAssetImporter importers["EquipmentType"] = EquipmentTypeImporter importers["EquipmentAsset"] = EquipmentAssetImporter importers["AnimalType"] = AnimalTypeImporter @@ -476,16 +475,6 @@ class WaterAssetImporter(FromWuttaFarmAsset, farmos_importing.model.WaterAssetIm source_model_class = model.WaterAsset -class CompostAssetImporter( - FromWuttaFarmAsset, farmos_importing.model.CompostAssetImporter -): - """ - WuttaFarm → farmOS API exporter for Compost Assets - """ - - source_model_class = model.CompostAsset - - ############################## # quantity importers ############################## diff --git a/src/wuttafarm/importing/farmos.py b/src/wuttafarm/importing/farmos.py index 81fedf0..eb82fe1 100644 --- a/src/wuttafarm/importing/farmos.py +++ b/src/wuttafarm/importing/farmos.py @@ -107,7 +107,6 @@ class FromFarmOSToWuttaFarm(FromFarmOSHandler, ToWuttaFarmHandler): importers["StructureType"] = StructureTypeImporter importers["StructureAsset"] = StructureAssetImporter importers["WaterAsset"] = WaterAssetImporter - importers["CompostAsset"] = CompostAssetImporter importers["EquipmentType"] = EquipmentTypeImporter importers["EquipmentAsset"] = EquipmentAssetImporter importers["AnimalType"] = AnimalTypeImporter @@ -1034,14 +1033,6 @@ class WaterAssetImporter(AssetImporterBase): model_class = model.WaterAsset -class CompostAssetImporter(AssetImporterBase): - """ - farmOS API → WuttaFarm importer for Compost Assets - """ - - model_class = model.CompostAsset - - class UserImporter(FromFarmOS, ToWutta): """ farmOS API → WuttaFarm importer for Users diff --git a/src/wuttafarm/web/forms/widgets.py b/src/wuttafarm/web/forms/widgets.py index 6897660..db79eae 100644 --- a/src/wuttafarm/web/forms/widgets.py +++ b/src/wuttafarm/web/forms/widgets.py @@ -667,17 +667,10 @@ class AssetRefsWidget(Widget): readonly = kw.get("readonly", self.readonly) if readonly: - assets = [] for uuid in cstruct or []: - if asset := session.get(model.Asset, uuid): - assets.append(asset) - - assets.sort(key=lambda asset: asset.asset_name) - - html = [] - for asset in assets: - html.append( + asset = session.get(model.Asset, uuid) + assets.append( HTML.tag( "li", c=tags.link_to( @@ -688,8 +681,7 @@ class AssetRefsWidget(Widget): ), ) ) - - return HTML.tag("ul", c=html) + return HTML.tag("ul", c=assets) values = kw.get("values", self.values) if not isinstance(values, sequence_types): diff --git a/src/wuttafarm/web/menus.py b/src/wuttafarm/web/menus.py index 71b9e5d..62d3d9c 100644 --- a/src/wuttafarm/web/menus.py +++ b/src/wuttafarm/web/menus.py @@ -92,11 +92,6 @@ class WuttaFarmMenuHandler(base.MenuHandler): "route": "animal_assets", "perm": "animal_assets.list", }, - { - "title": "Compost", - "route": "compost_assets", - "perm": "compost_assets.list", - }, { "title": "Equipment", "route": "equipment_assets", @@ -264,11 +259,6 @@ class WuttaFarmMenuHandler(base.MenuHandler): "route": "farmos_animal_assets", "perm": "farmos_animal_assets.list", }, - { - "title": "Compost Assets", - "route": "farmos_compost_assets", - "perm": "farmos_compost_assets.list", - }, { "title": "Equipment Assets", "route": "farmos_equipment_assets", @@ -413,11 +403,6 @@ class WuttaFarmMenuHandler(base.MenuHandler): "route": "farmos_animal_assets", "perm": "farmos_animal_assets.list", }, - { - "title": "Compost", - "route": "farmos_compost_assets", - "perm": "farmos_compost_assets.list", - }, { "title": "Equipment", "route": "farmos_equipment_assets", diff --git a/src/wuttafarm/web/views/__init__.py b/src/wuttafarm/web/views/__init__.py index 2069aa7..b663cf5 100644 --- a/src/wuttafarm/web/views/__init__.py +++ b/src/wuttafarm/web/views/__init__.py @@ -59,7 +59,6 @@ def includeme(config): config.include("wuttafarm.web.views.groups") config.include("wuttafarm.web.views.plants") config.include("wuttafarm.web.views.water") - config.include("wuttafarm.web.views.compost") config.include("wuttafarm.web.views.logs") config.include("wuttafarm.web.views.logs_activity") config.include("wuttafarm.web.views.logs_harvest") diff --git a/src/wuttafarm/web/views/assets.py b/src/wuttafarm/web/views/assets.py index d9516a5..1ada778 100644 --- a/src/wuttafarm/web/views/assets.py +++ b/src/wuttafarm/web/views/assets.py @@ -71,18 +71,6 @@ class AssetMasterView(WuttaFarmMasterView): "groups": "Group Membership", } - grid_columns = [ - "thumbnail", - "drupal_id", - "asset_name", - "groups", - "asset_type", - "parents", - "owners", - "locations", - "archived", - ] - sort_defaults = "asset_name" filter_defaults = { @@ -115,7 +103,6 @@ class AssetMasterView(WuttaFarmMasterView): row_labels = { "message": "Log Name", - "locations": "Location", } row_grid_columns = [ @@ -125,7 +112,7 @@ class AssetMasterView(WuttaFarmMasterView): "message", "log_type", "assets", - "locations", + "location", "quantity", "is_group_assignment", ] @@ -459,9 +446,6 @@ class AssetMasterView(WuttaFarmMasterView): # assets g.set_renderer("assets", self.render_assets_for_grid) - # locations - g.set_renderer("locations", self.render_assets_for_grid) - def render_assets_for_grid(self, log, field, value): assets = getattr(log, field) diff --git a/src/wuttafarm/web/views/compost.py b/src/wuttafarm/web/views/compost.py deleted file mode 100644 index c1634bb..0000000 --- a/src/wuttafarm/web/views/compost.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8; -*- -################################################################################ -# -# WuttaFarm --Web app to integrate with and extend farmOS -# Copyright © 2026 Lance Edgar -# -# This file is part of WuttaFarm. -# -# WuttaFarm 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, either version 3 of the License, or (at your option) any later -# version. -# -# WuttaFarm 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 -# WuttaFarm. If not, see . -# -################################################################################ -""" -Master view for Compost Assets -""" - -from wuttafarm.db.model import CompostAsset -from wuttafarm.web.views.assets import AssetMasterView - - -class CompostAssetView(AssetMasterView): - """ - Master view for Compost Assets - """ - - model_class = CompostAsset - route_prefix = "compost_assets" - url_prefix = "/assets/compost" - - farmos_bundle = "compost" - farmos_refurl_path = "/assets/compost" - - grid_columns = [ - "thumbnail", - "drupal_id", - "asset_name", - "groups", - "parents", - "owners", - "locations", - "archived", - ] - - -def defaults(config, **kwargs): - base = globals() - - CompostAssetView = kwargs.get("CompostAssetView", base["CompostAssetView"]) - CompostAssetView.defaults(config) - - -def includeme(config): - defaults(config) diff --git a/src/wuttafarm/web/views/farmos/__init__.py b/src/wuttafarm/web/views/farmos/__init__.py index 6ea7181..708b553 100644 --- a/src/wuttafarm/web/views/farmos/__init__.py +++ b/src/wuttafarm/web/views/farmos/__init__.py @@ -42,7 +42,6 @@ def includeme(config): config.include("wuttafarm.web.views.farmos.groups") config.include("wuttafarm.web.views.farmos.plants") config.include("wuttafarm.web.views.farmos.water") - config.include("wuttafarm.web.views.farmos.compost") config.include("wuttafarm.web.views.farmos.log_types") config.include("wuttafarm.web.views.farmos.logs_activity") config.include("wuttafarm.web.views.farmos.logs_harvest") diff --git a/src/wuttafarm/web/views/farmos/assets.py b/src/wuttafarm/web/views/farmos/assets.py index 517e8da..24dd145 100644 --- a/src/wuttafarm/web/views/farmos/assets.py +++ b/src/wuttafarm/web/views/farmos/assets.py @@ -327,12 +327,6 @@ class AssetMasterView(FarmOSMasterView): # archived f.set_node("archived", colander.Boolean()) - # drupal_id - if self.creating: - f.remove("drupal_id") - else: - f.set_readonly("drupal_id") - # thumbnail_url if self.creating or self.editing: f.remove("thumbnail_url") diff --git a/src/wuttafarm/web/views/farmos/compost.py b/src/wuttafarm/web/views/farmos/compost.py deleted file mode 100644 index 50ef62c..0000000 --- a/src/wuttafarm/web/views/farmos/compost.py +++ /dev/null @@ -1,79 +0,0 @@ -# -*- coding: utf-8; -*- -################################################################################ -# -# WuttaFarm --Web app to integrate with and extend farmOS -# Copyright © 2026 Lance Edgar -# -# This file is part of WuttaFarm. -# -# WuttaFarm 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, either version 3 of the License, or (at your option) any later -# version. -# -# WuttaFarm 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 -# WuttaFarm. If not, see . -# -################################################################################ -""" -Master view for farmOS Compost Assets -""" - -from webhelpers2.html import tags - -from wuttafarm.web.views.farmos.assets import AssetMasterView - - -class CompostAssetView(AssetMasterView): - """ - Master view for farmOS Compost Assets - """ - - model_name = "farmos_compost_assets" - model_title = "farmOS Compost Asset" - model_title_plural = "farmOS Compost Assets" - - route_prefix = "farmos_compost_assets" - url_prefix = "/farmOS/assets/compost" - - farmos_asset_type = "compost" - farmos_refurl_path = "/assets/compost" - - def get_xref_buttons(self, compost): - model = self.app.model - session = self.Session() - - buttons = super().get_xref_buttons(compost) - - if wf_compost := ( - session.query(model.Asset) - .filter(model.Asset.farmos_uuid == compost["uuid"]) - .first() - ): - buttons.append( - self.make_button( - f"View {self.app.get_title()} record", - primary=True, - url=self.request.route_url( - "compost_assets.view", uuid=wf_compost.uuid - ), - icon_left="eye", - ) - ) - - return buttons - - -def defaults(config, **kwargs): - base = globals() - - CompostAssetView = kwargs.get("CompostAssetView", base["CompostAssetView"]) - CompostAssetView.defaults(config) - - -def includeme(config): - defaults(config) diff --git a/src/wuttafarm/web/views/quantities.py b/src/wuttafarm/web/views/quantities.py index 05f624b..9a91941 100644 --- a/src/wuttafarm/web/views/quantities.py +++ b/src/wuttafarm/web/views/quantities.py @@ -298,8 +298,7 @@ class QuantityMasterView(WuttaFarmMasterView): f.remove("measure") else: f.set_readonly("measure") - if quantity.measure: - f.set_default("measure", quantity.measure.name) + f.set_default("measure", quantity.measure.name) # value if self.creating: