feat: implement keybindings for opening and downloading attachments (#137)

* Added support for opening or downloading attachments

* Removed some debug statements

* Added close statements I forgot

* Added gitignore to ignore built executables

* Removed executables I accidentally added

* Fixed opening files not working on Windows

* Updated .gitignore to ignore .vscode

Co-authored-by: ayntgl <90600421+ayntgl@users.noreply.github.com>

* Deleted launch.json that doesn't need to be included

* Implemented suggestions on #137

Co-authored-by: ayntgl <90600421+ayntgl@users.noreply.github.com>
This commit is contained in:
KodiCraft 2022-03-13 19:22:10 +01:00 • committed by GitHub
parent 20ca8a7268
commit 7ef0f71b7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 125 additions and 9 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
discordo*
# Visual Studio Code
.vscode/

View file

@ -1,27 +1,50 @@
package config
import (
"os"
"runtime"
)
type IdentifyConfig struct {
Os string `toml:"os"`
Browser string `toml:"browser"`
}
type GeneralConfig struct {
UserAgent string `toml:"user_agent"`
FetchMessagesLimit int `toml:"fetch_messages_limit"`
Mouse bool `toml:"mouse"`
Timestamps bool `toml:"timestamps"`
Identify IdentifyConfig `toml:"identify"`
UserAgent string `toml:"user_agent"`
FetchMessagesLimit int `toml:"fetch_messages_limit"`
Mouse bool `toml:"mouse"`
Timestamps bool `toml:"timestamps"`
Identify IdentifyConfig `toml:"identify"`
AttachmentDownloadsDir string `toml:"attachment_downloads_dir"`
}
func newGeneralConfig() GeneralConfig {
return GeneralConfig{
UserAgent: "Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0",
FetchMessagesLimit: 50,
Mouse: true,
Timestamps: false,
UserAgent: "Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Firefox/97.0",
FetchMessagesLimit: 50,
Mouse: true,
Timestamps: false,
AttachmentDownloadsDir: UserDownloadsDir(),
Identify: IdentifyConfig{
Os: "Linux",
Browser: "Firefox",
},
}
}
func UserDownloadsDir() string {
// We try to set the download folder location to the default Downloads folder
var dlloc string
if runtime.GOOS == "windows" {
h, _ := os.UserHomeDir()
dlloc = h + "\\Downloads"
} else if runtime.GOOS == "linux" || runtime.GOOS == "darwin" {
h, _ := os.UserHomeDir()
dlloc = h + "/Downloads"
} else {
dlloc = os.TempDir() // Very lame fallback, I know
}
return dlloc
}

View file

@ -7,12 +7,17 @@ type KeybindingsConfig struct {
ToggleMessageInputField string `toml:"toggle_message_input_field"`
OpenMessageActionsList string `toml:"open_message_actions_list"`
OpenExternalEditor string `toml:"open_external_editor"`
OpenAttachment string `toml:"open_attachment"`
DownloadAttachment string `toml:"download_attachment"`
SelectPreviousMessage string `toml:"select_previous_message"`
SelectNextMessage string `toml:"select_next_message"`
SelectFirstMessage string `toml:"select_first_message"`
SelectLastMessage string `toml:"select_last_message"`
}
func newKeybindingsConfig() KeybindingsConfig {
@ -25,6 +30,9 @@ func newKeybindingsConfig() KeybindingsConfig {
OpenMessageActionsList: "Rune[a]",
OpenExternalEditor: "Ctrl+E",
OpenAttachment: "Rune[o]",
DownloadAttachment: "Rune[d]",
SelectPreviousMessage: "Up",
SelectNextMessage: "Down",
SelectFirstMessage: "Home",

View file

@ -2,8 +2,12 @@ package ui
import (
"io"
"io/ioutil"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"github.com/atotto/clipboard"
@ -91,6 +95,83 @@ func (mtv *MessagesTextView) onInputCapture(e *tcell.EventKey) *tcell.EventKey {
ScrollToHighlight()
return nil
case mtv.app.Config.Keybindings.OpenAttachment:
if ms[mtv.app.SelectedMessage].Attachments != nil {
for _, a := range ms[mtv.app.SelectedMessage].Attachments {
// We are caching the files, but files with the same name can still exist, so it ultimately does not matter
t, _ := os.UserCacheDir()
f, err := os.Create(filepath.Join(t, a.Filename))
if err != nil {
f.Close()
return nil
}
response, err := http.Get(a.URL)
if err != nil {
f.Close()
return nil
}
d, err := ioutil.ReadAll(response.Body)
if err != nil {
f.Close()
return nil
}
f.Write(d)
f.Close()
if runtime.GOOS == "windows" {
// On windows, `start` can do all the heavy lifting through `cmd`
cmd := exec.Command("cmd", "/C start "+f.Name())
err := cmd.Run()
if err != nil {
return nil
}
} else if runtime.GOOS == "linux" {
// On linux, we'll assume xdg-open exists and try using that
cmd := exec.Command("xdg-open", f.Name())
err := cmd.Run()
if err != nil {
return nil
}
} else if runtime.GOOS == "darwin" {
// On MacOS open should do the trick
cmd := exec.Command("open", f.Name())
err := cmd.Run()
if err != nil {
return nil
}
} else {
// If we're on none of those platforms, I think I made some sort of fatal mistake
return nil
}
}
}
return nil
case mtv.app.Config.Keybindings.DownloadAttachment:
if ms[mtv.app.SelectedMessage].Attachments != nil {
// Download the files to the configured location
for _, a := range ms[mtv.app.SelectedMessage].Attachments {
f, err := os.Create(filepath.Join(mtv.app.Config.General.AttachmentDownloadsDir + a.Filename))
if err != nil {
f.Close()
return nil
}
response, err := http.Get(a.URL)
if err != nil {
f.Close()
return nil
}
d, err := ioutil.ReadAll(response.Body)
if err != nil {
f.Close()
return nil
}
f.Write(d)
f.Close()
}
}
case mtv.app.Config.Keybindings.OpenMessageActionsList:
messageActionsList := tview.NewList()