move Anko to sub package

This commit is contained in:
raziman 2021-02-14 14:35:36 +08:00
parent 2bf5d85b13
commit 738c0fa778
11 changed files with 201 additions and 200 deletions

172
anko.go
View File

@ -1,172 +0,0 @@
package main
import (
"io/ioutil"
"os"
"github.com/mattn/anko/core"
"github.com/mattn/anko/env"
"github.com/mattn/anko/vm"
_ "github.com/mattn/anko/packages"
"github.com/ztrue/tracerr"
)
type Anko struct {
env *env.Env
}
func newAnko() Anko {
return Anko{
core.Import(env.NewEnv()),
}
}
// define defines new symbol and value to the Anko env
func (a *Anko) define(symbol string, value interface{}) error {
return a.env.DefineGlobal(symbol, value)
}
// set sets new value to existing symbol. Use this when change value under an
// existing symbol.
func (a *Anko) set(symbol string, value interface{}) error {
return a.env.Set(symbol, value)
}
// get gets value from anko env, returns error if symbol is not found.
func (a *Anko) get(symbol string) (interface{}, error) {
return a.env.Get(symbol)
}
// getInt gets int value from symbol, returns golang default value if not found
func (a *Anko) getInt(symbol string) int {
v, err := a.env.Get(symbol)
if err != nil {
return 0
}
val, ok := v.(int64)
if !ok {
return 0
}
return int(val)
}
// getString gets string value from symbol, returns golang default value if not
// found
func (a *Anko) getString(symbol string) string {
v, err := a.env.Get(symbol)
if err != nil {
return ""
}
val, ok := v.(string)
if !ok {
return ""
}
return val
}
// getBool gets bool value from symbol, returns golang default value if not
// found
func (a *Anko) getBool(symbol string) bool {
v, err := a.env.Get(symbol)
if err != nil {
return false
}
val, ok := v.(bool)
if !ok {
return false
}
return val
}
// execute executes anko script
func (a *Anko) execute(src string) (interface{}, error) {
return vm.Execute(a.env, nil, src)
}
// executes user config with default config is executed first in order to apply
// default values
func execConfig(config string) error {
const defaultConfig = `
// confirmation popup to add the whole playlist to the queue
confirm_bulk_add = true
confirm_on_exit = true
queue_loop = false
load_prev_queue = true
popup_timeout = "5s"
// change this to directory that contains mp3 files
music_dir = "~/music"
// url history of downloaded audio will be saved here
history_path = "~/.local/share/gomu/urls"
// some of the terminal supports unicode character
// you can set this to true to enable emojis
use_emoji = true
// initial volume when gomu starts up
volume = 80
// if you experiencing error using this invidious instance, you can change it
// to another instance from this list:
// https://github.com/iv-org/documentation/blob/master/Invidious-Instances.md
invidious_instance = "https://vid.puffyan.us"
// default emoji here is using awesome-terminal-fonts
// you can change these to your liking
emoji_playlist = ""
emoji_file = ""
emoji_loop = "ﯩ"
emoji_noloop = ""
// not all colors can be reproducible in terminal
// changing hex colors may or may not produce expected result
color_accent = "#008B8B"
color_background = "none"
color_foreground = "#FFFFFF"
color_now_playing_title = "#017702"
color_playlist = "#008B8B"
color_popup = "#0A0F14"
// vim: syntax=go
`
// built-in functions
gomu.anko.define("debug_popup", debugPopup)
gomu.anko.define("input_popup", inputPopup)
gomu.anko.define("show_popup", defaultTimedPopup)
gomu.anko.define("shell", shell)
cfg := expandTilde(config)
_, err := os.Stat(cfg)
if os.IsNotExist(err) {
err = appendFile(cfg, defaultConfig)
if err != nil {
return tracerr.Wrap(err)
}
}
content, err := ioutil.ReadFile(cfg)
if err != nil {
return tracerr.Wrap(err)
}
// execute default config
_, err = gomu.anko.execute(defaultConfig)
if err != nil {
return tracerr.Wrap(err)
}
// execute user config
_, err = gomu.anko.execute(string(content))
if err != nil {
return tracerr.Wrap(err)
}
return nil
}

87
anko/anko.go Normal file
View File

@ -0,0 +1,87 @@
package anko
import (
"github.com/mattn/anko/core"
"github.com/mattn/anko/env"
"github.com/mattn/anko/vm"
_ "github.com/mattn/anko/packages"
)
type Anko struct {
env *env.Env
}
func NewAnko() Anko {
return Anko{
core.Import(env.NewEnv()),
}
}
// define defines new symbol and value to the Anko env
func (a *Anko) Define(symbol string, value interface{}) error {
return a.env.DefineGlobal(symbol, value)
}
// set sets new value to existing symbol. Use this when change value under an
// existing symbol.
func (a *Anko) Set(symbol string, value interface{}) error {
return a.env.Set(symbol, value)
}
// get gets value from anko env, returns error if symbol is not found.
func (a *Anko) Get(symbol string) (interface{}, error) {
return a.env.Get(symbol)
}
// getInt gets int value from symbol, returns golang default value if not found
func (a *Anko) GetInt(symbol string) int {
v, err := a.env.Get(symbol)
if err != nil {
return 0
}
val, ok := v.(int64)
if !ok {
return 0
}
return int(val)
}
// getString gets string value from symbol, returns golang default value if not
// found
func (a *Anko) GetString(symbol string) string {
v, err := a.env.Get(symbol)
if err != nil {
return ""
}
val, ok := v.(string)
if !ok {
return ""
}
return val
}
// getBool gets bool value from symbol, returns golang default value if not
// found
func (a *Anko) GetBool(symbol string) bool {
v, err := a.env.Get(symbol)
if err != nil {
return false
}
val, ok := v.(bool)
if !ok {
return false
}
return val
}
// execute executes anko script
func (a *Anko) Execute(src string) (interface{}, error) {
return vm.Execute(a.env, nil, src)
}

View File

@ -31,18 +31,18 @@ func newColor() *Colors {
for k, v := range defaultColors {
// color from the config file
cfgColor := anko.getString(k)
cfgColor := anko.GetString(k)
if validHexColor(cfgColor) {
continue
}
// use default value if invalid hex color was given
anko.set(k, v)
anko.Set(k, v)
}
// handle none background color
var bgColor tcell.Color
bg := anko.getString("color_background")
bg := anko.GetString("color_background")
if bg == "none" {
bgColor = tcell.ColorDefault
@ -50,11 +50,11 @@ func newColor() *Colors {
bgColor = tcell.GetColor(bg)
}
accent := anko.getString("color_accent")
foreground := anko.getString("color_foreground")
popup := anko.getString("color_popup")
title := anko.getString("color_now_playing_title")
playlist := anko.getString("color_playlist")
accent := anko.GetString("color_accent")
foreground := anko.GetString("color_foreground")
popup := anko.GetString("color_popup")
title := anko.GetString("color_now_playing_title")
playlist := anko.GetString("color_playlist")
color := &Colors{
accent: tcell.GetColor(accent),

View File

@ -205,7 +205,7 @@ func (c Command) defineCommands() {
c.define("bulk_add", func() {
currNode := gomu.playlist.GetCurrentNode()
bulkAdd := anko.getBool("confirm_bulk_add")
bulkAdd := anko.GetBool("confirm_bulk_add")
if !bulkAdd {
gomu.playlist.addAllToQueue(currNode)
@ -321,7 +321,7 @@ func (c Command) defineCommands() {
/* Global */
c.define("quit", func() {
confirmOnExit := anko.getBool("confirm_on_exit")
confirmOnExit := anko.GetBool("confirm_on_exit")
if !confirmOnExit {
err := gomu.quit(gomu.args)
@ -462,7 +462,7 @@ func (c Command) defineCommands() {
})
for name, cmd := range c.commands {
err := gomu.anko.define(name, cmd)
err := gomu.anko.Define(name, cmd)
if err != nil {
logError(err)
}

View File

@ -3,6 +3,7 @@ package main
import (
"github.com/rivo/tview"
"github.com/ztrue/tracerr"
"github.com/issadarkthing/gomu/anko"
)
var VERSION = "N/A"
@ -23,7 +24,7 @@ type Gomu struct {
prevPanel Panel
panels []Panel
args Args
anko Anko
anko anko.Anko
}
// Creates new instance of gomu with default values
@ -31,7 +32,7 @@ func newGomu() *Gomu {
gomu := &Gomu{
command: newCommand(),
anko: newAnko(),
anko: anko.NewAnko(),
}
return gomu

View File

@ -37,7 +37,7 @@ type Player struct {
func newPlayer() *Player {
volume := gomu.anko.getInt("volume")
volume := gomu.anko.GetInt("volume")
// Read initial volume from config
initVol := absVolume(volume)

View File

@ -74,7 +74,7 @@ func newPlaylist(args Args) *Playlist {
anko := gomu.anko
m := anko.getString("music_dir")
m := anko.GetString("music_dir")
rootDir, err := filepath.Abs(expandTilde(m))
if err != nil {
err = tracerr.Errorf("unable to find music directory: %e", err)
@ -89,11 +89,11 @@ func newPlaylist(args Args) *Playlist {
var rootTextView string
useEmoji := anko.getBool("use_emoji")
useEmoji := anko.GetBool("use_emoji")
if useEmoji {
emojiPlaylist := anko.getString("emoji_playlist")
emojiPlaylist := anko.GetString("emoji_playlist")
rootTextView = fmt.Sprintf("%s %s", emojiPlaylist, path.Base(rootDir))
} else {
@ -572,7 +572,7 @@ func ytdl(url string, selPlaylist *tview.TreeNode) error {
playlistPath := dir
audioPath := extractFilePath(stdout.Bytes(), playlistPath)
historyPath := gomu.anko.getString("history_path")
historyPath := gomu.anko.GetString("history_path")
err = appendFile(expandTilde(historyPath), url+"\n")
if err != nil {
@ -729,12 +729,12 @@ func (p *Playlist) paste() error {
}
func setDisplayText(songName string) string {
useEmoji := gomu.anko.getBool("use_emoji")
useEmoji := gomu.anko.GetBool("use_emoji")
if !useEmoji {
return songName
}
emojiFile := gomu.anko.getString("emoji_file")
emojiFile := gomu.anko.GetString("emoji_file")
return fmt.Sprintf(" %s %s", emojiFile, songName)
}

View File

@ -68,7 +68,7 @@ func (s *Stack) pop() tview.Primitive {
// Gets popup timeout from config file
func getPopupTimeout() time.Duration {
dur := gomu.anko.getString("popup_timeout")
dur := gomu.anko.GetString("popup_timeout")
m, err := time.ParseDuration(dur)
if err != nil {

View File

@ -97,17 +97,17 @@ func (q *Queue) updateTitle() string {
var loop string
isEmoji := gomu.anko.getBool("use_emoji")
isEmoji := gomu.anko.GetBool("use_emoji")
if q.isLoop {
if isEmoji {
loop = gomu.anko.getString("emoji_loop")
loop = gomu.anko.GetString("emoji_loop")
} else {
loop = "Loop"
}
} else {
if isEmoji {
loop = gomu.anko.getString("emoji_noloop")
loop = gomu.anko.GetString("emoji_noloop")
} else {
loop = "No loop"
}

View File

@ -86,7 +86,7 @@ func getRequest(url string, v interface{}) error {
func getSearchResult(query string) ([]YoutubeVideo, error) {
query = url.QueryEscape(query)
domain := gomu.anko.getString("invidious_instance")
domain := gomu.anko.GetString("invidious_instance")
targetUrl := domain + `/api/v1/search?q=` + query
yt := []YoutubeVideo{}

View File

@ -7,6 +7,7 @@ import (
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"os/signal"
"strings"
@ -15,6 +16,7 @@ import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/ztrue/tracerr"
)
// Panel is used to keep track of childrens in slices
@ -27,6 +29,7 @@ type Panel interface {
help() []string
}
// Default values for command line arguments.
const (
configPath = "~/.config/gomu/config"
musicPath = "~/music"
@ -52,6 +55,88 @@ func getArgs() Args {
return ar
}
// executes user config with default config is executed first in order to apply
// default values
func execConfig(config string) error {
const defaultConfig = `
// confirmation popup to add the whole playlist to the queue
confirm_bulk_add = true
confirm_on_exit = true
queue_loop = false
load_prev_queue = true
popup_timeout = "5s"
// change this to directory that contains mp3 files
music_dir = "~/music"
// url history of downloaded audio will be saved here
history_path = "~/.local/share/gomu/urls"
// some of the terminal supports unicode character
// you can set this to true to enable emojis
use_emoji = true
// initial volume when gomu starts up
volume = 80
// if you experiencing error using this invidious instance, you can change it
// to another instance from this list:
// https://github.com/iv-org/documentation/blob/master/Invidious-Instances.md
invidious_instance = "https://vid.puffyan.us"
// default emoji here is using awesome-terminal-fonts
// you can change these to your liking
emoji_playlist = ""
emoji_file = ""
emoji_loop = "ﯩ"
emoji_noloop = ""
// not all colors can be reproducible in terminal
// changing hex colors may or may not produce expected result
color_accent = "#008B8B"
color_background = "none"
color_foreground = "#FFFFFF"
color_now_playing_title = "#017702"
color_playlist = "#008B8B"
color_popup = "#0A0F14"
// vim: syntax=go
`
// built-in functions
gomu.anko.Define("debug_popup", debugPopup)
gomu.anko.Define("input_popup", inputPopup)
gomu.anko.Define("show_popup", defaultTimedPopup)
gomu.anko.Define("shell", shell)
cfg := expandTilde(config)
_, err := os.Stat(cfg)
if os.IsNotExist(err) {
err = appendFile(cfg, defaultConfig)
if err != nil {
return tracerr.Wrap(err)
}
}
content, err := ioutil.ReadFile(cfg)
if err != nil {
return tracerr.Wrap(err)
}
// execute default config
_, err = gomu.anko.Execute(defaultConfig)
if err != nil {
return tracerr.Wrap(err)
}
// execute user config
_, err = gomu.anko.Execute(string(content))
if err != nil {
return tracerr.Wrap(err)
}
return nil
}
// Sets the layout of the application
func layout(gomu *Gomu) *tview.Flex {
flex := tview.NewFlex().
@ -104,12 +189,12 @@ func start(application *tview.Application, args Args) {
gomu.playingBar.setDefault()
isQueueLoop := gomu.anko.getBool("queue_loop")
isQueueLoop := gomu.anko.GetBool("queue_loop")
gomu.player.isLoop = isQueueLoop
gomu.queue.isLoop = gomu.player.isLoop
loadQueue := gomu.anko.getBool("load_prev_queue")
loadQueue := gomu.anko.GetBool("load_prev_queue")
if !*args.empty && loadQueue {
// load saved queue from previous session
@ -150,7 +235,7 @@ func start(application *tview.Application, args Args) {
}
// check for user defined keybindings
kb, err := gomu.anko.get("keybinds")
kb, err := gomu.anko.Get("keybinds")
if err == nil {
keybinds, ok := kb.(map[interface{}]interface{})
if !ok {