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()
+}