shithub: hell

ref: c287fedbdc38de1ce9d5ab62433b1fa0366b85c3
dir: /filehandler.go/

View raw version
package main

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"path"

	"codeberg.org/penny64/hellclient-go-mastodon"
	"github.com/google/shlex"
)

func openItemInOS(command string, url string) {
	cmdstring := fmt.Sprintf(command, url)
	cmdargv, err := shlex.Split(cmdstring)
	if err != nil {
		fmt.Printf("Failed to parse browser command: %s\n", cmdstring)
		return
	}
	cmd := exec.Command(cmdargv[0], cmdargv[1:]...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stdout
	cmd.Run()
	return
}
func (hc *Hellclient) previewPostImages(target *mastodon.Status, commandstring string) (err error) {
	//Let go of the lock while we wait for return
	hc.unlock()
	_, pathnames, err := downloadPostImages(target)

	if len(pathnames) == 0 {
		//We tolerate failing to download some items but if we have none then error out
		hc.lock()
		return
	}
	for _, path := range pathnames {
		go openItemInOS(commandstring, path)
	}
	hc.lock()
	return

}

func savePostImages(target *mastodon.Status, savedir string) (err error) {
	files, pathnames, err := downloadPostImages(target)
	if err != nil {
		fmt.Printf("Failed to download post images:%v", err)
		return
	}
	for file := range pathnames {
		defer os.Remove(pathnames[file])
	}
	var download *os.File
	for file := range files {
		download, err = os.Create(savedir + "/" + path.Base(files[file].Name()))
		filereader, _ := os.Open(files[file].Name())
		if _, err = io.Copy(download, filereader); err != nil {
			fmt.Println("Failed to save %v\n", path.Base(files[file].Name()))
			continue
		}
		fmt.Printf("Downloaded: %v\n", download.Name())

	}
	return err
}

func downloadPostImages(target *mastodon.Status) (files []*os.File, pathnames []string, err error) {

	if len(target.MediaAttachments) == 0 {
		fmt.Printf("Status has no attachments.\n")
		return
	}

	for media := range target.MediaAttachments {
		err, mediafile := downloadImage(target.MediaAttachments[media].URL)
		if err != nil {
			fmt.Printf("Media download error: %v\n", err)
			continue
		}
		files = append(files, mediafile)
		pathnames = append(pathnames, mediafile.Name())

	}
	return
}

func downloadImage(target string) (err error, file *os.File) {
	response, err := http.Get(target)
	if err != nil {
		return
	}

	parsedurl, err := url.Parse(target)

	if err != nil {
		return
	}

	filename := path.Base(parsedurl.Path)

	if err != nil {
		return
	}

	file, err = os.CreateTemp("", "*"+filename)
	if err != nil {
		return
	}

	if response.StatusCode != http.StatusOK {
		fmt.Printf("HTTP Error: %v\n", response.StatusCode)
		return
	}

	_, err = io.Copy(file, response.Body)
	if err != nil {
		return
	}

	if err != nil {
		return
	}

	defer response.Body.Close()
	return

}