/**************************************************************************** * This file is part of the project AqHome. * AqHome (c) by 2023 Martin Preuss, all rights reserved. * * The license for this file can be found in the file COPYING which you * should have received along with this file. ****************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "./u_devices.h" #include "./u_objects.h" #include "./aqhomehttp.h" #include #include #include /* ------------------------------------------------------------------------------------------------ * defines * ------------------------------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ static int _addOrEditObject(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *db, int id); static GWEN_DB_NODE *_findObjectByIdAndReturnAsDb(AQH_HTTP_URLHANDLER *uh, int id); static int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf); static int _writeEditPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf); static void _listObjectsIntoBuffer(AQH_HTTP_URLHANDLER *uh, GWEN_BUFFER *pageBuf); static void _writeEditingTable(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf); static void _setFromObject(AQH_DEVICE *device, const AQH_DEVICE *srcDevice); /* ------------------------------------------------------------------------------------------------ * implementations * ------------------------------------------------------------------------------------------------ */ AQH_HTTP_URLHANDLER *AQH_DevicesHttpUrlHandler_new(AQH_SERVICE *sv) { AQH_HTTP_URLHANDLER *uh; uh=AQH_ObjectsHttpUrlHandler_new(sv, AQHOME_HTTP_PERMS_LIST_DEVICES, AQHOME_HTTP_PERMS_ADD_DEVICE, AQHOME_HTTP_PERMS_DEL_DEVICE, AQHOME_HTTP_PERMS_EDIT_DEVICE, "/devices/list"); AQH_ObjectsHttpUrlHandler_SetAddOrEditObjectFn(uh, _addOrEditObject); AQH_ObjectsHttpUrlHandler_SetFindObjectByIdAndReturnAsDbFn(uh, _findObjectByIdAndReturnAsDb); AQH_ObjectsHttpUrlHandler_SetWriteAddPageFn(uh, _writeAddPage); AQH_ObjectsHttpUrlHandler_SetWriteEditPageFn(uh, _writeEditPage); AQH_ObjectsHttpUrlHandler_SetListObjectsIntoBufferFn(uh, _listObjectsIntoBuffer); return uh; } int _addOrEditObject(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *db, int id) { AQH_SERVICE *sv; AQH_STORAGE *sto; AQH_DEVICE *newDevice; const char *deviceName; int rv; sv=AQH_HttpUrlHandler_GetHttpService(uh); sto=AqHomeHttpService_GetStorage(sv); newDevice=AQH_Device_fromDb(db); deviceName=AQH_Device_GetName(newDevice); if (!(deviceName && *deviceName)) { DBG_INFO(NULL, "Missing device name"); AQH_Device_free(newDevice); return GWEN_ERROR_INVALID; } rv=AqHomeHttpService_LockStorage(sv); if (rv<0) { DBG_ERROR(NULL, "Error locking storage"); AQH_Device_free(newDevice); return GWEN_ERROR_IO; } if (id>0) { AQH_DEVICE *device; DBG_INFO(NULL, "Edit existing device"); device=AQH_Storage_GetDeviceById(sto, id); if (device==NULL) { AqHomeHttpService_UnlockStorage(sv); DBG_ERROR(NULL, "Device %d not found", id); AQH_Device_free(newDevice); return GWEN_ERROR_NOT_FOUND; } AQH_Device_SetId(device, id); _setFromObject(device, newDevice); AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED); } else { AQH_DEVICE *device; DBG_INFO(NULL, "Adding new device"); device=AQH_Storage_GetDeviceByName(sto, deviceName); if (device) { AqHomeHttpService_UnlockStorage(sv); DBG_ERROR(NULL, "Device %s exists", deviceName); AQH_Device_free(newDevice); return GWEN_ERROR_FOUND; } device=AQH_Device_new(); AQH_Device_SetId(device, 0); _setFromObject(device, newDevice); AQH_Storage_AddDevice(sto, device); AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED); } AQH_Device_free(newDevice); rv=AqHomeHttpService_UnlockStorage(sv); if (rv<0) { DBG_ERROR(NULL, "Error unlocking storage"); return GWEN_ERROR_IO; } return 0; } void _setFromObject(AQH_DEVICE *device, const AQH_DEVICE *srcDevice) { AQH_Device_SetRoomId(device, AQH_Device_GetRoomId(srcDevice)); AQH_Device_SetName(device, AQH_Device_GetName(srcDevice)); AQH_Device_SetDeviceType(device, AQH_Device_GetDeviceType(srcDevice)); AQH_Device_SetLocation(device, AQH_Device_GetLocation(srcDevice)); AQH_Device_SetDescription(device, AQH_Device_GetDescription(srcDevice)); } GWEN_DB_NODE *_findObjectByIdAndReturnAsDb(AQH_HTTP_URLHANDLER *uh, int id) { AQH_SERVICE *sv; AQH_STORAGE *sto; const AQH_DEVICE *device; sv=AQH_HttpUrlHandler_GetHttpService(uh); sto=AqHomeHttpService_GetStorage(sv); device=AQH_Storage_GetDeviceById(sto, id); if (device) { GWEN_DB_NODE *db; db=GWEN_DB_Group_new("device"); AQH_Device_toDb(device, db); return db; } return NULL; } int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf) { GWEN_Buffer_AppendArgs(pageBuf, "

%s


\n" "
", I18N("Add Device")); _writeEditingTable(uh, dbValues, pageBuf); GWEN_Buffer_AppendArgs(pageBuf, "
", I18N("Submit")); return 0; } int _writeEditPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf) { GWEN_Buffer_AppendArgs(pageBuf, "

%s


\n" "
", I18N("Edit Device"), (long unsigned int)(dbValues?GWEN_DB_GetIntValue(dbValues, "id", 0, 0):0)); _writeEditingTable(uh, dbValues, pageBuf); GWEN_Buffer_AppendArgs(pageBuf, "
", I18N("Submit")); return 0; } void _writeEditingTable(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf) { AQH_SERVICE *sv; AQH_STORAGE *sto; const AQH_ROOM_LIST *roomList; unsigned long int selectedRoomId=0; char numbuf[16]; sv=AQH_HttpUrlHandler_GetHttpService(uh); sto=AqHomeHttpService_GetStorage(sv); roomList=AQH_Storage_GetRoomList(sto); selectedRoomId=(unsigned long int)(dbValues?GWEN_DB_GetIntValue(dbValues, "roomId", 0, 0):0); snprintf(numbuf, sizeof(numbuf)-1, "%lu", selectedRoomId); numbuf[sizeof(numbuf)-1]=0; GWEN_Buffer_AppendArgs(pageBuf, " " " " " " " " " ", I18N("Name"), dbValues?GWEN_DB_GetCharValue(dbValues, "name", 0, ""):""); GWEN_Buffer_AppendArgs(pageBuf, "" ""); GWEN_Buffer_AppendArgs(pageBuf, " " " " " " " ", I18N("Type"), dbValues?GWEN_DB_GetCharValue(dbValues, "deviceType", 0, ""):""); GWEN_Buffer_AppendArgs(pageBuf, " " " " " " " ", I18N("Location"), dbValues?GWEN_DB_GetCharValue(dbValues, "location", 0, ""):""); GWEN_Buffer_AppendArgs(pageBuf, " " " " " " " " "
", I18N("Description"), dbValues?GWEN_DB_GetCharValue(dbValues, "description", 0, ""):""); } void _listObjectsIntoBuffer(AQH_HTTP_URLHANDLER *uh, GWEN_BUFFER *pageBuf) { AQH_SERVICE *sv; AQH_STORAGE *sto; const AQH_DEVICE_LIST *rl; sv=AQH_HttpUrlHandler_GetHttpService(uh); sto=AqHomeHttpService_GetStorage(sv); GWEN_Buffer_AppendArgs(pageBuf, "

%s

" "" "" " " "", I18N("Devices"), I18N("Name"), I18N("Room"), I18N("Type"), I18N("Location"), I18N("Description")); GWEN_Buffer_AppendString(pageBuf, ""); rl=AQH_Storage_GetDeviceList(sto); if (rl) { const AQH_DEVICE *device; device=AQH_Device_List_First(rl); while(device) { long unsigned int id; int roomId; const char *name; const char *roomName=NULL; const char *devType; const char *descr; const char *location; const AQH_ROOM *r=NULL; id=(long unsigned int) AQH_Device_GetId(device); roomId=(long unsigned int) AQH_Device_GetRoomId(device); if (roomId>0) r=AQH_Storage_GetRoomById(sto, roomId); if (r) roomName=AQH_Room_GetName(r); name=AQH_Device_GetName(device); devType=AQH_Device_GetDeviceType(device); descr=AQH_Device_GetDescription(device); location=AQH_Device_GetLocation(device); GWEN_Buffer_AppendArgs(pageBuf, "" "" "", name?name:"", roomName?roomName:"", devType?devType:"", location?location:"", descr?descr:"", id); device=AQH_Device_List_Next(device); } } GWEN_Buffer_AppendString(pageBuf, ""); GWEN_Buffer_AppendArgs(pageBuf, "
%s%s%s%s%s
%s%s%s%s%s" "
%s
", I18N("Add Device")); }