From de763f14f68722385b03bc8b9d8e39119698ca1a Mon Sep 17 00:00:00 2001 From: despiegk Date: Tue, 2 Sep 2025 09:36:21 +0200 Subject: [PATCH] ... --- lib/hero/heromodels/calendar.v | 8 ++- lib/hero/heromodels/openrpc/comment.v | 10 +-- lib/hero/heromodels/openrpc/processor.v | 37 ++++++++-- lib/hero/heromodels/openrpc_interface.v | 72 +++++++++++++++++++ .../openrpcserver}/comment.v | 64 ++++++++++------- lib/schemas/openrpcserver/core_methods.v | 13 +++- lib/schemas/openrpcserver/core_models.v | 22 ------ lib/schemas/openrpcserver/openrpc_server.v | 20 ++++-- 8 files changed, 178 insertions(+), 68 deletions(-) create mode 100644 lib/hero/heromodels/openrpc_interface.v rename lib/{hero/heromodels => schemas/openrpcserver}/comment.v (61%) diff --git a/lib/hero/heromodels/calendar.v b/lib/hero/heromodels/calendar.v index aeae83e6..80c869d5 100644 --- a/lib/hero/heromodels/calendar.v +++ b/lib/hero/heromodels/calendar.v @@ -29,7 +29,13 @@ pub mut: pub fn calendar_new(args CalendarArgs) !Calendar { mut commentids:=[]u32{} for comment in args.comments{ - commentids << comment_set(comment)! + // Convert CommentArg to CommentArgExtended + extended_comment := CommentArgExtended{ + comment: comment.comment + parent: 0 + author: 0 + } + commentids << comment_set(extended_comment)! } mut obj := Calendar{ id: args.id or {0} // Will be set by DB? diff --git a/lib/hero/heromodels/openrpc/comment.v b/lib/hero/heromodels/openrpc/comment.v index 886ba451..d0f90a07 100644 --- a/lib/hero/heromodels/openrpc/comment.v +++ b/lib/hero/heromodels/openrpc/comment.v @@ -19,7 +19,7 @@ pub mut: } // comment_get retrieves comments based on the provided arguments -fn comment_get(params string) !string { +pub fn comment_get(params string) !string { // Handle empty params if params == 'null' || params == '{}' { return error('No valid search criteria provided. Please specify id, author, or parent.') @@ -47,14 +47,14 @@ fn comment_get(params string) !string { } // comment_set creates or updates a comment -fn comment_set(params string) !string { - comment_arg := json.decode(heromodels.CommentArg, params)! +pub fn comment_set(params string) !string { + comment_arg := json.decode(heromodels.CommentArgExtended, params)! id := heromodels.comment_set(comment_arg)! return json.encode({'id': id}) } // comment_delete removes a comment by ID -fn comment_delete(params string) !string { +pub fn comment_delete(params string) !string { args := json.decode(CommentDeleteArgs, params)! // Check if comment exists @@ -70,7 +70,7 @@ fn comment_delete(params string) !string { } // comment_list returns all comment IDs -fn comment_list() !string { +pub fn comment_list() !string { comments := heromodels.list[heromodels.Comment]()! mut ids := []u32{} diff --git a/lib/hero/heromodels/openrpc/processor.v b/lib/hero/heromodels/openrpc/processor.v index 716609b5..74600cee 100644 --- a/lib/hero/heromodels/openrpc/processor.v +++ b/lib/hero/heromodels/openrpc/processor.v @@ -1,10 +1,33 @@ module openrpc -// processes the JSON-RPC request -pub fn (mut server RPCServer) process(r string, params_str string)! string { +import freeflowuniverse.herolib.schemas.openrpcserver - // Route to appropriate method - result := match r { +// HeroModelsServer extends the base openrpcserver.RPCServer with heromodels-specific functionality +pub struct HeroModelsServer { + openrpcserver.RPCServer +} + +@[params] +pub struct HeroModelsServerArgs { +pub mut: + socket_path string = '/tmp/heromodels' +} + +// new_heromodels_server creates a new HeroModels RPC server +pub fn new_heromodels_server(args HeroModelsServerArgs) !&HeroModelsServer { + base_server := openrpcserver.new_rpc_server( + socket_path: args.socket_path + )! + + return &HeroModelsServer{ + RPCServer: *base_server + } +} + +// process extends the base process method with heromodels-specific methods +pub fn (mut server HeroModelsServer) process(method string, params_str string) !string { + // Route to heromodels-specific methods first + result := match method { 'comment_get' { comment_get(params_str)! } @@ -21,9 +44,9 @@ pub fn (mut server RPCServer) process(r string, params_str string)! string { server.discover()! } else { - return server.create_error_response(-32601, 'Method not found', r) + return server.create_error_response(-32601, 'Method not found', method) } } - + return result -} \ No newline at end of file +} \ No newline at end of file diff --git a/lib/hero/heromodels/openrpc_interface.v b/lib/hero/heromodels/openrpc_interface.v new file mode 100644 index 00000000..95ceb37f --- /dev/null +++ b/lib/hero/heromodels/openrpc_interface.v @@ -0,0 +1,72 @@ +module heromodels + +import freeflowuniverse.herolib.schemas.openrpcserver + +// Re-export types from openrpcserver for convenience +pub type Base = openrpcserver.Base +pub type BaseArgs = openrpcserver.BaseArgs +pub type CommentArg = openrpcserver.CommentArg + +// HeroModelsServer extends the base openrpcserver.RPCServer with heromodels-specific functionality +pub struct HeroModelsServer { + openrpcserver.RPCServer +} + +@[params] +pub struct HeroModelsServerArgs { +pub mut: + socket_path string = '/tmp/heromodels' +} + +// new_heromodels_server creates a new HeroModels RPC server +pub fn new_heromodels_server(args HeroModelsServerArgs) !&HeroModelsServer { + base_server := openrpcserver.new_rpc_server( + socket_path: args.socket_path + )! + + return &HeroModelsServer{ + RPCServer: *base_server + } +} + +// Re-export core methods from openrpcserver for convenience +pub fn set[T](mut obj T) !u32 { + return openrpcserver.set[T](mut obj)! +} + +pub fn get[T](id u32) !T { + return openrpcserver.get[T](id)! +} + +pub fn exists[T](id u32) !bool { + return openrpcserver.exists[T](id)! +} + +pub fn delete[T](id u32) ! { + openrpcserver.delete[T](id)! +} + +pub fn list[T]() ![]T { + return openrpcserver.list[T]()! +} + +// Re-export utility functions +pub fn tags2id(tags []string) !u32 { + return openrpcserver.tags2id(tags)! +} + +pub fn comment_multiset(args []CommentArg) ![]u32 { + return openrpcserver.comment_multiset(args)! +} + +pub fn comments2ids(args []CommentArg) ![]u32 { + return openrpcserver.comments2ids(args)! +} + +pub fn comment2id(comment string) !u32 { + return openrpcserver.comment2id(comment)! +} + +pub fn new_base(args BaseArgs) !Base { + return openrpcserver.new_base(args)! +} \ No newline at end of file diff --git a/lib/hero/heromodels/comment.v b/lib/schemas/openrpcserver/comment.v similarity index 61% rename from lib/hero/heromodels/comment.v rename to lib/schemas/openrpcserver/comment.v index c2aaa6d3..3d55c30d 100644 --- a/lib/hero/heromodels/comment.v +++ b/lib/schemas/openrpcserver/comment.v @@ -1,6 +1,5 @@ -module heromodels +module openrpcserver -import freeflowuniverse.herolib.core.redisclient import freeflowuniverse.herolib.data.encoder import freeflowuniverse.herolib.data.ourtime @@ -55,21 +54,47 @@ pub fn comment_load(data []u8) !Comment{ pub struct CommentArg { pub mut: - comment string - parent u32 //id of parent comment if any, 0 means none - author u32 //links to user + comment string + parent u32 + author u32 } +pub fn comment_multiset(args []CommentArg) ![]u32 { + return comments2ids(args)! +} + +pub fn comments2ids(args []CommentArg) ![]u32 { + return args.map(comment2id(it.comment)!) +} + +pub fn comment2id(comment string) !u32 { + comment_fixed := comment.to_lower_ascii().trim_space() + mut redis := redisclient.core_get()! + return if comment_fixed.len > 0{ + hash := md5.hexhash(comment_fixed) + comment_found := redis.hget("db:comments", hash)! + if comment_found == ""{ + id := u32(redis.incr("db:comments:id")!) + redis.hset("db:comments", hash, id.str())! + redis.hset("db:comments", id.str(), comment_fixed)! + id + }else{ + comment_found.u32() + } + } else { 0 } +} + + //get new comment, not from the DB pub fn comment_new(args CommentArg) !Comment{ - mut o:=Comment { + mut o := Comment { comment: args.comment - parent:args.parent + parent: args.parent updated_at: ourtime.now().unix() author: args.author } return o -} +} pub fn comment_multiset(args []CommentArg) ![]u32{ mut ids := []u32{} @@ -79,29 +104,16 @@ pub fn comment_multiset(args []CommentArg) ![]u32{ return ids } - pub fn comment_set(args CommentArg) !u32{ - mut redis := redisclient.core_get()! - mut o:=comment_new(args)! - myid := redis.incr("db:comments:id")! - o.id = u32(myid) - data := o.dump()! - redis.hset("db:comments:data", myid.str(), data.bytestr())! - return o.id + mut o := comment_new(args)! + // Use openrpcserver set function which now returns the ID + return openrpcserver.set[Comment](mut o)! } pub fn comment_exist(id u32) !bool{ - mut redis := redisclient.core_get()! - return redis.hexists("db:comments:data", id.str())! + return openrpcserver.exists[Comment](id)! } pub fn comment_get(id u32) !Comment{ - mut redis := redisclient.core_get()! - mut data:= redis.hget("db:comments:data", id.str())! - if data.len>0{ - return comment_load(data.bytes())! - }else{ - return error("Can't find comment with id: ${id}") - } - + return openrpcserver.get[Comment](id)! } diff --git a/lib/schemas/openrpcserver/core_methods.v b/lib/schemas/openrpcserver/core_methods.v index 85d4d2d7..6688c8a3 100644 --- a/lib/schemas/openrpcserver/core_methods.v +++ b/lib/schemas/openrpcserver/core_methods.v @@ -2,12 +2,19 @@ module openrpcserver import freeflowuniverse.herolib.core.redisclient -pub fn set[T](obj T) ! { +pub fn set[T](mut obj T) !u32 { name := T{}.type_name() mut redis := redisclient.core_get()! - id := obj.id + + // Generate ID if not set + if obj.id == 0 { + myid := redis.incr("db:${name}:id")! + obj.id = u32(myid) + } + data := obj.dump()! - redis.hset("db:${name}",id.str(),data.bytestr())! + redis.hset("db:${name}",obj.id.str(),data.bytestr())! + return obj.id } pub fn get[T](id u32) !T { diff --git a/lib/schemas/openrpcserver/core_models.v b/lib/schemas/openrpcserver/core_models.v index 9da97579..ea51a2bb 100644 --- a/lib/schemas/openrpcserver/core_models.v +++ b/lib/schemas/openrpcserver/core_models.v @@ -91,25 +91,3 @@ pub fn tags2id(tags []string) !u32 { 0 } } - -pub fn comments2ids(args []CommentArg) ![]u32 { - return args.map(comment2id(it.comment)!) -} - -pub fn comment2id(comment string) !u32 { - comment_fixed := comment.to_lower_ascii().trim_space() - mut redis := redisclient.core_get()! - return if comment_fixed.len > 0{ - hash := md5.hexhash(comment_fixed) - comment_found := redis.hget("db:comments", hash)! - if comment_found == ""{ - id := u32(redis.incr("db:comments:id")!) - redis.hset("db:comments", hash, id.str())! - redis.hset("db:comments", id.str(), comment_fixed)! - id - }else{ - comment_found.u32() - } - } else { 0 } -} - diff --git a/lib/schemas/openrpcserver/openrpc_server.v b/lib/schemas/openrpcserver/openrpc_server.v index 680d85db..271c6259 100644 --- a/lib/schemas/openrpcserver/openrpc_server.v +++ b/lib/schemas/openrpcserver/openrpc_server.v @@ -130,6 +130,18 @@ fn (mut server RPCServer) process_request(request_data string) !string { return server.create_success_response(result, id_str) } +// Default process method - should be overridden by implementations +pub fn (mut server RPCServer) process(method string, params_str string) !string { + return match method { + 'rpc.discover' { + server.discover()! + } + else { + server.create_error_response(-32601, 'Method not found', method) + } + } +} + fn (mut server RPCServer) create_success_response(result string, id string) string { response := JsonRpcResponse{ jsonrpc: '2.0' @@ -153,8 +165,8 @@ fn (mut server RPCServer) create_error_response(code int, message string, id str return json.encode(response) } -// discover returns the OpenRPC specification for the HeroModels service -fn (mut server RPCServer) discover() !string { - spec_json := $tmpl("openrpc.json") - return spec_json +// discover returns the OpenRPC specification for the service +pub fn (mut server RPCServer) discover() !string { + // Return a basic OpenRPC spec - should be overridden by implementations + return '{"openrpc": "1.2.6", "info": {"title": "OpenRPC Server", "version": "1.0.0"}, "methods": []}' } \ No newline at end of file