Created
January 30, 2026 12:58
-
-
Save peterhellberg/81f3a773f9f264a70b317762c9d44b9b to your computer and use it in GitHub Desktop.
My script for downloading images I've posted to Imgur
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "errors" | |
| "flag" | |
| "fmt" | |
| "io" | |
| "net/http" | |
| "os" | |
| "path/filepath" | |
| "strings" | |
| "time" | |
| ) | |
| var ( | |
| defaultDir = "/var/www/assets.c7.se/imgur" | |
| defaultURL = "https://assets.c7.se/imgur/" | |
| defaultRaw = false | |
| ) | |
| const ( | |
| iImgurCom = `https://i.imgur.com/` | |
| firefoxUA = `Mozilla/5.0 (X11; Linux i686; rv:135.0) Gecko/20100101 Firefox/135.0` | |
| ) | |
| type config struct { | |
| dir string | |
| url string | |
| src string | |
| img string | |
| raw bool | |
| } | |
| func (cfg config) path() string { | |
| return filepath.Join(cfg.dir, cfg.img) | |
| } | |
| func (cfg config) out() string { | |
| return cfg.url + cfg.img | |
| } | |
| func main() { | |
| if err := run(os.Args, os.Stdout); err != nil { | |
| fmt.Fprintf(os.Stderr, "❌ %s\n", err) | |
| os.Exit(1) | |
| } | |
| } | |
| func run(args []string, w io.Writer) error { | |
| cfg, err := parse(args) | |
| if err != nil { | |
| return err | |
| } | |
| client := &http.Client{ | |
| Timeout: time.Minute, | |
| } | |
| if err := download(cfg, client); err != nil { | |
| return err | |
| } | |
| return output(w, cfg) | |
| } | |
| func request(cfg config) (*http.Request, error) { | |
| req, err := http.NewRequest(http.MethodGet, cfg.src, nil) | |
| if err != nil { | |
| return nil, err | |
| } | |
| req.Header.Set("User-Agent", firefoxUA) | |
| return req, nil | |
| } | |
| func download(cfg config, client *http.Client) error { | |
| name := cfg.path() | |
| if _, err := os.Stat(name); !errors.Is(err, os.ErrNotExist) { | |
| return fmt.Errorf("file already exists, served on %s", cfg.out()) | |
| } | |
| req, err := request(cfg) | |
| if err != nil { | |
| return err | |
| } | |
| resp, err := client.Do(req) | |
| if err != nil { | |
| return err | |
| } | |
| defer resp.Body.Close() | |
| if resp.StatusCode != http.StatusOK { | |
| return fmt.Errorf("bad status: %s", resp.Status) | |
| } | |
| dst, err := os.Create(name) | |
| if err != nil { | |
| return err | |
| } | |
| defer dst.Close() | |
| _, err = io.Copy(dst, resp.Body) | |
| return err | |
| } | |
| func output(w io.Writer, cfg config) error { | |
| if cfg.raw { | |
| return fprintf(w, "%s\n", cfg.out()) | |
| } | |
| return fprintf(w, "✅ file downloaded, served on %s\n", cfg.out()) | |
| } | |
| func fprintf(w io.Writer, format string, a ...any) error { | |
| _, err := fmt.Fprintf(w, format, a...) | |
| return err | |
| } | |
| func parse(args []string) (config, error) { | |
| var cfg config | |
| flags := flag.NewFlagSet(args[0], flag.ExitOnError) | |
| flags.StringVar(&cfg.dir, "dir", defaultDir, "Local directory to download to") | |
| flags.StringVar(&cfg.url, "url", defaultURL, "URL to construct links from") | |
| flags.BoolVar(&cfg.raw, "raw", defaultRaw, "If to output just the link URL") | |
| if err := flags.Parse(args[1:]); err != nil { | |
| return cfg, err | |
| } | |
| cfg.src = strings.Join(flags.Args(), "") | |
| switch { | |
| case cfg.src == "": | |
| return cfg, fmt.Errorf("no URL provided") | |
| case !strings.HasPrefix(cfg.src, iImgurCom): | |
| return cfg, fmt.Errorf("provided source %q does not have the required prefix %q", cfg.src, iImgurCom) | |
| } | |
| cfg.img = filepath.Base(cfg.src) | |
| return cfg, nil | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment