// Copyright (C) 2021 nytpu // SPDX-License-Identifier: AGPL-3.0-or-later // For more license details, see LICENSE or . // comitium is a feed aggregator for gemini. see README.md for more details and // doc/comitium.1.scd for a manual page. package main import ( "fmt" "net/url" "os" "path/filepath" "github.com/mitchellh/go-homedir" "golang.nytpu.com/comitium/core" "golang.nytpu.com/comitium/fetch" ) func main() { if len(os.Args) < 2 { fmt.Fprint(os.Stderr, "Please provide a command.\n\n") usage() os.Exit(1) } // these are special cases where we shouldn't bother to do anything else if os.Args[1] == "help" { usage() os.Exit(0) } if os.Args[1] == "version" { fmt.Printf("comitium v%v, commit %v\n", Version, Commit) os.Exit(0) } c, ok := commands[os.Args[1]] if !ok { fmt.Fprint(os.Stderr, "Unrecognized Command.\n\n") usage() os.Exit(1) } c.AddFlagSet(globalFs) c.Parse(os.Args[2:]) // dataPath is the location where all the data (list of subs, cached hashes, // etcetera) are stored dataPath := getDataPath() err := core.Init(dataPath) if err != nil { fmt.Fprintf(os.Stderr, "Error in initialization: %v\n", err) os.Exit(1) } switch os.Args[1] { case "refresh": if len(c.Args()) != 0 { fmt.Fprint(os.Stderr, "\"refresh\" doesn't take an argument!\n\n") usage() os.Exit(1) } // TODO fmt.Fprintln(os.Stderr, "Not Yet Implemented") case "list": if len(c.Args()) != 0 { fmt.Fprint(os.Stderr, "\"list\" doesn't take an argument!\n\n") usage() os.Exit(1) } // TODO fmt.Fprintln(os.Stderr, "Not Yet Implemented") case "add": if len(c.Args()) < 1 { fmt.Fprint(os.Stderr, "Please provide a URL to add.\n\n") usage() os.Exit(1) } remote, err := url.Parse(c.Arg(0)) if err != nil { fmt.Fprintf(os.Stderr, "Error parsing URL: %v\n", err) os.Exit(1) } if !*addTypeFlag { // feed err = fetch.Feed(&core.Data, remote, c.Arg(1)) if err != nil { fmt.Fprintf(os.Stderr, "Error adding feed: %v\n", err) os.Exit(1) } } else { // page err = fetch.Page(&core.Data, remote, c.Arg(1)) if err != nil { fmt.Fprintf(os.Stderr, "Error adding page: %v\n", err) os.Exit(1) } } err = core.Data.WriteJSON(dataPath) if err != nil { fmt.Fprintf(os.Stderr, "Error writing json: %v\n", err) os.Exit(1) } case "remove": if len(c.Args()) < 1 { fmt.Fprint(os.Stderr, "Please provide a URL to remove.\n\n") usage() os.Exit(1) } // TODO fmt.Fprintln(os.Stderr, "Not Yet Implemented") } } // verifyPath will expand ~ if neccessary and will clean the path. func verifyPath(p string) string { if n, err := homedir.Expand(p); err != nil { return filepath.Clean(p) } else { return filepath.Clean(n) } } // getDataPath will return a data path in a gracefully degrading tree, picking // the first that exists: // --data flag, $COMITIUM_DATA, $XDG_DATA_HOME/comitium, // $HOME/.local/share/comitium, $HOME/.comitium, $PWD (last resort) func getDataPath() string { if *dataFlag != "" { return verifyPath(*dataFlag) } if env := os.Getenv("COMITIUM_DATA"); env != "" { return verifyPath(env) } if env := os.Getenv("XDG_DATA_HOME"); env != "" { return verifyPath(env + "/comitium") } home, err := homedir.Dir() if err == nil { if _, err := os.Stat(verifyPath(home + "/.local")); !os.IsNotExist(err) { return verifyPath(home + "/.local/share/comitium") } return verifyPath(home + "/.comitium") } fmt.Fprintln(os.Stderr, "Error finding a suitable directory! Falling back to the current working directory. See \"comitium help\" or comitium(1) for more information.") return verifyPath("comitium") } func usage() { fmt.Fprintf(os.Stderr, "Usage:\n") fmt.Fprintf(os.Stderr, " %v [FLAGS] [ARGUMENTS]\n\n", os.Args[0]) fmt.Fprint(os.Stderr, "Commands:\n") for _, v := range commandInfo { // FIXME: find a way to dynamically match the spacing that // flag.PrintDefaults() outputs (instead of hardcoding "-20") fmt.Fprintf(os.Stderr, " %-20s%s\n", v.Name, v.Usage) } fmt.Fprintf(os.Stderr, "\nGlobal Flags:\n%v", globalFs.FlagUsages()) // command-specific flags should be printed here fmt.Fprintf(os.Stderr, "Flags for \"add\":\n%v\n", commands["add"].FlagUsages()) //fmt.Fprintf(os.Stderr, "To see specific details for a command, run \"%v -h\"\n", os.Args[0]) fmt.Fprint(os.Stderr, "For more help, see comitium(1).\n") }