fix: standardize a bit more for the farmOS Animal Assets view
This commit is contained in:
parent
87101d6b04
commit
9cfa91e091
6 changed files with 222 additions and 145 deletions
|
|
@ -202,8 +202,8 @@ class WuttaFarmMenuHandler(base.MenuHandler):
|
||||||
{"type": "sep"},
|
{"type": "sep"},
|
||||||
{
|
{
|
||||||
"title": "Animal Assets",
|
"title": "Animal Assets",
|
||||||
"route": "farmos_animals",
|
"route": "farmos_assets_animal",
|
||||||
"perm": "farmos_animals.list",
|
"perm": "farmos_assets_animal.list",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Group Assets",
|
"title": "Group Assets",
|
||||||
|
|
@ -311,8 +311,8 @@ class WuttaFarmMenuHandler(base.MenuHandler):
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"title": "Animal",
|
"title": "Animal",
|
||||||
"route": "farmos_animals",
|
"route": "farmos_assets_animal",
|
||||||
"perm": "farmos_animals.list",
|
"perm": "farmos_assets_animal.list",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Group",
|
"title": "Group",
|
||||||
|
|
|
||||||
|
|
@ -153,11 +153,11 @@ class AnimalAssetView(AssetMasterView):
|
||||||
"thumbnail",
|
"thumbnail",
|
||||||
"drupal_id",
|
"drupal_id",
|
||||||
"asset_name",
|
"asset_name",
|
||||||
|
"produces_eggs",
|
||||||
"animal_type",
|
"animal_type",
|
||||||
"birthdate",
|
"birthdate",
|
||||||
"is_sterile",
|
"is_sterile",
|
||||||
"sex",
|
"sex",
|
||||||
"produces_eggs",
|
|
||||||
"archived",
|
"archived",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ class AssetMasterView(WuttaFarmMasterView):
|
||||||
# TODO
|
# TODO
|
||||||
route = None
|
route = None
|
||||||
if asset.asset_type == "animal":
|
if asset.asset_type == "animal":
|
||||||
route = "farmos_animals.view"
|
route = "farmos_assets_animal.view"
|
||||||
elif asset.asset_type == "group":
|
elif asset.asset_type == "group":
|
||||||
route = "farmos_groups.view"
|
route = "farmos_groups.view"
|
||||||
elif asset.asset_type == "land":
|
elif asset.asset_type == "land":
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,8 @@ class CommonView(base.CommonView):
|
||||||
"asset_types.versions",
|
"asset_types.versions",
|
||||||
"farmos_animal_types.list",
|
"farmos_animal_types.list",
|
||||||
"farmos_animal_types.view",
|
"farmos_animal_types.view",
|
||||||
"farmos_animals.list",
|
"farmos_assets_animal.list",
|
||||||
"farmos_animals.view",
|
"farmos_assets_animal.view",
|
||||||
"farmos_asset_types.list",
|
"farmos_asset_types.list",
|
||||||
"farmos_asset_types.view",
|
"farmos_asset_types.view",
|
||||||
"farmos_groups.list",
|
"farmos_groups.list",
|
||||||
|
|
|
||||||
|
|
@ -30,28 +30,27 @@ import colander
|
||||||
from wuttaweb.forms.schema import WuttaDateTime
|
from wuttaweb.forms.schema import WuttaDateTime
|
||||||
from wuttaweb.forms.widgets import WuttaDateTimeWidget
|
from wuttaweb.forms.widgets import WuttaDateTimeWidget
|
||||||
|
|
||||||
from wuttafarm.web.views.farmos import FarmOSMasterView
|
from wuttafarm.web.views.farmos.assets import AssetMasterView
|
||||||
from wuttafarm.web.forms.schema import UsersType, AnimalTypeType, StructureType
|
from wuttafarm.web.forms.schema import AnimalTypeType
|
||||||
from wuttafarm.web.forms.widgets import ImageWidget
|
|
||||||
|
|
||||||
|
|
||||||
class AnimalView(FarmOSMasterView):
|
class AnimalView(AssetMasterView):
|
||||||
"""
|
"""
|
||||||
Master view for Farm Animals
|
Master view for Farm Animals
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model_name = "farmos_animal"
|
model_name = "farmos_animal_asset"
|
||||||
model_title = "farmOS Animal"
|
model_title = "farmOS Animal Asset"
|
||||||
model_title_plural = "farmOS Animals"
|
model_title_plural = "farmOS Animal Assets"
|
||||||
|
|
||||||
route_prefix = "farmos_animals"
|
route_prefix = "farmos_assets_animal"
|
||||||
url_prefix = "/farmOS/animals"
|
url_prefix = "/farmOS/assets/animal"
|
||||||
|
|
||||||
|
farmos_asset_type = "animal"
|
||||||
farmos_refurl_path = "/assets/animal"
|
farmos_refurl_path = "/assets/animal"
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
"animal_type": "Species / Breed",
|
"animal_type": "Species / Breed",
|
||||||
"location": "Current Location",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
grid_columns = [
|
grid_columns = [
|
||||||
|
|
@ -62,8 +61,6 @@ class AnimalView(FarmOSMasterView):
|
||||||
"archived",
|
"archived",
|
||||||
]
|
]
|
||||||
|
|
||||||
sort_defaults = "name"
|
|
||||||
|
|
||||||
form_fields = [
|
form_fields = [
|
||||||
"name",
|
"name",
|
||||||
"animal_type",
|
"animal_type",
|
||||||
|
|
@ -80,38 +77,21 @@ class AnimalView(FarmOSMasterView):
|
||||||
"image",
|
"image",
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_grid_data(self, columns=None, session=None):
|
|
||||||
animals = self.farmos_client.resource.get("asset", "animal")
|
|
||||||
return [self.normalize_animal(a) for a in animals["data"]]
|
|
||||||
|
|
||||||
def configure_grid(self, grid):
|
def configure_grid(self, grid):
|
||||||
g = grid
|
g = grid
|
||||||
super().configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
# name
|
|
||||||
g.set_link("name")
|
|
||||||
g.set_searchable("name")
|
|
||||||
|
|
||||||
# birthdate
|
# birthdate
|
||||||
g.set_renderer("birthdate", "date")
|
g.set_renderer("birthdate", "date")
|
||||||
|
|
||||||
# is_sterile
|
# is_sterile
|
||||||
g.set_renderer("is_sterile", "boolean")
|
g.set_renderer("is_sterile", "boolean")
|
||||||
|
|
||||||
# archived
|
|
||||||
g.set_renderer("archived", "boolean")
|
|
||||||
|
|
||||||
def get_instance(self):
|
def get_instance(self):
|
||||||
|
|
||||||
animal = self.farmos_client.resource.get_id(
|
data = super().get_instance()
|
||||||
"asset", "animal", self.request.matchdict["uuid"]
|
|
||||||
)
|
|
||||||
self.raw_json = animal
|
|
||||||
|
|
||||||
# instance data
|
if relationships := self.raw_json["data"].get("relationships"):
|
||||||
data = self.normalize_animal(animal["data"])
|
|
||||||
|
|
||||||
if relationships := animal["data"].get("relationships"):
|
|
||||||
|
|
||||||
# add animal type
|
# add animal type
|
||||||
if animal_type := relationships.get("animal_type"):
|
if animal_type := relationships.get("animal_type"):
|
||||||
|
|
@ -124,54 +104,11 @@ class AnimalView(FarmOSMasterView):
|
||||||
"name": animal_type["data"]["attributes"]["name"],
|
"name": animal_type["data"]["attributes"]["name"],
|
||||||
}
|
}
|
||||||
|
|
||||||
# add location
|
|
||||||
if location := relationships.get("location"):
|
|
||||||
if location["data"]:
|
|
||||||
location = self.farmos_client.resource.get_id(
|
|
||||||
"asset", "structure", location["data"][0]["id"]
|
|
||||||
)
|
|
||||||
data["location"] = {
|
|
||||||
"uuid": location["data"]["id"],
|
|
||||||
"name": location["data"]["attributes"]["name"],
|
|
||||||
}
|
|
||||||
|
|
||||||
# add owners
|
|
||||||
if owner := relationships.get("owner"):
|
|
||||||
data["owners"] = []
|
|
||||||
for owner_data in owner["data"]:
|
|
||||||
owner = self.farmos_client.resource.get_id(
|
|
||||||
"user", "user", owner_data["id"]
|
|
||||||
)
|
|
||||||
data["owners"].append(
|
|
||||||
{
|
|
||||||
"uuid": owner["data"]["id"],
|
|
||||||
"display_name": owner["data"]["attributes"]["display_name"],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# add image urls
|
|
||||||
if image := relationships.get("image"):
|
|
||||||
if image["data"]:
|
|
||||||
image = self.farmos_client.resource.get_id(
|
|
||||||
"file", "file", image["data"][0]["id"]
|
|
||||||
)
|
|
||||||
data["raw_image_url"] = self.app.get_farmos_url(
|
|
||||||
image["data"]["attributes"]["uri"]["url"]
|
|
||||||
)
|
|
||||||
# nb. other styles available: medium, wide
|
|
||||||
data["large_image_url"] = image["data"]["attributes"][
|
|
||||||
"image_style_uri"
|
|
||||||
]["large"]
|
|
||||||
data["thumbnail_image_url"] = image["data"]["attributes"][
|
|
||||||
"image_style_uri"
|
|
||||||
]["thumbnail"]
|
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_instance_title(self, animal):
|
def normalize_asset(self, animal):
|
||||||
return animal["name"]
|
|
||||||
|
|
||||||
def normalize_animal(self, animal):
|
normal = super().normalize_asset(animal)
|
||||||
|
|
||||||
birthdate = animal["attributes"]["birthdate"]
|
birthdate = animal["attributes"]["birthdate"]
|
||||||
if birthdate:
|
if birthdate:
|
||||||
|
|
@ -184,30 +121,19 @@ class AnimalView(FarmOSMasterView):
|
||||||
else:
|
else:
|
||||||
sterile = animal["attributes"]["is_castrated"]
|
sterile = animal["attributes"]["is_castrated"]
|
||||||
|
|
||||||
if notes := animal["attributes"]["notes"]:
|
normal.update(
|
||||||
notes = notes["value"]
|
{
|
||||||
|
"birthdate": birthdate,
|
||||||
|
"sex": animal["attributes"]["sex"] or colander.null,
|
||||||
|
"is_sterile": sterile,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if self.farmos_4x:
|
return normal
|
||||||
archived = animal["attributes"]["archived"]
|
|
||||||
else:
|
|
||||||
archived = animal["attributes"]["status"] == "archived"
|
|
||||||
|
|
||||||
return {
|
|
||||||
"uuid": animal["id"],
|
|
||||||
"drupal_id": animal["attributes"]["drupal_internal__id"],
|
|
||||||
"name": animal["attributes"]["name"],
|
|
||||||
"birthdate": birthdate,
|
|
||||||
"sex": animal["attributes"]["sex"] or colander.null,
|
|
||||||
"is_sterile": sterile,
|
|
||||||
"location": colander.null, # TODO
|
|
||||||
"archived": archived,
|
|
||||||
"notes": notes or colander.null,
|
|
||||||
}
|
|
||||||
|
|
||||||
def configure_form(self, form):
|
def configure_form(self, form):
|
||||||
f = form
|
f = form
|
||||||
super().configure_form(f)
|
super().configure_form(f)
|
||||||
animal = f.model_instance
|
|
||||||
|
|
||||||
# animal_type
|
# animal_type
|
||||||
f.set_node("animal_type", AnimalTypeType(self.request))
|
f.set_node("animal_type", AnimalTypeType(self.request))
|
||||||
|
|
@ -219,52 +145,28 @@ class AnimalView(FarmOSMasterView):
|
||||||
# is_sterile
|
# is_sterile
|
||||||
f.set_node("is_sterile", colander.Boolean())
|
f.set_node("is_sterile", colander.Boolean())
|
||||||
|
|
||||||
# location
|
|
||||||
f.set_node("location", StructureType(self.request))
|
|
||||||
|
|
||||||
# owners
|
|
||||||
f.set_node("owners", UsersType(self.request))
|
|
||||||
|
|
||||||
# notes
|
|
||||||
f.set_widget("notes", "notes")
|
|
||||||
|
|
||||||
# archived
|
|
||||||
f.set_node("archived", colander.Boolean())
|
|
||||||
|
|
||||||
# image
|
|
||||||
if url := animal.get("large_image_url"):
|
|
||||||
f.set_widget("image", ImageWidget("animal image"))
|
|
||||||
f.set_default("image", url)
|
|
||||||
|
|
||||||
def get_xref_buttons(self, animal):
|
def get_xref_buttons(self, animal):
|
||||||
model = self.app.model
|
buttons = super().get_xref_buttons(animal)
|
||||||
session = self.Session()
|
|
||||||
|
|
||||||
buttons = [
|
if self.app.is_farmos_mirror():
|
||||||
self.make_button(
|
model = self.app.model
|
||||||
"View in farmOS",
|
session = self.Session()
|
||||||
primary=True,
|
|
||||||
url=self.app.get_farmos_url(f"/asset/{animal['drupal_id']}"),
|
|
||||||
target="_blank",
|
|
||||||
icon_left="external-link-alt",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
if wf_animal := (
|
if wf_animal := (
|
||||||
session.query(model.Asset)
|
session.query(model.Asset)
|
||||||
.filter(model.Asset.farmos_uuid == animal["uuid"])
|
.filter(model.Asset.farmos_uuid == animal["uuid"])
|
||||||
.first()
|
.first()
|
||||||
):
|
):
|
||||||
buttons.append(
|
buttons.append(
|
||||||
self.make_button(
|
self.make_button(
|
||||||
f"View {self.app.get_title()} record",
|
f"View {self.app.get_title()} record",
|
||||||
primary=True,
|
primary=True,
|
||||||
url=self.request.route_url(
|
url=self.request.route_url(
|
||||||
"animal_assets.view", uuid=wf_animal.uuid
|
"animal_assets.view", uuid=wf_animal.uuid
|
||||||
),
|
),
|
||||||
icon_left="eye",
|
icon_left="eye",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
return buttons
|
return buttons
|
||||||
|
|
||||||
|
|
|
||||||
175
src/wuttafarm/web/views/farmos/assets.py
Normal file
175
src/wuttafarm/web/views/farmos/assets.py
Normal file
|
|
@ -0,0 +1,175 @@
|
||||||
|
# -*- 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 <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
"""
|
||||||
|
Base class for Asset master views
|
||||||
|
"""
|
||||||
|
|
||||||
|
import colander
|
||||||
|
|
||||||
|
from wuttafarm.web.views.farmos import FarmOSMasterView
|
||||||
|
from wuttafarm.web.forms.schema import UsersType, StructureType
|
||||||
|
from wuttafarm.web.forms.widgets import ImageWidget
|
||||||
|
|
||||||
|
|
||||||
|
class AssetMasterView(FarmOSMasterView):
|
||||||
|
"""
|
||||||
|
Base class for Asset master views
|
||||||
|
"""
|
||||||
|
|
||||||
|
farmos_asset_type = None
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
"name": "Asset Name",
|
||||||
|
"location": "Current Location",
|
||||||
|
}
|
||||||
|
|
||||||
|
grid_columns = [
|
||||||
|
"name",
|
||||||
|
"archived",
|
||||||
|
]
|
||||||
|
|
||||||
|
sort_defaults = "name"
|
||||||
|
|
||||||
|
def get_grid_data(self, columns=None, session=None):
|
||||||
|
result = self.farmos_client.asset.get(self.farmos_asset_type)
|
||||||
|
return [self.normalize_asset(a) for a in result["data"]]
|
||||||
|
|
||||||
|
def configure_grid(self, grid):
|
||||||
|
g = grid
|
||||||
|
super().configure_grid(g)
|
||||||
|
|
||||||
|
# name
|
||||||
|
g.set_link("name")
|
||||||
|
g.set_searchable("name")
|
||||||
|
|
||||||
|
# archived
|
||||||
|
g.set_renderer("archived", "boolean")
|
||||||
|
|
||||||
|
def get_instance(self):
|
||||||
|
asset = self.farmos_client.resource.get_id(
|
||||||
|
"asset", self.farmos_asset_type, self.request.matchdict["uuid"]
|
||||||
|
)
|
||||||
|
self.raw_json = asset
|
||||||
|
|
||||||
|
# instance data
|
||||||
|
data = self.normalize_asset(asset["data"])
|
||||||
|
|
||||||
|
if relationships := asset["data"].get("relationships"):
|
||||||
|
|
||||||
|
# add location
|
||||||
|
if location := relationships.get("location"):
|
||||||
|
if location["data"]:
|
||||||
|
location = self.farmos_client.resource.get_id(
|
||||||
|
"asset", "structure", location["data"][0]["id"]
|
||||||
|
)
|
||||||
|
data["location"] = {
|
||||||
|
"uuid": location["data"]["id"],
|
||||||
|
"name": location["data"]["attributes"]["name"],
|
||||||
|
}
|
||||||
|
|
||||||
|
# add owners
|
||||||
|
if owner := relationships.get("owner"):
|
||||||
|
data["owners"] = []
|
||||||
|
for owner_data in owner["data"]:
|
||||||
|
owner = self.farmos_client.resource.get_id(
|
||||||
|
"user", "user", owner_data["id"]
|
||||||
|
)
|
||||||
|
data["owners"].append(
|
||||||
|
{
|
||||||
|
"uuid": owner["data"]["id"],
|
||||||
|
"display_name": owner["data"]["attributes"]["display_name"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# add image urls
|
||||||
|
if image := relationships.get("image"):
|
||||||
|
if image["data"]:
|
||||||
|
image = self.farmos_client.resource.get_id(
|
||||||
|
"file", "file", image["data"][0]["id"]
|
||||||
|
)
|
||||||
|
data["raw_image_url"] = self.app.get_farmos_url(
|
||||||
|
image["data"]["attributes"]["uri"]["url"]
|
||||||
|
)
|
||||||
|
# nb. other styles available: medium, wide
|
||||||
|
data["large_image_url"] = image["data"]["attributes"][
|
||||||
|
"image_style_uri"
|
||||||
|
]["large"]
|
||||||
|
data["thumbnail_image_url"] = image["data"]["attributes"][
|
||||||
|
"image_style_uri"
|
||||||
|
]["thumbnail"]
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_instance_title(self, asset):
|
||||||
|
return asset["name"]
|
||||||
|
|
||||||
|
def normalize_asset(self, asset):
|
||||||
|
|
||||||
|
if notes := asset["attributes"]["notes"]:
|
||||||
|
notes = notes["value"]
|
||||||
|
|
||||||
|
if self.farmos_4x:
|
||||||
|
archived = asset["attributes"]["archived"]
|
||||||
|
else:
|
||||||
|
archived = asset["attributes"]["status"] == "archived"
|
||||||
|
|
||||||
|
return {
|
||||||
|
"uuid": asset["id"],
|
||||||
|
"drupal_id": asset["attributes"]["drupal_internal__id"],
|
||||||
|
"name": asset["attributes"]["name"],
|
||||||
|
"location": colander.null, # TODO
|
||||||
|
"notes": notes or colander.null,
|
||||||
|
"archived": archived,
|
||||||
|
}
|
||||||
|
|
||||||
|
def configure_form(self, form):
|
||||||
|
f = form
|
||||||
|
super().configure_form(f)
|
||||||
|
animal = f.model_instance
|
||||||
|
|
||||||
|
# location
|
||||||
|
f.set_node("location", StructureType(self.request))
|
||||||
|
|
||||||
|
# owners
|
||||||
|
f.set_node("owners", UsersType(self.request))
|
||||||
|
|
||||||
|
# notes
|
||||||
|
f.set_widget("notes", "notes")
|
||||||
|
|
||||||
|
# archived
|
||||||
|
f.set_node("archived", colander.Boolean())
|
||||||
|
|
||||||
|
# image
|
||||||
|
if url := animal.get("large_image_url"):
|
||||||
|
f.set_widget("image", ImageWidget("animal image"))
|
||||||
|
f.set_default("image", url)
|
||||||
|
|
||||||
|
def get_xref_buttons(self, asset):
|
||||||
|
return [
|
||||||
|
self.make_button(
|
||||||
|
"View in farmOS",
|
||||||
|
primary=True,
|
||||||
|
url=self.app.get_farmos_url(f"/asset/{asset['drupal_id']}"),
|
||||||
|
target="_blank",
|
||||||
|
icon_left="external-link-alt",
|
||||||
|
),
|
||||||
|
]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue