shithub: hell

ref: 16fd80edde8e3928854f8e600c5037459b97163d
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 (hc *Hellclient) previewPostImages(target *mastodon.Status, commandstring string) (err error) {

	var command string

	args, err := shlex.Split(commandstring)

	if len(args) < 0 {
		//No command
		return
	}

	command = args[0]
	args = args[1:]

	_, pathnames, err := downloadPostImages(target)

	if len(pathnames) == 0 {
		//We tolerate failing to download some items but if we have none then error out
		return
	}
	for file := range pathnames {
		defer os.Remove(pathnames[file])
	}

	args = append(args, pathnames...)

	cmd := exec.Command(command, args...)
	cmd.Stdout = os.Stdout
	//Let go of the lock while we wait for return
	hc.unlock()
	err = cmd.Run()
	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

}