...
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
//#!/usr/bin/env -S v -cg -enable-globals run
|
||||
import freeflowuniverse.herolib.biz.bizmodel
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.core.playcmds
|
||||
import os
|
||||
|
||||
const playbook_path = os.dir(@FILE) + '/playbook'
|
||||
@@ -11,9 +8,7 @@ const build_path = os.join_path(os.dir(@FILE), '/docusaurus')
|
||||
|
||||
buildpath := '${os.home_dir()}/hero/var/mdbuild/bizmodel'
|
||||
|
||||
mut model := bizmodel.getset("example")!
|
||||
model.workdir = build_path
|
||||
model.play(mut playbook.new(path: playbook_path)!)!
|
||||
mut model := bizmodel.generate("test", playbook_path)!
|
||||
|
||||
println(model.sheet)
|
||||
println(model.sheet.export()!)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
module biz
|
||||
1
lib/biz/bizmodel/.gitignore
vendored
1
lib/biz/bizmodel/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
testdata
|
||||
31
lib/biz/bizmodel/exampledata/cost_centers.md
Normal file
31
lib/biz/bizmodel/exampledata/cost_centers.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# HR Params
|
||||
|
||||
## Engineering
|
||||
|
||||
Costs can be grouped in cost centers which can then be used to futher process e.g. transcactions between companies.
|
||||
|
||||
```js
|
||||
|
||||
!!bizmodel.costcenter_define bizname:'test'
|
||||
name:'tfdmcc'
|
||||
descr:'TFDMCC executes on near source agreement for TFTech'
|
||||
min_month:'10000USD'
|
||||
max_month:'100000USD'
|
||||
end_date:'1/1/2026' //when does agreement stop
|
||||
|
||||
!!bizmodel.costcenter_define bizname:'test'
|
||||
name:'cs_tftech'
|
||||
descr:'Nearsource agreement for TFTech towards Codescalers'
|
||||
min_month:'10000USD'
|
||||
max_month:'100000USD'
|
||||
end_date:'1/1/2026'
|
||||
|
||||
!!bizmodel.costcenter_define bizname:'test'
|
||||
name:'cs_tfcloud'
|
||||
descr:'Nearsource agreement for TFCloud towards Codescalers'
|
||||
min_month:'10000USD'
|
||||
max_month:'100000USD'
|
||||
end_date:'1/1/2026'
|
||||
|
||||
|
||||
```
|
||||
39
lib/biz/bizmodel/exampledata/costs_params.md
Normal file
39
lib/biz/bizmodel/exampledata/costs_params.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Generic Overhead Costs
|
||||
|
||||
possible parameters
|
||||
|
||||
- name
|
||||
- descr: description of the cost
|
||||
- cost: is 'month:amount,month:amount, ...', no extrapolation
|
||||
- cost_growth: is 'month:amount,month:amount, ..., or just a nr', will extrapolate
|
||||
- type: travel, admin, legal, varia, office
|
||||
- cost_percent_revenue e.g. 4%, will make sure the cost will be at least 4% of revenue
|
||||
- indexation, e.g. 2%
|
||||
|
||||
Other financial flows can be mentioned here as well.
|
||||
|
||||
|
||||
```js
|
||||
!!bizmodel.cost_define bizname:'test'
|
||||
name:'rental'
|
||||
descr:'Office Rental in BE.'
|
||||
cost:'5000'
|
||||
indexation:'2%'
|
||||
type:'office'
|
||||
|
||||
!!bizmodel.cost_define bizname:'test'
|
||||
name:'oneoff'
|
||||
descr:'Event in Z.'
|
||||
cost_one:'3:50000'
|
||||
type:'event'
|
||||
|
||||
!!bizmodel.cost_define bizname:'test'
|
||||
name:'cloud'
|
||||
descr:'Datacenter and Cloud Costs'
|
||||
cost:'2000eur'
|
||||
cost_percent_revenue:'2%'
|
||||
type:'cloud'
|
||||
|
||||
|
||||
```
|
||||
|
||||
20
lib/biz/bizmodel/exampledata/department_params.md
Normal file
20
lib/biz/bizmodel/exampledata/department_params.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Department Params
|
||||
|
||||
```js
|
||||
|
||||
!!bizmodel.department_define bizname:'test'
|
||||
name:'ops'
|
||||
title:'Operations'
|
||||
order:5
|
||||
|
||||
!!bizmodel.department_define bizname:'test'
|
||||
name:'coordination'
|
||||
title:'Coordination'
|
||||
order:1
|
||||
|
||||
!!bizmodel.department_define bizname:'test'
|
||||
name:'engineering'
|
||||
title:'Engineering'
|
||||
order:4
|
||||
|
||||
```
|
||||
29
lib/biz/bizmodel/exampledata/funding_params.md
Normal file
29
lib/biz/bizmodel/exampledata/funding_params.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Funding Params
|
||||
|
||||
possible parameters
|
||||
|
||||
- name, e.g. for a specific person
|
||||
- descr: description of the funding
|
||||
- investment is month:amount,month:amount, ...
|
||||
- type: loan or capital
|
||||
|
||||
Other financial flows can be mentioned here as well.
|
||||
|
||||
|
||||
```js
|
||||
!!bizmodel.funding_define bizname:'test'
|
||||
name:'our_investor'
|
||||
descr:'A fantastic super investor.'
|
||||
investment:'3:1000000EUR'
|
||||
type:'capital'
|
||||
|
||||
!!bizmodel.funding_define bizname:'test'
|
||||
name:'a_founder'
|
||||
descr:'Together Are Strong'
|
||||
investment:'2000000'
|
||||
type:'loan'
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
73
lib/biz/bizmodel/exampledata/hr_params.md
Normal file
73
lib/biz/bizmodel/exampledata/hr_params.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# HR Params
|
||||
|
||||
## Engineering
|
||||
|
||||
possible parameters
|
||||
|
||||
- descr, description of the function (e.g. master architect)
|
||||
- cost, any currency eg. 1000usd
|
||||
- in case cost changes over time e.g. 1:10000USD,20:20000USD,60:30000USD
|
||||
- indexation, e.g. 2%
|
||||
- department
|
||||
- name, e.g. for a specific person
|
||||
- nrpeople: how many people per month, growth over time notation e.g. 1:10,60:20 means 10 in month 1 growing to 20 month 60
|
||||
- cost_percent_revenue e.g. 4%, will make sure the cost will be at least 4% of revenue
|
||||
|
||||
```js
|
||||
|
||||
!!bizmodel.employee_define bizname:'test'
|
||||
sid:2
|
||||
descr:'Senior Engineer'
|
||||
cost:'1:12000,12:14000' //cost is always per person
|
||||
department:'engineering'
|
||||
nrpeople:'0:5,20:5'
|
||||
|
||||
!!bizmodel.employee_define bizname:'test'
|
||||
name:'despiegk'
|
||||
title: 'CTO and crazy inventor.'
|
||||
sid:3
|
||||
descr:'CTO'
|
||||
cost:'12000EUR' //the salary is the cost independent of the fulltime status
|
||||
indexation:'10%'
|
||||
department:'coordination'
|
||||
page:'cto.md'
|
||||
fulltime: "50%" //100% means yes
|
||||
|
||||
!!bizmodel.employee_define bizname:'test'
|
||||
descr:'Senior Architect'
|
||||
cost:'10000USD' indexation:'5%'
|
||||
department:'engineering'
|
||||
nrpeople:'0:5,20:10'
|
||||
|
||||
!!bizmodel.employee_define bizname:'test'
|
||||
descr:'Junior Engineer'
|
||||
cost:'4000USD' indexation:'5%'
|
||||
department:'engineering'
|
||||
nrpeople:'0:5,20:10'
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Operations
|
||||
|
||||
```js
|
||||
|
||||
!!bizmodel.employee_define bizname:'test'
|
||||
descr:'Ops Manager'
|
||||
cost:'1:8000,12:14000'
|
||||
department:'ops'
|
||||
!!bizmodel.employee_define bizname:'test'
|
||||
descr:'Support Junior'
|
||||
cost:'2000EUR' indexation:'5%'
|
||||
department:'ops'
|
||||
nrpeople:'7:5,18:10'
|
||||
cost_percent_revenue:'1%'
|
||||
!!bizmodel.employee_define bizname:'test'
|
||||
descr:'Support Senior'
|
||||
cost:'5000EUR' indexation:'5%'
|
||||
department:'ops'
|
||||
nrpeople:'3:5,20:10'
|
||||
cost_percent_revenue:'1%'
|
||||
costcenter:'tfdmcc:25,cs_tfcloud:75'
|
||||
generate_page:'../employees/support_senior.md'
|
||||
```
|
||||
14
lib/biz/bizmodel/exampledata/params.md
Normal file
14
lib/biz/bizmodel/exampledata/params.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Bizmodel Params
|
||||
|
||||
In this section we can find all the parameters for the bizmodel.
|
||||
|
||||
## how to use and read
|
||||
|
||||
The params are defined in the different instruction files e.g. revenue_params.md
|
||||
|
||||
Often you will see something like `revenue_growth:'10:1000,20:1100'` this can be read as month 10 it 1000, month 20 its 1100.
|
||||
|
||||
The software will extrapolate.
|
||||
|
||||
|
||||
|
||||
85
lib/biz/bizmodel/exampledata/revenue_params.md
Normal file
85
lib/biz/bizmodel/exampledata/revenue_params.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# HR Params
|
||||
|
||||
## Revenue Items (non recurring)
|
||||
|
||||
This company is a cloud company ...
|
||||
|
||||
- name, e.g. for a specific project
|
||||
- descr, description of the revenue line item
|
||||
- revenue_items: does one of revenue, is not exterpolated
|
||||
- revenue_growth: is a revenue stream which is being extrapolated
|
||||
- revenue_setup, revenue for 1 item '1000usd'
|
||||
- revenue_setup_delay
|
||||
- revenue_monthly, revenue per month for 1 item
|
||||
- revenue_monthly_delay, how many months before monthly revenue starts
|
||||
- maintenance_month_perc, how much percent of revenue_setup will come back over months
|
||||
- cogs_setup, cost of good for 1 item at setup
|
||||
- cogs_setup_delay, how many months before setup cogs starts, after sales
|
||||
- cogs_setup_perc: what is percentage of the cogs (can change over time) for setup e.g. 0:50%
|
||||
|
||||
- cogs_monthly, cost of goods for the monthly per 1 item
|
||||
- cogs_monthly_delay, how many months before monthly cogs starts, after sales
|
||||
- cogs_monthly_perc: what is percentage of the cogs (can change over time) for monthly e.g. 0:5%,12:10%
|
||||
|
||||
- nr_sold: how many do we sell per month (is in growth format e.g. 10:100,20:200, default is 1)
|
||||
- nr_months_recurring: how many months is recurring, if 0 then no recurring
|
||||
|
||||
```js
|
||||
!!bizmodel.revenue_define bizname:'test'
|
||||
descr:'OEM Deals'
|
||||
revenue_items:'10:1000000EUR,15:3333,20:1200000'
|
||||
cogs_setup_perc: '1:5%,20:10%'
|
||||
|
||||
!!bizmodel.revenue_define bizname:'test'
|
||||
descr:'License Deals'
|
||||
revenue_growth:'10:1000,20:1100'
|
||||
cogs_perc: '10%'
|
||||
rev_delay_month: 1
|
||||
|
||||
!!bizmodel.revenue_define bizname:'test'
|
||||
descr:'3NODE License Sales 1 Time'
|
||||
//means revenue is 100 month 1, 200 month 60
|
||||
revenue_item:'1:100,60:200'
|
||||
revenue_nr:'10:1000,24:2000,60:40000'
|
||||
cogs_perc: '10%'
|
||||
rev_delay_month: 1
|
||||
|
||||
```
|
||||
|
||||
## Revenue Items Recurring
|
||||
|
||||
possible parameters
|
||||
|
||||
- name, e.g. for a specific project
|
||||
- descr, description of the revenue line item
|
||||
- revenue_setup, revenue for 1 item '1000usd'
|
||||
- revenue_monthly, revenue per month for 1 item
|
||||
- revenue_setup_delay, how many months before revenue comes in after sales
|
||||
- revenue_monthly_delay, how many months before monthly revenue starts
|
||||
- cogs_setup, cost of good for 1 item at setup
|
||||
- cogs_setup_perc: what is percentage of the cogs (can change over time) for setup e.g. 0:50%
|
||||
- cogs_monthly, cost of goods for the monthly per 1 item
|
||||
- cogs_monthly_perc: what is percentage of the cogs (can change over time) for monthly e.g. 0:5%,12:10%
|
||||
- nr_sold: how many do we sell per month (is in growth format e.g. 10:100,20:200)
|
||||
- nr_months: how many months is recurring
|
||||
|
||||
if currency not specified then is always in USD
|
||||
|
||||
```js
|
||||
|
||||
!!bizmodel.revenue_recurring_define bizname:'test'
|
||||
name: '3node_lic'
|
||||
descr:'3NODE License Sales Recurring Basic'
|
||||
revenue_setup:'1:100,60:50'
|
||||
// revenue_setup:'5'
|
||||
revenue_monthly_delay:3
|
||||
revenue_monthly:'1:1,60:1'
|
||||
// cogs_setup:'1:0'
|
||||
cogs_setup_perc:'50%'
|
||||
revenue_setup_delay:1
|
||||
cogs_monthly_perc:'50%'
|
||||
nr_sold:'10:1000,24:2000,60:40000'
|
||||
60 is the default
|
||||
nr_months:60
|
||||
```
|
||||
|
||||
90
lib/biz/bizmodel/export_csv.v
Normal file
90
lib/biz/bizmodel/export_csv.v
Normal file
@@ -0,0 +1,90 @@
|
||||
module bizmodel
|
||||
|
||||
import os
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
|
||||
@[params]
|
||||
pub struct ExportCSVArgs {
|
||||
pub mut:
|
||||
path string
|
||||
include_empty bool = false // whether to include empty cells or not
|
||||
separator string = '|' // separator character for CSV
|
||||
}
|
||||
|
||||
// export_csv exports the business model data to CSV files
|
||||
pub fn (model BizModel) export_csv(args ExportCSVArgs) ! {
|
||||
mut path := args.path
|
||||
if path == '' {
|
||||
path = os.join_path(os.home_dir(), 'hero/var/bizmodel/exports')
|
||||
}
|
||||
mut dir := pathlib.get_dir(path: path, create: true)!
|
||||
|
||||
// Export employees data
|
||||
mut employees_data := []string{}
|
||||
header := ['Name', 'Role', 'Department', 'Cost', 'Start Date'].map(fn [args] (s string) string {
|
||||
return format_csv_value(s, args.separator)
|
||||
}).join(args.separator)
|
||||
employees_data << header
|
||||
|
||||
for _, employee in model.employees {
|
||||
row := [
|
||||
employee.name,
|
||||
employee.role,
|
||||
employee.department,
|
||||
employee.cost.str(),
|
||||
if start_date := employee.start_date { start_date.str() } else { '' }
|
||||
].map(fn [args] (s string) string {
|
||||
return format_csv_value(s, args.separator)
|
||||
}).join(args.separator)
|
||||
employees_data << row
|
||||
}
|
||||
mut emp_file := pathlib.get_file(path: os.join_path(dir.path, 'employees.csv'), create: true, delete: true)!
|
||||
emp_file.write(employees_data.join('\n'))!
|
||||
|
||||
// Export products data
|
||||
mut products_data := []string{}
|
||||
products_header := ['Name', 'Description'].map(fn [args] (s string) string {
|
||||
return format_csv_value(s, args.separator)
|
||||
}).join(args.separator)
|
||||
products_data << products_header
|
||||
|
||||
for _, product in model.products {
|
||||
row := [
|
||||
product.name,
|
||||
product.description,
|
||||
].map(fn [args] (s string) string {
|
||||
return format_csv_value(s, args.separator)
|
||||
}).join(args.separator)
|
||||
products_data << row
|
||||
}
|
||||
mut prod_file := pathlib.get_file(path: os.join_path(dir.path, 'products.csv'), create: true, delete: true)!
|
||||
prod_file.write(products_data.join('\n'))!
|
||||
|
||||
// Export departments data
|
||||
mut departments_data := []string{}
|
||||
departments_header := ['Name', 'Description'].map(fn [args] (s string) string {
|
||||
return format_csv_value(s, args.separator)
|
||||
}).join(args.separator)
|
||||
departments_data << departments_header
|
||||
|
||||
for _, department in model.departments {
|
||||
row := [
|
||||
department.name,
|
||||
department.description
|
||||
].map(fn [args] (s string) string {
|
||||
return format_csv_value(s, args.separator)
|
||||
}).join(args.separator)
|
||||
departments_data << row
|
||||
}
|
||||
mut dept_file := pathlib.get_file(path: os.join_path(dir.path, 'departments.csv'), create: true, delete: true)!
|
||||
dept_file.write(departments_data.join('\n'))!
|
||||
}
|
||||
|
||||
// format_csv_value formats a value for CSV export, handling special characters
|
||||
fn format_csv_value(val string, separator string) string {
|
||||
// If value contains the separator, quotes, or newlines, wrap in quotes and escape quotes
|
||||
if val.contains(separator) || val.contains('"') || val.contains('\n') {
|
||||
return '"${val.replace('"', '""')}"'
|
||||
}
|
||||
return val
|
||||
}
|
||||
36
lib/biz/bizmodel/export_csv_test.vsh
Executable file
36
lib/biz/bizmodel/export_csv_test.vsh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env -S v -n -w -cg -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import os
|
||||
import freeflowuniverse.herolib.biz.bizmodel
|
||||
|
||||
bizmodel_name := 'test'
|
||||
export_path := '${os.home_dir}/Downloads/bizmodel'
|
||||
playbook_path := os.dir(@FILE) + '/exampledata'
|
||||
|
||||
mut model := bizmodel.generate(bizmodel_name, playbook_path)!
|
||||
|
||||
// Export to CSV
|
||||
model.export_csv(
|
||||
path: export_path
|
||||
include_empty: false
|
||||
separator: '|'
|
||||
)!
|
||||
|
||||
// // Verify files were created
|
||||
// employees_path := os.join_path(export_path, 'employees.csv')
|
||||
// products_path := os.join_path(export_path, 'products.csv')
|
||||
// departments_path := os.join_path(export_path, 'departments.csv')
|
||||
|
||||
// assert os.exists(employees_path), 'employees.csv should exist'
|
||||
// assert os.exists(products_path), 'products.csv should exist'
|
||||
// assert os.exists(departments_path), 'departments.csv should exist'
|
||||
|
||||
// // Read and verify content
|
||||
// employees_content := os.read_file(employees_path)!
|
||||
// assert employees_content.contains('Name|Role|Department|Cost|Start Date'), 'employees.csv should have correct header'
|
||||
|
||||
// products_content := os.read_file(products_path)!
|
||||
// assert products_content.contains('Name|Description|Price|Cost'), 'products.csv should have correct header'
|
||||
|
||||
// departments_content := os.read_file(departments_path)!
|
||||
// assert departments_content.contains('Name|Description|Budget'), 'departments.csv should have correct header'
|
||||
@@ -4,7 +4,7 @@ import os
|
||||
import freeflowuniverse.herolib.web.docusaurus
|
||||
|
||||
const bizmodel_name = 'test'
|
||||
const export_path = os.join_path(os.dir(@FILE), 'testdata')
|
||||
const export_path = os.join_path(os.dir(@FILE), 'exampledata')
|
||||
|
||||
pub fn test_export_report() ! {
|
||||
model := getset(bizmodel_name)!
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module bizmodel
|
||||
|
||||
import freeflowuniverse.herolib.biz.spreadsheet
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
|
||||
__global (
|
||||
bizmodels shared map[string]&BizModel
|
||||
@@ -32,6 +33,16 @@ pub fn getset(name string) !&BizModel {
|
||||
panic('bug')
|
||||
}
|
||||
|
||||
|
||||
pub fn generate(name string, path string) !&BizModel {
|
||||
mut model:=getset(name)!
|
||||
mut pb := playbook.new(path: path)!
|
||||
model.play(mut pb)!
|
||||
return model
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn set(bizmodel BizModel) {
|
||||
lock bizmodels {
|
||||
bizmodels[bizmodel.name] = &bizmodel
|
||||
|
||||
@@ -2,6 +2,7 @@ module bizmodel
|
||||
|
||||
import os
|
||||
import freeflowuniverse.herolib.biz.spreadsheet
|
||||
import freeflowuniverse.herolib.data.ourtime
|
||||
|
||||
pub struct BizModel {
|
||||
pub mut:
|
||||
@@ -21,6 +22,7 @@ pub:
|
||||
description string
|
||||
title string
|
||||
department string
|
||||
role string
|
||||
cost string
|
||||
cost_percent_revenue f64
|
||||
nrpeople string
|
||||
@@ -28,6 +30,7 @@ pub:
|
||||
cost_center string
|
||||
page string
|
||||
fulltime_perc f64
|
||||
start_date ?ourtime.OurTime
|
||||
}
|
||||
|
||||
pub struct Department {
|
||||
|
||||
@@ -33,10 +33,18 @@ pub fn play(mut plbook PlayBook) ! {
|
||||
pub fn (mut m BizModel) play(mut plbook PlayBook) ! {
|
||||
mut actions := plbook.actions_find(actor: 'bizmodel')!
|
||||
|
||||
|
||||
for action in actions.filter(it.name in action_priorities[0]) {
|
||||
console.print_debug(action)
|
||||
m.act(*action)!
|
||||
}
|
||||
|
||||
if true{
|
||||
println(actions)
|
||||
exit(0)
|
||||
}
|
||||
|
||||
|
||||
m.cost_total()!
|
||||
m.revenue_total()!
|
||||
m.funding_total()!
|
||||
|
||||
@@ -15,7 +15,38 @@ If we have 60 months representation (5 year), we have 60 columns
|
||||
|
||||
A sheet can also be represented per year or per quarter, if per year then there would be 5 columns only.
|
||||
|
||||
There is also functionality to export a sheet to wiki (markdown) or html representation.
|
||||
There is also functionality to export a sheet to wiki (markdown), html representation, or CSV format.
|
||||
|
||||
## Exporting to CSV
|
||||
|
||||
You can export sheet data to CSV format with pipe separation (or custom separator) using the `export_csv` method:
|
||||
|
||||
```v
|
||||
// Create a sheet
|
||||
mut sheet := sheet_new(name: 'my_sheet', nrcol: 12)!
|
||||
|
||||
// Add rows and data to the sheet
|
||||
// ...
|
||||
|
||||
// Export to a CSV file with default pipe separator
|
||||
sheet.export_csv(path: '~/output.csv')!
|
||||
|
||||
// Export with custom separator and include empty cells
|
||||
csv_content := sheet.export_csv(
|
||||
path: '~/output.csv',
|
||||
separator: ',',
|
||||
include_empty: true
|
||||
)!
|
||||
|
||||
// Export to string only (no file)
|
||||
csv_string := sheet.export_csv(path: '')!
|
||||
```
|
||||
|
||||
The CSV export includes the following features:
|
||||
- Default pipe (`|`) separator (configurable)
|
||||
- Proper handling of special characters in text fields
|
||||
- Option to include or exclude empty cells
|
||||
- Automatic formatting of numeric values
|
||||
|
||||
## offline
|
||||
|
||||
|
||||
81
lib/biz/spreadsheet/sheet_export_csv.v
Normal file
81
lib/biz/spreadsheet/sheet_export_csv.v
Normal file
@@ -0,0 +1,81 @@
|
||||
module spreadsheet
|
||||
|
||||
import os
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
|
||||
@[params]
|
||||
pub struct ExportCSVArgs {
|
||||
pub mut:
|
||||
path string
|
||||
include_empty bool = false // whether to include empty cells or not
|
||||
separator string = '|' // separator character for CSV
|
||||
}
|
||||
|
||||
// format_csv_value formats a value for CSV export, handling special characters
|
||||
fn format_csv_value(val string, separator string) string {
|
||||
// If value contains the separator, quotes, or newlines, wrap in quotes and escape quotes
|
||||
if val.contains(separator) || val.contains('"') || val.contains('\n') {
|
||||
return '"${val.replace('"', '""')}"'
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// format_number_csv formats a number for CSV export
|
||||
fn format_number_csv(val f64, include_empty bool) string {
|
||||
if val < 0.001 && val > -0.001 {
|
||||
if include_empty {
|
||||
return '0'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
if val >= 1000.0 || val <= -1000.0 {
|
||||
return int(val).str()
|
||||
}
|
||||
// Format small numbers with up to 3 decimal places, removing trailing zeros
|
||||
str := '${val:.3f}'
|
||||
// Remove trailing zeros and decimal point if needed
|
||||
if str.contains('.') {
|
||||
str_trimmed := str.trim_right('0').trim_right('.')
|
||||
return str_trimmed
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
// export_csv exports the sheet data to a CSV file with pipe separation
|
||||
pub fn (mut s Sheet) export_csv(args ExportCSVArgs) !string {
|
||||
mut result := []string{}
|
||||
mut separator := args.separator
|
||||
|
||||
// Add headers
|
||||
mut header_row := ['Name', 'Description', 'AggregateType', 'Tags', 'Subgroup']
|
||||
header_row << s.header()!
|
||||
result << header_row.map(format_csv_value(it, separator)).join(separator)
|
||||
|
||||
// Add rows
|
||||
for _, row in s.rows {
|
||||
mut row_data := [
|
||||
format_csv_value(row.name, separator),
|
||||
format_csv_value(row.description, separator),
|
||||
format_csv_value(row.aggregatetype.str(), separator),
|
||||
format_csv_value(row.tags, separator),
|
||||
format_csv_value(row.subgroup, separator)
|
||||
]
|
||||
|
||||
for cell in row.cells {
|
||||
if cell.empty && !args.include_empty {
|
||||
row_data << ''
|
||||
} else {
|
||||
val_str := format_number_csv(cell.val, args.include_empty)
|
||||
row_data << format_csv_value(val_str, separator)
|
||||
}
|
||||
}
|
||||
result << row_data.join(separator)
|
||||
}
|
||||
|
||||
if args.path.len > 0 {
|
||||
mut p := pathlib.get_file(path: args.path.replace('~', os.home_dir()), create: true, delete: true)!
|
||||
p.write(result.join('\n'))!
|
||||
}
|
||||
|
||||
return result.join('\n')
|
||||
}
|
||||
80
lib/biz/spreadsheet/sheet_export_csv_test.v
Normal file
80
lib/biz/spreadsheet/sheet_export_csv_test.v
Normal file
@@ -0,0 +1,80 @@
|
||||
module spreadsheet
|
||||
|
||||
fn test_sheet_export_csv() {
|
||||
// Create a test sheet
|
||||
mut sheet := sheet_new(name: 'test_sheet', nrcol: 12)!
|
||||
|
||||
// Add some test rows with data
|
||||
mut row1 := sheet.row_new(
|
||||
name: 'row1',
|
||||
descr: 'First test row',
|
||||
tags: 'test,row,first'
|
||||
)!
|
||||
|
||||
mut row2 := sheet.row_new(
|
||||
name: 'row2',
|
||||
descr: 'Second test row with | pipe character',
|
||||
tags: 'test,row,second'
|
||||
)!
|
||||
|
||||
// Set some cell values
|
||||
row1.cells[0].val = 10.5
|
||||
row1.cells[0].empty = false
|
||||
row1.cells[1].val = 20.75
|
||||
row1.cells[1].empty = false
|
||||
row1.cells[2].val = 1500
|
||||
row1.cells[2].empty = false
|
||||
row1.cells[3].val = 0.0
|
||||
row1.cells[3].empty = false
|
||||
|
||||
row2.cells[0].val = 5.25
|
||||
row2.cells[0].empty = false
|
||||
row2.cells[1].val = 0.0
|
||||
row2.cells[1].empty = false
|
||||
row2.cells[2].val = 2500
|
||||
row2.cells[2].empty = false
|
||||
row2.cells[3].val = 3.333
|
||||
row2.cells[3].empty = false
|
||||
|
||||
// Test default export with pipe separator
|
||||
csv_output := sheet.export_csv(path: '')!
|
||||
lines := csv_output.split('\n')
|
||||
|
||||
// Verify header line
|
||||
assert lines.len > 0
|
||||
assert lines[0].starts_with('Name|Description|AggregateType|Tags|Subgroup|')
|
||||
|
||||
// Verify data lines
|
||||
assert lines.len >= 3 // Header + 2 data rows
|
||||
assert lines[1].starts_with('row1|First test row|sum|test,row,first|')
|
||||
|
||||
// Check for the cell values in the output
|
||||
assert lines[1].contains('|10.5|')
|
||||
assert lines[1].contains('|20.75|')
|
||||
assert lines[1].contains('|1500|')
|
||||
|
||||
// Test with custom separator and include_empty option
|
||||
csv_output2 := sheet.export_csv(
|
||||
path: '',
|
||||
separator: ',',
|
||||
include_empty: true
|
||||
)!
|
||||
lines2 := csv_output2.split('\n')
|
||||
|
||||
// Verify that empty cells are included as '0'
|
||||
assert lines2[1].contains('0')
|
||||
|
||||
// When using comma separator, the comma in tags should be quoted, not the pipe character
|
||||
assert lines2[2].contains('Second test row with | pipe character')
|
||||
assert lines2[2].contains('"test,row,second"')
|
||||
|
||||
// Test with different separator
|
||||
csv_output3 := sheet.export_csv(
|
||||
path: '',
|
||||
separator: ';'
|
||||
)!
|
||||
lines3 := csv_output3.split('\n')
|
||||
|
||||
// Verify separator is used correctly
|
||||
assert lines3[0].starts_with('Name;Description;AggregateType;Tags;Subgroup;')
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
import freeflowuniverse.herolib.osal.screen
|
||||
import freeflowuniverse.herolib.ui
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import os
|
||||
import time
|
||||
import json
|
||||
|
||||
@@ -10,7 +10,7 @@ import freeflowuniverse.herolib.data.encoderhero
|
||||
@end
|
||||
|
||||
@if model.cat == .installer
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
@end
|
||||
|
||||
@@ -10,7 +10,7 @@ import freeflowuniverse.herolib.data.encoderhero
|
||||
@end
|
||||
|
||||
@if model.cat == .installer
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
@end
|
||||
|
||||
@@ -3,7 +3,7 @@ module base
|
||||
import freeflowuniverse.herolib.osal
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.core
|
||||
import time
|
||||
import os
|
||||
|
||||
@@ -3,7 +3,7 @@ module cometbft
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module meilisearch_installer
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module postgresql
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module zerodb
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module zerofs
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module coredns
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module gitea
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module livekit
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module screen
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module zinit_installer
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module golang
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module nodejs
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module python
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module rust
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -3,7 +3,7 @@ module mycelium_installer
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module wireguard_installer
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module yggdrasil
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module actrunner
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module b2
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -3,7 +3,7 @@ module daguserver
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module fungistor
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module garage_s3
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module grafana
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module prometheus
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.core.texttools
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module rclone
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module restic
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module s3
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module griddriver
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module cloudhypervisor
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module docker
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module pacman
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module podman
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module youki
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module bun
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module imagemagick
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module lighttpd
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module tailwind
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -2,7 +2,7 @@ module tailwind4
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -3,7 +3,7 @@ module traefik
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
import time
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module zola
|
||||
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
import freeflowuniverse.herolib.osal.zinit
|
||||
|
||||
__global (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# startup manager
|
||||
|
||||
```go
|
||||
import freeflowuniverse.herolib.sysadmin.startupmanager
|
||||
import freeflowuniverse.herolib.osal.startupmanager
|
||||
mut sm:=startupmanager.get()!
|
||||
|
||||
|
||||
|
||||
@@ -103,19 +103,22 @@ pub mut:
|
||||
pub struct Main {
|
||||
pub mut:
|
||||
name string
|
||||
title string
|
||||
title string = 'Docusaurus'
|
||||
tagline string
|
||||
favicon string
|
||||
url string
|
||||
favicon string = 'img/favicon.png'
|
||||
url string = 'http://localhost'
|
||||
url_home string
|
||||
base_url string @[json: 'baseUrl']
|
||||
image string
|
||||
base_url string = '/' @[json: 'baseUrl']
|
||||
image string = 'img/tf_graph.png' @[required]
|
||||
metadata MainMetadata
|
||||
build_dest []string
|
||||
build_dest_dev []string
|
||||
build_dest []string @[json: 'buildDest']
|
||||
build_dest_dev []string @[json: 'buildDestDev']
|
||||
copyright string = "someone"
|
||||
to_import []MyImport @[json: 'import']
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Footer config structures
|
||||
pub struct FooterItem {
|
||||
pub mut:
|
||||
@@ -144,22 +147,6 @@ pub mut:
|
||||
title string = 'Docusaurus'
|
||||
}
|
||||
|
||||
pub struct Main {
|
||||
pub mut:
|
||||
name string
|
||||
title string = 'Docusaurus'
|
||||
tagline string
|
||||
favicon string = 'img/favicon.png'
|
||||
url string = 'http://localhost'
|
||||
url_home string
|
||||
base_url string = '/' @[json: 'baseUrl']
|
||||
image string = 'img/tf_graph.png' @[required]
|
||||
metadata MainMetadata
|
||||
build_dest []string @[json: 'buildDest']
|
||||
build_dest_dev []string @[json: 'buildDestDev']
|
||||
copyright string = "someone"
|
||||
to_import []MyImport @[json: 'import']
|
||||
}
|
||||
|
||||
pub struct MyImport {
|
||||
pub mut:
|
||||
@@ -199,56 +186,9 @@ pub struct BuildDest {
|
||||
pub mut:
|
||||
ssh_name string = 'main'
|
||||
path string //can be on the ssh root or direct path e.g. /root/hero/www/info
|
||||
// load_config loads all configuration from the specified directory
|
||||
pub fn load_config(cfg_dir string) !Config {
|
||||
// Ensure the config directory exists
|
||||
if !os.exists(cfg_dir) {
|
||||
return error('Config directory ${cfg_dir} does not exist')
|
||||
}
|
||||
|
||||
// Load and parse footer config
|
||||
footer_content := os.read_file(os.join_path(cfg_dir, 'footer.json'))!
|
||||
footer := json.decode(Footer, footer_content) or {
|
||||
eprintln('footer.json in ${cfg_dir} is not in the right format please fix.\nError: ${err}')
|
||||
exit(99)
|
||||
}
|
||||
|
||||
// Load and parse main config
|
||||
main_config_path := os.join_path(cfg_dir, 'main.json')
|
||||
main_content := os.read_file(main_config_path)!
|
||||
main := json.decode(Main, main_content) or {
|
||||
eprintln('main.json in ${cfg_dir} is not in the right format please fix.\nError: ${err}')
|
||||
println('
|
||||
|
||||
## EXAMPLE OF A GOOD ONE:
|
||||
|
||||
- note the list for buildDest and buildDestDev
|
||||
- note its the full path where the html is pushed too
|
||||
|
||||
{
|
||||
"title": "ThreeFold Web4",
|
||||
"tagline": "ThreeFold Web4",
|
||||
"favicon": "img/favicon.png",
|
||||
"url": "https://docs.threefold.io",
|
||||
"url_home": "docs/introduction",
|
||||
"baseUrl": "/",
|
||||
"image": "img/tf_graph.png",
|
||||
"metadata": {
|
||||
"description": "ThreeFold is laying the foundation for a geo aware Web 4, the next generation of the Internet.",
|
||||
"image": "https://threefold.info/kristof/img/tf_graph.png",
|
||||
"title": "ThreeFold Docs"
|
||||
},
|
||||
"buildDest":["root@info.ourworld.tf:/root/hero/www/info/tfgrid4"],
|
||||
"buildDestDev":["root@info.ourworld.tf:/root/hero/www/infodev/tfgrid4"]
|
||||
|
||||
}
|
||||
|
||||
// Load and parse navbar config
|
||||
navbar_content := os.read_file(os.join_path(cfg_dir, 'navbar.json'))!
|
||||
navbar := json.decode(Navbar, navbar_content) or {
|
||||
eprintln('navbar.json in ${cfg_dir} is not in the right format please fix.\nError: $err')
|
||||
exit(99)
|
||||
}
|
||||
|
||||
|
||||
pub struct ImportSource {
|
||||
pub mut:
|
||||
|
||||
Reference in New Issue
Block a user