sncli

package module
v0.0.0-...-24f49af Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 9, 2024 License: AGPL-3.0 Imports: 27 Imported by: 0

README

sn-cli

a command-line interface for Standard Notes.

Build Status Go Report Card

latest updates

version 0.3.4 - 2024-01-07
  • fix command completion and update instructions
version 0.3.3 - 2024-01-07
  • add task command for management of Checklists and Advanced Checklists
version 0.3.2 - 2024-01-06
  • bug fixes and sync speed increases
version 0.3.1 - 2023-12-20
  • various output improvements, including stats
version 0.3.0 - 2023-12-14
  • bug fixes and item schema tests
version 0.2.8 - 2023-12-07
  • stored sessions are now auto-renewed when expired, or nearing expiry
version 0.2.7 - 2023-12-06

current features

COMMANDS:
     add        add items
     delete     delete items
     edit       edit notes
     tag        tag items
     task       manage checklists and tasks
     session    store session to
     register   register an account
     resync     delete and repopulate cache
     get        get item data
     stats      show statistics
     wipe       deletes all tags and notes
     test-data  create test data (hidden option)

note: export and import currently disabled due to recent StandardNotes API changes

installation

Download the latest release here: https://github.com/jonhadfield/sn-cli/releases

macOS and Linux

Install:

$ install <sn-cli binary> /usr/local/bin/sn
Windows

An installer is planned, but for now... Download the binary 'sncli_windows_amd64.exe' and rename to sn.exe

running

To see commands and options:

$ sn --help
authentication

By default, your credentials will be requested every time, but you can store them using either environment variables or, on MacOS and Linux, store your session using the native Keychain application.

environment variables

Note: if using 2FA, the token value will be requested each time

export SN_EMAIL=<email address>
export SN_PASSWORD=<password>
export SN_SERVER=<https://myserver.example.com>   # optional, if running personal server
session (macOS Keychain / Gnome Keyring)

Using a session is different from storing credentials as you no longer need to authenticate. As a result, if using 2FA (Two Factor Authentication), you won't need to enter your token value each time.

add session
sn session --add   # session will be stored after successful authentication

To encrypt your session when adding:

sn session --add --session-key   # either enter key as part of command, or '.' to hide its input
using a session

Prefix any command with --use-session to automatically retrieve and use the session. If your session is encrypted, you will be prompted for the session key. To specify the key on the command line:

sn --use-session --session-key <key> <command>

To use your session automatically, set the environment variable SN_USE_SESSION to true

known issues

  • accounts registered via sn-cli are initialised without initial encryption key(s). The workaround is to log in via the offical web/desktop app, to create these keys, after initial registration.

bash autocompletion

tool

the bash completion tool should be installed by default on most Linux installations.

To install on macOS (Homebrew)

$ brew install bash_completion

then add the following to ~/.bash_profile:

[ -f /usr/local/etc/bash_completion ] && . /usr/local/etc/bash_completion
installing completion script (found here)
macOS
$ cp bash_autocomplete /usr/local/etc/bash_completion.d/sn
$ echo "source /usr/local/etc/bash_completion.d/sn" | tee -a ~/.bashrc
Linux
$ cp bash_autocomplete /etc/bash_completion.d/sn
$ echo "source /etc/bash_completion.d/sn" | tee -a ~/.bashrc
autocomplete commands
$ sn <tab>

Documentation

Index

Constants

View Source
const (
	SNServerURL       = "https://api.standardnotes.com"
	SNPageSize        = 600
	SNAppName         = "sn-cli"
	MinPasswordLength = 8
)

Variables

This section is empty.

Functions

func CommaSplit

func CommaSplit(i string) []string

func DecryptString

func DecryptString(input DecryptStringInput) (plaintext string, err error)

func ItemKeysHealthcheck

func ItemKeysHealthcheck(input ItemsKeysHealthcheckInput) error

func OutputSession

func OutputSession(input OutputSessionInput) error

func RemoveDeleted

func RemoveDeleted(in items.Items) (out items.Items)

func Resync

func Resync(s *cache.Session, cacheDBDir, appName string) error

func StringInSlice

func StringInSlice(inStr string, inSlice []string, matchCase bool) bool

func Sync

func Sync(si cache.SyncInput, useStdErr bool) (so cache.SyncOutput, err error)

Types

type AddAdvancedChecklistTaskInput

type AddAdvancedChecklistTaskInput struct {
	Session  *cache.Session
	Debug    bool
	UUID     string
	Title    string
	Group    string
	Tasklist string
}

func (*AddAdvancedChecklistTaskInput) Run

func (ci *AddAdvancedChecklistTaskInput) Run() (err error)

type AddNoteInput

type AddNoteInput struct {
	Session  *cache.Session
	Title    string
	Text     string
	FilePath string
	Tags     []string
	Replace  bool
	Debug    bool
}

func (*AddNoteInput) Run

func (i *AddNoteInput) Run() error

type AddTagsInput

type AddTagsInput struct {
	Session    *cache.Session
	Tags       []string
	Parent     string
	ParentUUID string
	Debug      bool
	Replace    bool
}

func (*AddTagsInput) Run

func (i *AddTagsInput) Run() (output AddTagsOutput, err error)

type AddTagsOutput

type AddTagsOutput struct {
	Added, Existing []string
}

type AddTaskInput

type AddTaskInput struct {
	Session  *cache.Session
	Debug    bool
	Title    string
	UUID     string
	Tasklist string
}

func (*AddTaskInput) Run

func (ci *AddTaskInput) Run() (err error)

type AdvancedChecklist

type AdvancedChecklist struct {
	UUID            string                   `json:"-"`
	Duplicates      []AdvancedChecklist      `json:"-"`
	Title           string                   `json:"-"`
	SchemaVersion   string                   `json:"schemaVersion"`
	Groups          []AdvancedChecklistGroup `json:"groups"`
	DefaultSections []DefaultSection         `json:"defaultSections"`
	UpdatedAt       time.Time                `json:"updatedAt"`
	Trashed         bool                     `json:"trashed"`
}

func (*AdvancedChecklist) Sort

func (c *AdvancedChecklist) Sort()

type AdvancedChecklistGroup

type AdvancedChecklistGroup struct {
	Name       string                     `json:"name"`
	LastActive time.Time                  `json:"lastActive"`
	Sections   []AdvancedChecklistSection `json:"sections"`
	Tasks      AdvancedChecklistTasks     `json:"tasks"`
	Collapsed  bool                       `json:"collapsed"`
}

type AdvancedChecklistSection

type AdvancedChecklistSection struct {
	Id        string `json:"id"`
	Name      string `json:"name"`
	Collapsed bool   `json:"collapsed"`
}

type AdvancedChecklistTask

type AdvancedChecklistTask struct {
	Id          string    `json:"id"`
	Description string    `json:"description"`
	Completed   bool      `json:"completed"`
	CreatedAt   time.Time `json:"createdAt"`
	UpdatedAt   time.Time `json:"updatedAt"`
}

type AdvancedChecklistTasks

type AdvancedChecklistTasks []AdvancedChecklistTask

func (*AdvancedChecklistTasks) Sort

func (t *AdvancedChecklistTasks) Sort()

type AppDataContentJSON

type AppDataContentJSON struct {
	OrgStandardNotesSN           OrgStandardNotesSNDetailJSON             `json:"org.standardnotes.sn"`
	OrgStandardNotesSNComponents items.OrgStandardNotesSNComponentsDetail `json:"org.standardnotes.sn.components,omitempty"`
}

type AppDataContentYAML

type AppDataContentYAML struct {
	OrgStandardNotesSN           OrgStandardNotesSNDetailYAML             `yaml:"org.standardnotes.sn"`
	OrgStandardNotesSNComponents items.OrgStandardNotesSNComponentsDetail `yaml:"org.standardnotes.sn.components,omitempty"`
}

type CompleteAdvancedTaskInput

type CompleteAdvancedTaskInput struct {
	Session  *cache.Session
	Debug    bool
	Title    string
	Group    string
	Tasklist string
	UUID     string
}

func (*CompleteAdvancedTaskInput) Run

func (ci *CompleteAdvancedTaskInput) Run() error

type CompleteTaskInput

type CompleteTaskInput struct {
	Session  *cache.Session
	Debug    bool
	Title    string
	Tasklist string
	UUID     string
}

func (*CompleteTaskInput) Run

func (ci *CompleteTaskInput) Run() (err error)

type CreateItemsKeyInput

type CreateItemsKeyInput struct {
	Debug     bool
	MasterKey string
}

type DecryptStringInput

type DecryptStringInput struct {
	Session   session.Session
	In        string
	UseStdOut bool
	Key       string
}

type DefaultSection

type DefaultSection struct {
	Id   string `json:"id"`
	Name string `json:"name"`
}

type DeleteAdvancedChecklistTaskInput

type DeleteAdvancedChecklistTaskInput struct {
	Session   *cache.Session
	Debug     bool
	Title     string
	Group     string
	Checklist string
	UUID      string
}

func (*DeleteAdvancedChecklistTaskInput) Run

func (ci *DeleteAdvancedChecklistTaskInput) Run() (err error)

type DeleteItemConfig

type DeleteItemConfig struct {
	Session    *cache.Session
	NoteTitles []string
	NoteText   string
	ItemsUUIDs []string
	Regex      bool
	Debug      bool
}

func (*DeleteItemConfig) Run

func (i *DeleteItemConfig) Run() (noDeleted int, err error)

type DeleteNoteConfig

type DeleteNoteConfig struct {
	Session    *cache.Session
	NoteTitles []string
	NoteText   string
	NoteUUIDs  []string
	Regex      bool
	Debug      bool
}

func (*DeleteNoteConfig) Run

func (i *DeleteNoteConfig) Run() (int, error)

type DeleteTagConfig

type DeleteTagConfig struct {
	Session   *cache.Session
	Email     string
	TagTitles []string
	TagUUIDs  []string
	Regex     bool
	Debug     bool
}

func (*DeleteTagConfig) Run

func (i *DeleteTagConfig) Run() (noDeleted int, err error)

type DeleteTaskInput

type DeleteTaskInput struct {
	Session  *cache.Session
	Debug    bool
	Title    string
	Tasklist string
	UUID     string
}

func (*DeleteTaskInput) Run

func (ci *DeleteTaskInput) Run() (err error)

type EncryptedItemExport

type EncryptedItemExport struct {
	UUID        string `json:"uuid"`
	ItemsKeyID  string `json:"items_key_id,omitempty"`
	Content     string `json:"content"`
	ContentType string `json:"content_type"`
	// Deleted            bool    `json:"deleted"`
	EncItemKey         string  `json:"enc_item_key"`
	CreatedAt          string  `json:"created_at"`
	UpdatedAt          string  `json:"updated_at"`
	CreatedAtTimestamp int64   `json:"created_at_timestamp"`
	UpdatedAtTimestamp int64   `json:"updated_at_timestamp"`
	DuplicateOf        *string `json:"duplicate_of"`
}

type EncryptedItemsFile

type EncryptedItemsFile struct {
	Items items.EncryptedItems `json:"items"`
}

type ExportConfig

type ExportConfig struct {
	Session   *cache.Session
	Decrypted bool
	File      string
	UseStdOut bool
}

type GetItemsConfig

type GetItemsConfig struct {
	Session *cache.Session
	Filters items.ItemFilters
	Output  string
	Debug   bool
}

func (*GetItemsConfig) Run

func (i *GetItemsConfig) Run() (items items.Items, err error)

type GetNoteConfig

type GetNoteConfig struct {
	Session    *cache.Session
	Filters    items.ItemFilters
	NoteTitles []string
	TagTitles  []string
	TagUUIDs   []string
	PageSize   int
	BatchSize  int
	Debug      bool
}

func (*GetNoteConfig) Run

func (i *GetNoteConfig) Run() (items items.Items, err error)

type GetSettingsConfig

type GetSettingsConfig struct {
	Session *cache.Session
	Filters items.ItemFilters
	Output  string
	Debug   bool
}

func (*GetSettingsConfig) Run

func (i *GetSettingsConfig) Run() (settings items.Items, err error)

type GetTagConfig

type GetTagConfig struct {
	Session *cache.Session
	Filters items.ItemFilters
	Output  string
	Debug   bool
}

func (*GetTagConfig) Run

func (i *GetTagConfig) Run() (items items.Items, err error)

type ImportConfig

type ImportConfig struct {
	Session   *cache.Session
	File      string
	Format    string
	UseStdOut bool
	Debug     bool
}

type ItemOrphanedRefs

type ItemOrphanedRefs struct {
	ContentType  string
	Item         items.Item
	OrphanedRefs []string
}

type ItemReferenceJSON

type ItemReferenceJSON struct {
	UUID          string `json:"uuid"`
	ContentType   string `json:"content_type"`
	ReferenceType string `json:"reference_type",omitempty`
}

func ItemRefsToJSON

func ItemRefsToJSON(irs []items.ItemReference) []ItemReferenceJSON

type ItemReferenceYAML

type ItemReferenceYAML struct {
	UUID          string `yaml:"uuid"`
	ContentType   string `yaml:"content_type"`
	ReferenceType string `yaml:"reference_type",omitempty`
}

func ItemRefsToYaml

func ItemRefsToYaml(irs []items.ItemReference) []ItemReferenceYAML

type ItemsKeysHealthcheckInput

type ItemsKeysHealthcheckInput struct {
	Session       session.Session
	UseStdOut     bool
	DeleteInvalid bool
}

type ListChecklistsInput

type ListChecklistsInput struct {
	Session *cache.Session
	Debug   bool
}

type ListTasklistsInput

type ListTasklistsInput struct {
	Session  *cache.Session
	Ordering string
	Debug    bool
}

func (*ListTasklistsInput) Run

func (ci *ListTasklistsInput) Run() error

type NoteContentJSON

type NoteContentJSON struct {
	Title            string              `json:"title"`
	Text             string              `json:"text"`
	ItemReferences   []ItemReferenceJSON `json:"references"`
	AppData          AppDataContentJSON  `json:"appData"`
	EditorIdentifier string              `json:"editorIdentifier"`
	PreviewPlain     string              `json:"preview_plain"`
	PreviewHtml      string              `json:"preview_html"`
	Spellcheck       bool                `json:"spellcheck"`
	Trashed          *bool               `json:"trashed,omitempty"`
}

type NoteContentYAML

type NoteContentYAML struct {
	Title            string              `yaml:"title"`
	Text             string              `json:"text"`
	ItemReferences   []ItemReferenceYAML `yaml:"references"`
	AppData          AppDataContentYAML  `yaml:"appData"`
	EditorIdentifier string              `yaml:"editorIdentifier"`
	PreviewPlain     string              `yaml:"preview_plain"`
	PreviewHtml      string              `yaml:"preview_html"`
	Spellcheck       bool                `yaml:"spellcheck"`
	Trashed          *bool               `yaml:"trashed,omitempty"`
}

type NoteJSON

type NoteJSON struct {
	UUID        string          `json:"uuid"`
	Content     NoteContentJSON `json:"content"`
	ContentType string          `json:"content_type"`
	CreatedAt   string          `json:"created_at"`
	UpdatedAt   string          `json:"updated_at"`
}

type NoteYAML

type NoteYAML struct {
	UUID        string          `yaml:"uuid"`
	Content     NoteContentYAML `yaml:"content"`
	ContentType string          `yaml:"content_type"`
	CreatedAt   string          `yaml:"created_at"`
	UpdatedAt   string          `yaml:"updated_at"`
}

type OrgStandardNotesSNComponentsDetailJSON

type OrgStandardNotesSNComponentsDetailJSON map[string]interface{}

type OrgStandardNotesSNDetailJSON

type OrgStandardNotesSNDetailJSON struct {
	ClientUpdatedAt    string `json:"client_updated_at"`
	PrefersPlainEditor bool   `json:"prefersPlainEditor"`
	Pinned             bool   `json:"pinned"`
}

type OrgStandardNotesSNDetailYAML

type OrgStandardNotesSNDetailYAML struct {
	ClientUpdatedAt string `yaml:"client_updated_at"`
}

type OutputSessionInput

type OutputSessionInput struct {
	Session         session.Session
	In              string
	UseStdOut       bool
	OutputMasterKey bool
}

type RegisterConfig

type RegisterConfig struct {
	Email     string
	Password  string
	APIServer string
	Debug     bool
}

func (*RegisterConfig) Run

func (i *RegisterConfig) Run() error

type ReopenAdvancedTaskInput

type ReopenAdvancedTaskInput struct {
	Session  *cache.Session
	Debug    bool
	UUID     string
	Title    string
	Group    string
	Tasklist string
}

func (*ReopenAdvancedTaskInput) Run

func (ci *ReopenAdvancedTaskInput) Run() error

type ReopenTaskInput

type ReopenTaskInput struct {
	Session  *cache.Session
	Debug    bool
	UUID     string
	Title    string
	Tasklist string
}

func (*ReopenTaskInput) Run

func (ci *ReopenTaskInput) Run() (err error)

type SettingContentJSON

type SettingContentJSON struct {
	Title          string              `json:"title"`
	ItemReferences []ItemReferenceJSON `json:"references"`
	AppData        AppDataContentJSON  `json:"appData"`
}

type SettingContentYAML

type SettingContentYAML struct {
	Title          string              `yaml:"title"`
	ItemReferences []ItemReferenceYAML `yaml:"references"`
	AppData        AppDataContentYAML  `yaml:"appData"`
}

type SettingJSON

type SettingJSON struct {
	UUID        string             `json:"uuid"`
	Content     SettingContentJSON `json:"content"`
	ContentType string             `json:"content_type"`
	CreatedAt   string             `json:"created_at"`
	UpdatedAt   string             `json:"updated_at"`
}

type SettingYAML

type SettingYAML struct {
	UUID        string             `yaml:"uuid"`
	Content     SettingContentYAML `yaml:"content"`
	ContentType string             `yaml:"content_type"`
	CreatedAt   string             `yaml:"created_at"`
	UpdatedAt   string             `yaml:"updated_at"`
}

type ShowChecklistInput

type ShowChecklistInput struct {
	Session *cache.Session
	Title   string
	UUID    string
	Debug   bool
}

type ShowTasklistInput

type ShowTasklistInput struct {
	Session       *cache.Session
	Debug         bool
	Group         string
	Title         string
	UUID          string
	ShowCompleted bool
	Ordering      string
}

func (*ShowTasklistInput) Run

func (ci *ShowTasklistInput) Run() error

type StatsConfig

type StatsConfig struct {
	Session cache.Session
}

func (*StatsConfig) GetData

func (i *StatsConfig) GetData() (StatsData, error)

func (*StatsConfig) Run

func (i *StatsConfig) Run() error

type StatsData

type StatsData struct {
	CoreTypeCounter   typeCounter
	OtherTypeCounter  typeCounter
	LargestNotes      []*items.Note
	ItemsOrphanedRefs []ItemOrphanedRefs
	LastUpdatedNote   *items.Note
	NewestNote        *items.Note
	OldestNote        *items.Note
}

type TagContentJSON

type TagContentJSON struct {
	Title          string              `json:"title"`
	ItemReferences []ItemReferenceJSON `json:"references"`
	AppData        AppDataContentJSON  `json:"appData"`
}

type TagContentYAML

type TagContentYAML struct {
	Title          string              `yaml:"title"`
	ItemReferences []ItemReferenceYAML `yaml:"references"`
	AppData        AppDataContentYAML  `yaml:"appData"`
}

type TagItemsConfig

type TagItemsConfig struct {
	Session    *cache.Session
	FindTitle  string
	FindText   string
	FindTag    string
	NewTags    []string
	Replace    bool
	IgnoreCase bool
	Debug      bool
}

func (*TagItemsConfig) Run

func (i *TagItemsConfig) Run() error

type TagJSON

type TagJSON struct {
	UUID        string         `json:"uuid"`
	Content     TagContentJSON `json:"content"`
	ContentType string         `json:"content_type"`
	CreatedAt   string         `json:"created_at"`
	UpdatedAt   string         `json:"updated_at"`
}

type TagYAML

type TagYAML struct {
	UUID        string         `yaml:"uuid"`
	Content     TagContentYAML `yaml:"content"`
	ContentType string         `yaml:"content_type"`
	CreatedAt   string         `yaml:"created_at"`
	UpdatedAt   string         `yaml:"updated_at"`
}

type TestDataCreateNotesConfig

type TestDataCreateNotesConfig struct {
	Session  cache.Session
	NumNotes int
	NumParas int
	Debug    bool
}

func (*TestDataCreateNotesConfig) Run

type TestDataCreateTagsConfig

type TestDataCreateTagsConfig struct {
	Session session.Session
	NumTags int64
	Debug   bool
}

func (*TestDataCreateTagsConfig) Run

type WipeConfig

type WipeConfig struct {
	Session    *cache.Session
	UseStdOut  bool
	Debug      bool
	Everything bool
}

func (*WipeConfig) Run

func (i *WipeConfig) Run() (int, error)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL