diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7cd1091 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/quikassociate.iml b/.idea/quikassociate.iml new file mode 100644 index 0000000..7ee078d --- /dev/null +++ b/.idea/quikassociate.iml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/UNLICENSE b/UNLICENSE new file mode 100644 index 0000000..3c577b0 --- /dev/null +++ b/UNLICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to \ No newline at end of file diff --git a/cmd/associate.go b/cmd/associate.go new file mode 100644 index 0000000..8cbb911 --- /dev/null +++ b/cmd/associate.go @@ -0,0 +1,25 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +var thisisunsafe bool +var xdgbinlocation string + +var associateCmd = &cobra.Command{ + Use: "associate", + Short: "Set default for all supported file types", + Args: cobra.ExactArgs(1), + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + mime := processMime(mimeType(args[0])) + associate(mime, args[0], thisisunsafe, xdgbinlocation) + }, +} + +func init() { + associateCmd.Flags().BoolVarP(&thisisunsafe, "thisisunsafe", "k", false, "Disable association warning") + associateCmd.Flags().StringVarP(&xdgbinlocation, "xdgbinlocation", "b", "/usr/bin/xdg-mime", "Location to xdg-mime binary") + rootCmd.AddCommand(associateCmd) +} diff --git a/cmd/query.go b/cmd/query.go new file mode 100644 index 0000000..776829f --- /dev/null +++ b/cmd/query.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" +) + +var queryCmd = &cobra.Command{ + Use: "query", + Short: "Dumps all supported file types for app", + Args: cobra.ExactArgs(1), + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + mime := processMime(mimeType(args[0])) + for _, app := range mime { + fmt.Println(app) + } + }, +} + +func init() { + rootCmd.AddCommand(queryCmd) +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..7e58a03 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,25 @@ +package cmd + +import ( + "os" + + "github.com/spf13/cobra" +) + +var rootCmd = &cobra.Command{ + Use: "quikassociate", + Short: "Rapidly restore file associations", + Long: `quikassociate - rapidly restore file associations +When I install new applications, they putsch my preferred apps out. Quikassociate helps bulk setting mime defaults.`, +} + +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/cmd/utils.go b/cmd/utils.go new file mode 100644 index 0000000..3ff85c0 --- /dev/null +++ b/cmd/utils.go @@ -0,0 +1,65 @@ +package cmd + +import ( + "bufio" + "fmt" + "log" + "os" + "os/exec" + "strings" +) + +func mimeType(arg string) string { + // ? KDE Menu Editor puts edited files into ~/.local/share/applications + // ? so files might not be in /usr/share/applications, should add some way to change it or parse that folder too? + input := fmt.Sprintf("/usr/share/applications/%s.desktop", arg) + f, err := os.Open(input) + if err != nil { + log.Fatal(err) + } + defer func(f *os.File) { + err := f.Close() + if err != nil { + log.Fatal(err) + } + }(f) + + scanner := bufio.NewScanner(f) + + for scanner.Scan() { + if strings.Contains(scanner.Text(), "MimeType") { + return scanner.Text() + } + } + if err := scanner.Err(); err != nil { + log.Fatal(err) + } + + log.Fatal("This application file doesn't contain a MimeType entry!") + return "" +} + +func processMime(mime string) []string { + // The .desktop file of an application lists what file types it supports. + // Luckily, this list is easily parsable. + s := strings.Replace(mime, "MimeType=", "", -1) + arr := strings.Split(s, ";") + arr = arr[:len(arr)-1] + return arr +} + +func associate(mimes []string, app string, confirm bool, xdgbinlocation string) { + if !confirm { + fmt.Println("This will override your currently set default app for files that use a file type!") + fmt.Println("Press Enter to confirm.") + fmt.Scanln() // ? Is there a better way to do this? + } + for _, mime := range mimes { + cmd := exec.Command(xdgbinlocation, "default", app+".desktop", mime) + err := cmd.Run() + if err != nil { + log.Fatal(err) + } + + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..88eb3e0 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module quikassociate + +go 1.19 + +require github.com/spf13/cobra v1.6.1 + +require ( + github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..442875a --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..4ff9d74 --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main + +import "quikassociate/cmd" + +func main() { + cmd.Execute() +}