I'm trying to write a "Download Page Website", and I trying to show the file icon to my webpage.
Like Windows system, ".exe" file has icon image inside. Or linux executable file. Can I read it?
I know python can do it with a package name "win32api", is it any package for Golang to achieve this function?
You can use the linux package in your advantage.
For example, you can use icoextract, which can be installed via apt:
apt install icoextract
And then run it like this:
icoextract /path/to/file.exe /path/to/file.ico
Go make possible to call commands and execute them using the package os/exec. So you can do something like
func ExtractIcon(executablePath string) []byte {
file, err := ioutil.TempFile("dir", "prefix")
if err != nil {
log.Fatal(err)
}
defer os.Remove(file.Name())
cmd := exec.Command("icoextract", executablePath, file.Name())
if err = cmd.Run(); err != nil {
log.Fatal(err)
}
content, _ := ioutil.ReadFile(file.Name())
return content
}
Related
I'm trying to execute .ics file that my program just created. Basically, my program is simple CLI calendar app, which generates .ics file. It would be nice if my program would execute this file and add it straight to OS calendar app, without unnecessary searching and executing through OS GUI.
I paste main function to better understanding.
func main() {
serialized, name := cal()
f, err := os.Create(name + ".ics")
if err != nil {
log.Fatal(err)
}
defer f.Close()
_, err2 := f.WriteString(serialized)
if err2 != nil {
log.Fatal(err2)
}
cmd := exec.Command(name + ".ics")
err = cmd.Run()
if err != nil {
log.Fatal(err)
}
}
As it's shown I tried with exec.Command, but it doesnt' work. I was even trying with additional prefixes like ./ or ~/, but it as well didn't work.
Error messages:
fork/exec ./Meeting.ics: permission denied
exec: "Meeting.ics": executable file not found in $PATH
So to sum it up - I want to skip the process where the user has to find a file and open it. I want to make it automatically as a part of my application.
Here's my repository if it would help https://github.com/lenoopaleno/golang-calendar
I'm working on WSL 2, Ubuntu 22.04
Beside the comments above, you might have a problem in your code with the defer f.Close()
The defer runs when the function ends. Until that time your file might or might not be closed and accessible by a different process.
Second you will most likely have to set an execute flag on the a program to run under unix style operating systems.
Program adjustment:
func main() {
serialized, name := cal()
f, err := os.Create(name + ".ics")
if err != nil {
log.Fatal(err)
}
_, err2 := f.WriteString(serialized)
if err2 != nil {
log.Fatal(err2)
}
f.Sync()
f.Close()
exec.Command(`chmod +x `+name+".ics").Run() // This can be done prettier
cmd := exec.Command(name + ".ics")
err = cmd.Run()
if err != nil {
log.Fatal(err)
}
}
Im using the following code to install chart that is bounded in my source code (eg. in my app/chart/chart1 in my go bin app), Now I need to move the chart to git repository or to artifactory,
My question is how can I install the chart from outside my program?
This is the code I use which works for bundled chart
I use the helm3 loader package which works when I have the chart bundled in my app
chart, err := loader.Load(“chart/chart1”)
https://pkg.go.dev/helm.sh/helm/v3#v3.5.4/pkg/chart/loader
Should I load it somehow with an http call or helm have some built in functionality ? we need some efficient way to handle it
It seems that helm during its upgrade/install commands checks first a couple of different locations which you can see getting called here. The content of that function is here.
And then continues here with loader.Load
You can use something like this for installing nginx chart
myChart, err := loader.Load("https://charts.bitnami.com/bitnami/nginx-8.8.4.tgz")
...
install := action.NewInstall(m.actionConfig)
install.ReleaseName = "my-release"
...
myRelease, err := install.Run(myChart, myValues)
It would be similar to:
helm install my-release https://charts.bitnami.com/bitnami/nginx-8.8.4.tgz
loader.load checks only for files and directories. If you want to use URL helm sdk provides LocateChart method in Install interface. Here is an example:
settings := cli.New()
actionConfig := new(action.Configuration)
if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
log.Printf("%+v", err)
os.Exit(1)
}
client := action.NewInstall(actionConfig)
chrt_path, err := client.LocateChart("https://github.com/kubernetes/ingress-nginx/releases/download/helm-chart-4.0.6/ingress-nginx-4.0.6.tgz", settings); if err != nil {
panic(err)
}
myChart, err := loader.Load(chrt_path); if err != nil {
panic(err)
}
Then you can simple setup install options and call client.Run method.
I'm trying to play a sound from Golang. It's a .wav file. And I want to package the .wav file into the executable using packr
I have created a very small project here: packr-test repository with the code.
When I run the executable (./packr-test) in it's default folder, the sound plays.
But the problem I'm having is that when I move the executable to another directory, I get an error trying to play the sound file. Which I think probably means the sound file isn't being bundled up with the executable.
This is on Ubuntu. I'm using the 'play' command which is often installed by default, but if it's not there, can be done with:
sudo apt-get install sox
sudo apt-get install sox libsox-fmt-all
To use play command:
play file_name.extension
To save you looking it up, here is my Go code:
package main
import (
"fmt"
"os/exec"
"github.com/gobuffalo/packr"
)
func main() {
soundsBox := packr.NewBox("./sounds")
if soundsBox.Has("IEEE_float_mono_32kHz.wav") {
fmt.Println("It's there.")
} else {
fmt.Println("It's not there.")
}
args := []string{"-v20", "./sounds/IEEE_float_mono_32kHz.wav"}
output, err := exec.Command("play", args...).Output()
if err != nil {
// Play command was not successful
fmt.Println("Got an error.")
fmt.Println(err.Error())
} else {
fmt.Println(string(output))
}
}
Here is my output:
sudo ./packr-test
It's there.
Got an error.
exit status 2
You're still referencing the file on the file system, even though you have it packed into the binary:
args := []string{"-v20", "./sounds/IEEE_float_mono_32kHz.wav"}
output, err := exec.Command("play", args...).Output()
You can grab the file data from your packr box like this:
bytes, err := soundsBox.FindBytes("IEEE_float_mono_32kHz.wav")
To execute the file with exec.Command() I think you'll have to write those bytes back to the file system:
err := ioutil.WriteFile("/tmp/IEEE_float_mono_32kHz.wav", bytes, 0755)
exec.Command("play", []string{"-v20", "/tmp/IEEE_float_mono_32kHz.wav"}
You might be able to pass your bytes to play via stdin, but that would depend on how the play binary works.
cmd.Stdin = bytes
cmd.Run()
Is there a way to call the Go tools (like go build) programmatically from within another Go program with a library call and to get more structured output compared to the text output from the command line invocation?
If you're trying to run build programmatically you can also use the os/exec package.
func runBuild() {
cmd := exec.Command("go", "build", "./main.go")
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
You can pass other flags too. E.g: the buildmode flag
cmd := exec.Command("go", "build", "-buildmode=plugin", "./main.go")
Reference: https://golang.org/pkg/os/exec/
Within another go program it is possible to execute console commands using the os/exec package like so:
func main (){
cmd := exec.Command("go run lib/main.go")
if err := cmd.Run(); err != nil{
log.Fatal(err)
}
}
I don't see this being very useful though.
I am using golang revel web framework and
I am trying to create a sqlite db in the current working directory.
model.go
func New(dbName string,table string) *Db {
_,filename,_,_ := runtime.Caller(1)
db , err := sql.Open("sqlite3",path.Join(path.Dir(filename),dbName))
if err != nil {
log.Fatal(err)
}
err = db.Ping()
if err != nil {
log.Panic(err)
}
database := &Db{Database:db}
_,err = db.Exec("create table %s" +
"( id integer primary key, " +
"name varchar(100),"+
"email varchar(100),"+
"branch varchar(100),"+
"help varchar(100)",)
if err != nil {
log.Fatal(err)
}
}
I have a test in place which just calls this function.
whenever i run the test using revel test or by going to the localhost:9000/#tests, the function Panics and the error message is
cannot open the database file.
The reason that is happening is because the filename returned by runtime.Caller(1) is /usr/local/go/src/runtime/asm_amd64.s for which the program has no permission.
if i directly write ./foo.db, even then the error shows.
I tried os.Getwd() which return empty string.
I also tried filepath.Abs(filepath.Dir(os.Args[0]))
but that returned /home/girish/GoProjects/bin/revel.d which is the revel binary.
So whats the best way to find the directory of the model.go?
It doesn't make sense to get the directory of the model.go file at runtime, because the compiled executable could be on a completely different filesystem.
You may want to get the directory of where the running executable was started from:
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
dir will be the folder where the program lives at runtime.