...
This commit is contained in:
@@ -1,62 +0,0 @@
|
||||
module heromodels
|
||||
|
||||
import freeflowuniverse.herolib.data.ourtime
|
||||
import time
|
||||
|
||||
// Calendar represents a collection of events
|
||||
@[heap]
|
||||
pub struct Calendar {
|
||||
Base
|
||||
pub mut:
|
||||
events []u32 // IDs of calendar events (changed to u32 to match CalendarEvent)
|
||||
color string // Hex color code
|
||||
timezone string
|
||||
is_public bool
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct CalendarArgs {
|
||||
BaseArgs
|
||||
pub mut:
|
||||
events []u32
|
||||
color string
|
||||
timezone string
|
||||
is_public bool
|
||||
}
|
||||
|
||||
pub fn calendar_new(args CalendarArgs) !Calendar {
|
||||
mut commentids:=[]u32{}
|
||||
mut obj := Calendar{
|
||||
id: args.id or {0} // Will be set by DB?
|
||||
name: args.name
|
||||
description: args.description
|
||||
created_at: ourtime.now().unix()
|
||||
updated_at: ourtime.now().unix()
|
||||
securitypolicy: args.securitypolicy or {0}
|
||||
tags: tags2id(args.tags)!
|
||||
comments: comments2ids(args.comments)!
|
||||
group_id: args.group_id
|
||||
events: args.events
|
||||
color: args.color
|
||||
timezone: args.timezone
|
||||
is_public: args.is_public
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
pub fn (mut c Calendar) add_event(event_id u32) { // Changed event_id to u32
|
||||
if event_id !in c.events {
|
||||
c.events << event_id
|
||||
c.updated_at = ourtime.now().unix() // Use Base's updated_at
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut c Calendar) dump() []u8 {
|
||||
// TODO: implement based on lib/data/encoder/readme.md
|
||||
return []u8{}
|
||||
}
|
||||
|
||||
pub fn calendar_load(data []u8) Calendar {
|
||||
// TODO: implement based on lib/data/encoder/readme.md
|
||||
return Calendar{}
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
module heromodels
|
||||
|
||||
import crypto.blake3
|
||||
import json
|
||||
import freeflowuniverse.herolib.data.ourtime
|
||||
import freeflowuniverse.herolib.data.encoder
|
||||
import freeflowuniverse.herolib.core.redisclient
|
||||
|
||||
// CalendarEvent represents a single event in a calendar
|
||||
@[heap]
|
||||
pub struct CalendarEvent {
|
||||
Base
|
||||
pub mut:
|
||||
title string
|
||||
start_time i64 // Unix timestamp
|
||||
end_time i64 // Unix timestamp
|
||||
location string
|
||||
attendees []u32 // IDs of user groups
|
||||
fs_items []u32 // IDs of linked files or dirs
|
||||
calendar_id u32 // Associated calendar
|
||||
status EventStatus
|
||||
is_all_day bool
|
||||
is_recurring bool
|
||||
recurrence []RecurrenceRule // normally empty
|
||||
reminder_mins []int // Minutes before event for reminders
|
||||
color string // Hex color code
|
||||
timezone string
|
||||
}
|
||||
|
||||
pub struct Attendee {
|
||||
pub mut:
|
||||
user_id u32
|
||||
status AttendanceStatus
|
||||
role AttendeeRole
|
||||
}
|
||||
|
||||
pub enum AttendanceStatus {
|
||||
no_response
|
||||
accepted
|
||||
declined
|
||||
tentative
|
||||
}
|
||||
|
||||
pub enum AttendeeRole {
|
||||
required
|
||||
optional
|
||||
organizer
|
||||
}
|
||||
|
||||
pub enum EventStatus {
|
||||
draft
|
||||
published
|
||||
cancelled
|
||||
completed
|
||||
}
|
||||
|
||||
pub struct RecurrenceRule {
|
||||
pub mut:
|
||||
frequency RecurrenceFreq
|
||||
interval int // Every N frequencies
|
||||
until i64 // End date (Unix timestamp)
|
||||
count int // Number of occurrences
|
||||
by_weekday []int // Days of week (0=Sunday)
|
||||
by_monthday []int // Days of month
|
||||
}
|
||||
|
||||
pub enum RecurrenceFreq {
|
||||
none
|
||||
daily
|
||||
weekly
|
||||
monthly
|
||||
yearly
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct CalendarEventArgs {
|
||||
BaseArgs
|
||||
pub mut:
|
||||
title string
|
||||
start_time string // use ourtime module to go from string to epoch
|
||||
end_time string // use ourtime module to go from string to epoch
|
||||
location string
|
||||
attendees []u32 // IDs of user groups
|
||||
fs_items []u32 // IDs of linked files or dirs
|
||||
calendar_id u32 // Associated calendar
|
||||
status EventStatus
|
||||
is_all_day bool
|
||||
is_recurring bool
|
||||
recurrence []RecurrenceRule
|
||||
reminder_mins []int // Minutes before event for reminders
|
||||
color string // Hex color code
|
||||
timezone string
|
||||
}
|
||||
|
||||
pub fn calendar_event_new(args CalendarEventArgs) !CalendarEvent {
|
||||
// Convert tags to u32 ID
|
||||
tags_id := tags2id(args.tags)!
|
||||
|
||||
return CalendarEvent{
|
||||
// Base fields
|
||||
id: args.id or { 0 }
|
||||
name: args.name
|
||||
description: args.description
|
||||
created_at: ourtime.now().unix()
|
||||
updated_at: ourtime.now().unix()
|
||||
securitypolicy: args.securitypolicy or { 0 }
|
||||
tags: tags_id
|
||||
comments: comments2ids(args.comments)!
|
||||
|
||||
// CalendarEvent specific fields
|
||||
title: args.title
|
||||
start_time: ourtime.new(args.start_time)!.unix()
|
||||
end_time: ourtime.new(args.end_time)!.unix()
|
||||
location: args.location
|
||||
attendees: args.attendees
|
||||
fs_items: args.fs_items
|
||||
calendar_id: args.calendar_id
|
||||
status: args.status
|
||||
is_all_day: args.is_all_day
|
||||
is_recurring: args.is_recurring
|
||||
recurrence: args.recurrence
|
||||
reminder_mins: args.reminder_mins
|
||||
color: args.color
|
||||
timezone: args.timezone
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut e CalendarEvent) dump() ![]u8 {
|
||||
// Create a new encoder
|
||||
mut enc := encoder.new()
|
||||
|
||||
// Add version byte
|
||||
enc.add_u8(1)
|
||||
|
||||
// Encode Base fields
|
||||
enc.add_u32(e.id)
|
||||
enc.add_string(e.name)
|
||||
enc.add_string(e.description)
|
||||
enc.add_i64(e.created_at)
|
||||
enc.add_i64(e.updated_at)
|
||||
enc.add_u32(e.securitypolicy)
|
||||
enc.add_u32(e.tags)
|
||||
enc.add_list_u32(e.comments)
|
||||
|
||||
// Encode CalendarEvent specific fields
|
||||
enc.add_string(e.title)
|
||||
enc.add_string(e.description)
|
||||
enc.add_i64(e.start_time)
|
||||
enc.add_i64(e.end_time)
|
||||
enc.add_string(e.location)
|
||||
enc.add_list_u32(e.attendees)
|
||||
enc.add_list_u32(e.fs_items)
|
||||
enc.add_u32(e.calendar_id)
|
||||
enc.add_u8(u8(e.status))
|
||||
enc.add_bool(e.is_all_day)
|
||||
enc.add_bool(e.is_recurring)
|
||||
|
||||
// Encode recurrence array
|
||||
enc.add_u16(u16(e.recurrence.len))
|
||||
for rule in e.recurrence {
|
||||
enc.add_u8(u8(rule.frequency))
|
||||
enc.add_int(rule.interval)
|
||||
enc.add_i64(rule.until)
|
||||
enc.add_int(rule.count)
|
||||
enc.add_list_int(rule.by_weekday)
|
||||
enc.add_list_int(rule.by_monthday)
|
||||
}
|
||||
|
||||
enc.add_list_int(e.reminder_mins)
|
||||
enc.add_string(e.color)
|
||||
enc.add_string(e.timezone)
|
||||
|
||||
return enc.data
|
||||
}
|
||||
|
||||
pub fn (ce CalendarEvent) load(data []u8) !CalendarEvent {
|
||||
// Create a new decoder
|
||||
mut dec := encoder.decoder_new(data)
|
||||
|
||||
// Read version byte
|
||||
version := dec.get_u8()!
|
||||
if version != 1 {
|
||||
return error('wrong version in calendar event load')
|
||||
}
|
||||
|
||||
// Decode Base fields
|
||||
id := dec.get_u32()!
|
||||
name := dec.get_string()!
|
||||
description := dec.get_string()!
|
||||
created_at := dec.get_i64()!
|
||||
updated_at := dec.get_i64()!
|
||||
securitypolicy := dec.get_u32()!
|
||||
tags := dec.get_u32()!
|
||||
comments := dec.get_list_u32()!
|
||||
|
||||
// Decode CalendarEvent specific fields
|
||||
title := dec.get_string()!
|
||||
description2 := dec.get_string()! // Second description field
|
||||
start_time := dec.get_i64()!
|
||||
end_time := dec.get_i64()!
|
||||
location := dec.get_string()!
|
||||
attendees := dec.get_list_u32()!
|
||||
fs_items := dec.get_list_u32()!
|
||||
calendar_id := dec.get_u32()!
|
||||
status := unsafe { EventStatus(dec.get_u8()!) }
|
||||
is_all_day := dec.get_bool()!
|
||||
is_recurring := dec.get_bool()!
|
||||
|
||||
// Decode recurrence array
|
||||
recurrence_len := dec.get_u16()!
|
||||
mut recurrence := []RecurrenceRule{}
|
||||
for _ in 0 .. recurrence_len {
|
||||
frequency := unsafe { RecurrenceFreq(dec.get_u8()!) }
|
||||
interval := dec.get_int()!
|
||||
until := dec.get_i64()!
|
||||
count := dec.get_int()!
|
||||
by_weekday := dec.get_list_int()!
|
||||
by_monthday := dec.get_list_int()!
|
||||
|
||||
recurrence << RecurrenceRule{
|
||||
frequency: frequency
|
||||
interval: interval
|
||||
until: until
|
||||
count: count
|
||||
by_weekday: by_weekday
|
||||
by_monthday: by_monthday
|
||||
}
|
||||
}
|
||||
|
||||
reminder_mins := dec.get_list_int()!
|
||||
color := dec.get_string()!
|
||||
timezone := dec.get_string()!
|
||||
|
||||
return CalendarEvent{
|
||||
// Base fields
|
||||
id: id
|
||||
name: name
|
||||
description: description
|
||||
created_at: created_at
|
||||
updated_at: updated_at
|
||||
securitypolicy: securitypolicy
|
||||
tags: tags
|
||||
comments: comments
|
||||
|
||||
// CalendarEvent specific fields
|
||||
title: title
|
||||
start_time: start_time
|
||||
end_time: end_time
|
||||
location: location
|
||||
attendees: attendees
|
||||
fs_items: fs_items
|
||||
calendar_id: calendar_id
|
||||
status: status
|
||||
is_all_day: is_all_day
|
||||
is_recurring: is_recurring
|
||||
recurrence: recurrence
|
||||
reminder_mins: reminder_mins
|
||||
color: color
|
||||
timezone: timezone
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
module heromodels
|
||||
|
||||
import freeflowuniverse.herolib.data.encoder
|
||||
import crypto.md5
|
||||
import freeflowuniverse.herolib.core.redisclient
|
||||
import freeflowuniverse.herolib.data.ourtime
|
||||
|
||||
|
||||
@[heap]
|
||||
pub struct Comment {
|
||||
Base
|
||||
pub mut:
|
||||
// id u32
|
||||
comment string
|
||||
parent u32 //id of parent comment if any, 0 means none
|
||||
updated_at i64
|
||||
author u32 //links to user
|
||||
}
|
||||
|
||||
pub fn (self Comment) type_name() string {
|
||||
return 'comments'
|
||||
}
|
||||
|
||||
pub fn (self Comment) load(data []u8) !Comment {
|
||||
return comment_load(data)!
|
||||
}
|
||||
|
||||
pub fn (self Comment) dump() ![]u8{
|
||||
// Create a new encoder
|
||||
mut e := encoder.new()
|
||||
e.add_u8(1)
|
||||
e.add_u32(self.id)
|
||||
e.add_string(self.comment)
|
||||
e.add_u32(self.parent)
|
||||
e.add_i64(self.updated_at)
|
||||
e.add_u32(self.author)
|
||||
return e.data
|
||||
}
|
||||
|
||||
pub fn comment_load(data []u8) !Comment{
|
||||
// Create a new decoder
|
||||
mut e := encoder.decoder_new(data)
|
||||
version := e.get_u8()!
|
||||
if version != 1 {
|
||||
panic("wrong version in comment load")
|
||||
}
|
||||
mut comment := Comment{}
|
||||
comment.id = e.get_u32()!
|
||||
comment.comment = e.get_string()!
|
||||
comment.parent = e.get_u32()!
|
||||
comment.updated_at = e.get_i64()!
|
||||
comment.author = e.get_u32()!
|
||||
return comment
|
||||
}
|
||||
|
||||
|
||||
pub struct CommentArg {
|
||||
pub mut:
|
||||
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 {
|
||||
comment: args.comment
|
||||
parent: args.parent
|
||||
updated_at: ourtime.now().unix()
|
||||
author: args.author
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
pub fn comment_set(args CommentArg) !u32{
|
||||
mut o := comment_new(args)!
|
||||
// Use openrpcserver set function which now returns the ID
|
||||
return set[Comment](mut o)!
|
||||
}
|
||||
|
||||
pub fn comment_delete(id u32) ! {
|
||||
delete[Comment](id)!
|
||||
}
|
||||
|
||||
pub fn comment_exist(id u32) !bool{
|
||||
return exists[Comment](id)!
|
||||
}
|
||||
|
||||
pub fn comment_get(id u32) !Comment{
|
||||
return get[Comment](id)!
|
||||
}
|
||||
@@ -116,7 +116,7 @@ fn (mut self DBCalendarEvent) load(mut o CalendarEvent, mut e &encoder.Decoder)
|
||||
o.attendees = e.get_list_u32()!
|
||||
o.fs_items = e.get_list_u32()!
|
||||
o.calendar_id = e.get_u32()!
|
||||
o.status = unsafe { EventStatus(e.get_u8()!) }
|
||||
o.status = unsafe { EventStatus(e.get_u8()!) } //TODO: is there no better way?
|
||||
o.is_all_day = e.get_bool()!
|
||||
o.is_recurring = e.get_bool()!
|
||||
|
||||
|
||||
81
lib/hero/heromodels/group.v
Normal file
81
lib/hero/heromodels/group.v
Normal file
@@ -0,0 +1,81 @@
|
||||
module heromodels
|
||||
|
||||
import time
|
||||
import crypto.blake3
|
||||
import json
|
||||
|
||||
// Group represents a collection of users with roles and permissions
|
||||
@[heap]
|
||||
pub struct Group {
|
||||
pub mut:
|
||||
id string // blake192 hash
|
||||
name string
|
||||
description string
|
||||
members []GroupMember
|
||||
subgroups []string // IDs of child groups
|
||||
parent_group string // ID of parent group
|
||||
created_at i64
|
||||
updated_at i64
|
||||
is_public bool
|
||||
tags []string
|
||||
}
|
||||
|
||||
pub struct GroupMember {
|
||||
pub mut:
|
||||
user_id string
|
||||
role GroupRole
|
||||
joined_at i64
|
||||
}
|
||||
|
||||
pub enum GroupRole {
|
||||
reader
|
||||
writer
|
||||
admin
|
||||
owner
|
||||
}
|
||||
|
||||
pub fn (mut g Group) calculate_id() {
|
||||
content := json.encode(GroupContent{
|
||||
name: g.name
|
||||
description: g.description
|
||||
members: g.members
|
||||
subgroups: g.subgroups
|
||||
parent_group: g.parent_group
|
||||
is_public: g.is_public
|
||||
tags: g.tags
|
||||
})
|
||||
hash := blake3.sum256(content.bytes())
|
||||
g.id = hash.hex()[..48]
|
||||
}
|
||||
|
||||
struct GroupContent {
|
||||
name string
|
||||
description string
|
||||
members []GroupMember
|
||||
subgroups []string
|
||||
parent_group string
|
||||
is_public bool
|
||||
tags []string
|
||||
}
|
||||
|
||||
pub fn new_group(name string, description string) Group {
|
||||
mut group := Group{
|
||||
name: name
|
||||
description: description
|
||||
created_at: time.now().unix()
|
||||
updated_at: time.now().unix()
|
||||
is_public: false
|
||||
}
|
||||
group.calculate_id()
|
||||
return group
|
||||
}
|
||||
|
||||
pub fn (mut g Group) add_member(user_id string, role GroupRole) {
|
||||
g.members << GroupMember{
|
||||
user_id: user_id
|
||||
role: role
|
||||
joined_at: time.now().unix()
|
||||
}
|
||||
g.updated_at = time.now().unix()
|
||||
g.calculate_id()
|
||||
}
|
||||
Reference in New Issue
Block a user