Skip to content

Commit

Permalink
Merge pull request #11 from oolong-sh/patrick-dev
Browse files Browse the repository at this point in the history
refactor/feat: better config handling
  • Loading branch information
ptdewey authored Dec 11, 2024
2 parents 699d267 + 1d53ac6 commit abeabf2
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 87 deletions.
36 changes: 20 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ Oolong looks for a configuration file at `~/.config/oolong.toml`
| `ignored_directories` | Subdirectories to exclude from reading and linking | `[".git"]` |
| `allowed_extensions` | Whitelist of file extensions to use in linking | `[".md", ".txt", ".mdx", ".tex", ".typ"]` |
| `open_command` | Command to run when clicking a graph node | `["code"]` (See below for more details) |
| `ngram_range` | Range of NGram sizes to use for keyword linking | `[1, 2, 3]` |
| `stop_words` | Additional stop words to exclude from keyword extraction | `[]` |


The `open_command` option is used by the graph to allow you to open a clicked note in an editor of your choice.
Expand All @@ -64,14 +62,21 @@ For more situations where you want to run a more complex command, separate conse
<!-- TODO: example using a script -->


**Graph Settings** (required):
**Linker Config** (optional -- falls back to defaults)

| Option | Description | Recommended |
| Option | Description | Default |
|--------|-------------|-------------|
| `ngram_range` | Range of NGram sizes to use for keyword linking | `[1, 2, 3]` |
| `stop_words` | Additional stop words to exclude from keyword extraction | `[]` |

**Graph Settings** (optional -- falls back to defaults):

| Option | Description | Default |
|--------|-------------|-------------|
| min_node_weight | Minimum NGram weight to allow to show up in the graph | `2.0` (Increase to a larger number for large note directories) |
| max_node_weight | Maximum size of a node in the graph (larger values are clamped to this size) | `10.0` |
| min_link_weight | The minimum allowed link strength between a note and NGram | `0.1` (Increase to a larger number (0.2-0.3) for larger note directories) |
| default_mode | Default graph mode (2d/3d) | `"3d"` |
| default_mode | Default graph mode (2d/3d) | `"2d"` |


**Cloud Synchronization Settings** (optional):
Expand Down Expand Up @@ -117,27 +122,20 @@ allowed_extensions = [
# Note: All arguments MUST be separated into separate strings (see config for more details)
open_command = [ "code" ]


[linker]
# Range of NGram sizes to use for keyword linking
ngram_range = [ 1, 2, 3 ]

# Extra stop words to exclude from NGram generation
stop_words = [
"hello",
]
stop_words = [ "hello" ]

# graph settings (required)
[graph]
min_node_weight = 8.0
min_node_weight = 2.0
max_node_weight = 12.0
min_link_weight = 0.2
min_link_weight = 0.1
default_mode = "3d"

# optional plugins section (not currently recommended)
[plugins]
# List of plugins (lua files) to load
plugin_paths = [ "./scripts/daily_note.lua" ]

#
# NOTE: do not include the following section if you do not want to use cloud sync
#
Expand All @@ -146,4 +144,10 @@ host = "127.0.0.1" # replace with your server hostname/ip
user = "your_username" # replace with your server username
port = 22 # server ssh port
private_key_path = "/home/<your_username>/.ssh/<your_ssh_key_path>" # replace with your private key path


# optional plugins section (not currently recommended)
[plugins]
# List of plugins (lua files) to load
plugin_paths = [ "./scripts/daily_note.lua" ]
```
9 changes: 4 additions & 5 deletions examples/oolong.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@ open_command = [ "code" ]
# (more complicated commands should likely be written into a script)
# i.e. 'open_command = ["tmux", "neww", "-c", "shell", "nvim"]'

[linker]
# Range of NGram sizes to use for keyword linking
ngram_range = [ 1, 2, 3 ]

# Additional stop words
stop_words = [
"hello",
]
stop_words = [ "hello" ]

[graph]
min_node_weight = 4.0
max_node_weight = 80.0
min_node_weight = 2.0
max_node_weight = 10.0
min_link_weight = 0.1
default_mode = "3d"

Expand Down
72 changes: 14 additions & 58 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
package config

import (
"errors"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"time"

"github.com/BurntSushi/toml"
"github.com/fsnotify/fsnotify"
"github.com/oolong-sh/sync"
)

var cfg OolongConfig
var cfg OolongConfig = defaultConfig()

type OolongSyncConfig sync.SyncConfig

Expand All @@ -24,17 +18,16 @@ type OolongConfig struct {
IgnoreDirectories []string `toml:"ignored_directories"`
OpenCommand []string `toml:"open_command"`

// TODO: move these things to a "linker" config section
NGramRange []int `toml:"ngram_range"`
StopWords []string `toml:"stop_words"`

PluginsConfig OolongPluginConfig `toml:"plugins"`
LinkerConfig OolongLinkerConfig `toml:"linker"`
GraphConfig OolongGraphConfig `toml:"graph"`
SyncConfig OolongSyncConfig `toml:"sync"`
PluginsConfig OolongPluginConfig `toml:"plugins"`
}

type OolongPluginConfig struct {
PluginPaths []string `toml:"plugin_paths"`
type OolongLinkerConfig struct {
// TODO: move these things to a "linker" config section
NGramRange []int `toml:"ngram_range"`
StopWords []string `toml:"stop_words"`
}

type OolongGraphConfig struct {
Expand All @@ -48,21 +41,25 @@ type OolongEditorConfig struct {
// TODO: web editor related config (themes?)
}

type OolongPluginConfig struct {
PluginPaths []string `toml:"plugin_paths"`
}

func Config() *OolongConfig { return &cfg }

func NotesDirPaths() []string { return cfg.NotesDirPaths }
func OpenCommand() []string { return cfg.OpenCommand }
func NGramRange() []int { return cfg.NGramRange }
func AllowedExtensions() []string { return cfg.AllowedExtensions }
func PluginPaths() []string { return cfg.PluginsConfig.PluginPaths }
func IgnoredDirectories() []string { return cfg.IgnoreDirectories }
func StopWords() []string { return cfg.StopWords }
func LinkerConfig() OolongLinkerConfig { return cfg.LinkerConfig }
func NGramRange() []int { return cfg.LinkerConfig.NGramRange }
func StopWords() []string { return cfg.LinkerConfig.StopWords }
func WeightThresholds() OolongGraphConfig { return cfg.GraphConfig }
func GraphMode() string { return cfg.GraphConfig.DefaultMode }
func SyncConfig() OolongSyncConfig { return cfg.SyncConfig }

func Setup() error {
// CHANGE: for hot-reloading, only one config path location should be supported (~/.config/oolong/oolong.toml)
configPath, err := findConfigPath()
if err != nil {
panic(err)
Expand Down Expand Up @@ -95,45 +92,4 @@ func readConfig(configPath string) {
}
cfg.NotesDirPaths[i] = d
}

// TODO: set default values for thresholds if not set
}

func initWatcher(configPath string) error {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return err
}
defer watcher.Close()

if err := watcher.Add(filepath.Dir(configPath)); err != nil {
return err
}

for {
select {
case event, ok := <-watcher.Events:
if !ok {
log.Println("Watcher event channel returned bad result.")
return errors.New("Invalid watcher errors channel value.")
}

if !strings.Contains(event.Name, configPath) {
time.Sleep(500)
continue
} else if !event.Has(fsnotify.Write) {
time.Sleep(500)
continue
}

// write event is sent on write start, wait 500ms for write to finish
time.Sleep(500)
readConfig(configPath)
case err, ok := <-watcher.Errors:
if !ok {
return errors.New("Invalid watcher errors channel value.")
}
log.Println("error:", err)
}
}
}
3 changes: 0 additions & 3 deletions internal/config/config_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ func checkDefaultLocations() (string, error) {
configPaths := []string{
"~/.config/oolong/oolong.toml",
"~/.config/oolong.toml",
"~/oolong.toml",
"~/.oolong.toml",
"/etc/oolong/oolong.toml",
"./oolong.toml",
}

Expand Down
32 changes: 32 additions & 0 deletions internal/config/defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package config

// Sync, editor, plugin configs can use default type values
func defaultConfig() OolongConfig {
return OolongConfig{
NotesDirPaths: []string{},
AllowedExtensions: []string{},
IgnoreDirectories: []string{},
OpenCommand: []string{},
LinkerConfig: defaultLinkerConfig(),
GraphConfig: defaultGraphConfig(),
SyncConfig: OolongSyncConfig{},
PluginsConfig: OolongPluginConfig{},
}
}

func defaultLinkerConfig() OolongLinkerConfig {
return OolongLinkerConfig{
NGramRange: []int{1, 2, 3},
StopWords: []string{},
}
}

func defaultGraphConfig() OolongGraphConfig {
// TEST: these values with new users (setting these dynamically would likely be ideal using some sort of percentages)
return OolongGraphConfig{
MinNodeWeight: 2.0,
MaxNodeWeight: 10.0,
MinLinkWeight: 0.1,
DefaultMode: "2d",
}
}
50 changes: 50 additions & 0 deletions internal/config/watcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package config

import (
"errors"
"log"
"path/filepath"
"strings"
"time"

"github.com/fsnotify/fsnotify"
)

func initWatcher(configPath string) error {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return err
}
defer watcher.Close()

if err := watcher.Add(filepath.Dir(configPath)); err != nil {
return err
}

for {
select {
case event, ok := <-watcher.Events:
if !ok {
log.Println("Watcher event channel returned bad result.")
return errors.New("Invalid watcher errors channel value.")
}

if !strings.Contains(event.Name, configPath) {
time.Sleep(500)
continue
} else if !event.Has(fsnotify.Write) {
time.Sleep(500)
continue
}

// write event is sent on write start, wait 500ms for write to finish
time.Sleep(500)
readConfig(configPath)
case err, ok := <-watcher.Errors:
if !ok {
return errors.New("Invalid watcher errors channel value.")
}
log.Println("error:", err)
}
}
}
10 changes: 5 additions & 5 deletions internal/documents/corpus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import (

var cfg = config.OolongConfig{
// NotesDirPaths: []string{"~/notes"},
NotesDirPaths: []string{"../../examples/data"},
NGramRange: []int{1, 2, 3},
NotesDirPaths: []string{"../../examples/data"},
LinkerConfig: config.OolongLinkerConfig{
NGramRange: []int{1, 2, 3},
},
AllowedExtensions: []string{".md", ".tex", ".typ", ".txt"},
IgnoreDirectories: []string{".templates", ".git"},
}
Expand All @@ -26,16 +28,14 @@ func init() {
func TestReadNotesDirs(t *testing.T) {
conf := config.Config()
conf.NotesDirPaths = cfg.NotesDirPaths
conf.NGramRange = cfg.NGramRange
conf.LinkerConfig.NGramRange = cfg.LinkerConfig.NGramRange
conf.AllowedExtensions = cfg.AllowedExtensions
conf.IgnoreDirectories = cfg.IgnoreDirectories

// TODO: actual tests with an example data directory
fmt.Println("reading?? -- gets lock")
if err := documents.ReadNotesDirs(); err != nil {
t.Fatalf("Failed to read notes directories: %v\n", err)
}
fmt.Println("finished reading -- getting read lock")
s := state.State()

b := append([]byte{}, []byte("ngram,weight,count\n")...)
Expand Down
1 change: 1 addition & 0 deletions internal/graph/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/oolong-sh/oolong/internal/notes"
)

// FIX: calculate document weight with non-partial bm25f, use that to define node size
type NodeJSON struct {
ID string `json:"id"`
Name string `json:"name"`
Expand Down

0 comments on commit abeabf2

Please sign in to comment.