Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3970c611a4 | |||
| d8dc3e4ea8 | |||
| 3693d94297 | |||
| 8ded2b2e2d | |||
| e3e712d073 | |||
| 1ecac568f7 | |||
| 82ba3be742 | |||
|
|
4825dc56e6 | ||
| 65b9241492 | |||
|
|
73b33f5872 | ||
|
|
cc0fee57c2 | ||
|
|
05a3a0d09a | ||
|
|
72588642b6 | ||
|
|
7ff4685a70 | ||
|
|
f6b92ee8bd | ||
|
|
68d9ab7859 | ||
|
|
d2d7843b6f | ||
|
|
13589535a8 | ||
|
|
cb1f1d1a05 | ||
|
|
699ca9fcfc | ||
|
|
4e925136ba | ||
|
|
b37589985b | ||
| f60928fefb | |||
| 29fc0c67c9 | |||
| 6c3cb6066d | |||
| 1870313424 | |||
| 00218b6cc5 | |||
| fcf206b999 | |||
| 49c8ecd31a | |||
| 4c595d75d4 | |||
| 49d5ed58d0 | |||
| 77b7167d9c |
24
.gitignore
vendored
24
.gitignore
vendored
@@ -1,20 +1,4 @@
|
||||
/blib/
|
||||
/.build/
|
||||
_build/
|
||||
cover_db/
|
||||
inc/
|
||||
Build
|
||||
!Build/
|
||||
Build.bat
|
||||
.last_cover_stats
|
||||
/Makefile
|
||||
/Makefile.old
|
||||
/MANIFEST.bak
|
||||
/META.yml
|
||||
/META.json
|
||||
/MYMETA.*
|
||||
nytprof.out
|
||||
/pm_to_blib
|
||||
*.o
|
||||
*.bs
|
||||
/_eumm/
|
||||
dist
|
||||
release
|
||||
discord-auto-upload
|
||||
discord-auto-upload.exe
|
||||
|
||||
17
BINARIES.md
17
BINARIES.md
@@ -1,17 +0,0 @@
|
||||
# Building "binaries"
|
||||
|
||||
For perl toolchain-free distribution.
|
||||
|
||||
Install PAR::Packer first, then:
|
||||
|
||||
## Mac
|
||||
|
||||
pp -M IO::Socket::SSL -o dau-mac dau
|
||||
|
||||
## Linux
|
||||
|
||||
pp -M IO::Socket::SSL -o dau-linux dau
|
||||
|
||||
## Windows
|
||||
|
||||
pp -M IO::Socket::SSL -o dau.exe dau
|
||||
72
README.md
72
README.md
@@ -1,6 +1,6 @@
|
||||
# Automatically upload screenshots from your computer into a discord channel
|
||||
# Automatically upload screenshots into a discord channel
|
||||
|
||||
This script automaticall uploads new screenshots that appear in a folder on your computer to Discord and posts them in a channel:
|
||||
This program automatically uploads new screenshots that appear in a folder on your computer to Discord and posts them in a channel:
|
||||
|
||||

|
||||
|
||||
@@ -10,50 +10,22 @@ Point it at your Steam screenshot folder, or similar, and shortly after you hit
|
||||
|
||||
* A folder where screenshots are stored
|
||||
* A [discord webhook](https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks)
|
||||
* This script
|
||||
* perl installed (or the windows binary)
|
||||
* This program
|
||||
|
||||
## Getting started
|
||||
|
||||
### Linux
|
||||
### Binaries
|
||||
|
||||
* Download this script:
|
||||
Binaries are available for Mac, Linux and Windows [here](https://github.com/tardisx/discord-auto-upload/releases/latest).
|
||||
|
||||
`curl -O https://raw.githubusercontent.com/tardisx/discord-auto-upload/master/dau`
|
||||
Put them somewhere on your path and run from the command line.
|
||||
|
||||
* Put it somewhere on your path (if you want to be able to run it from anywhere)
|
||||
* chmod +x it
|
||||
* Install the dependencies:
|
||||
The windows version comes with a .bat file to make this a little easier - edit the `dau.bat` file to include your webhook URL and
|
||||
other parameters, then you can simply double click `dau.bat` to start `dau` running.
|
||||
|
||||
CPAN: `cpan install Mojolicious IO::Socket::SSL`
|
||||
#### From source
|
||||
|
||||
CPANM: `cpanm Mojolicious IO::Socket::SSL`
|
||||
|
||||
Ubuntu/Debian: `sudo apt-get install libmojolicious-perl libio-socket-ssl-perl`
|
||||
|
||||
* test it:
|
||||
|
||||
`dau --help`
|
||||
|
||||
### Mac
|
||||
|
||||
Basically the same as Linux above. [Perlbrew](https://perlbrew.pl) is highly recommended so as not to disturb the system perl. No need for superuser access then either.
|
||||
|
||||
### Windows
|
||||
|
||||
* Grab the windows exe file:
|
||||
|
||||
`http://tba`
|
||||
|
||||
* Optional, put it somewhere on your path
|
||||
* Open a command prompt
|
||||
* Test it
|
||||
|
||||
`\some\path\dau --help`
|
||||
|
||||
If you want to hack it, audit it, or don't trust my exe, you can install
|
||||
[Strawberry Perl](http://strawberryperl.com) and run it using that directly.
|
||||
You'll need the same dependencies mentioned above in the Linux setup.
|
||||
You'll need to [download Go](https://golang.org/dl/) check the code out somewhere, and 'go build'.
|
||||
|
||||
## Using it
|
||||
|
||||
@@ -65,30 +37,34 @@ Thus, you do not have to worry about pointing `dau` at a directory full of image
|
||||
|
||||
If `dau` is on your path, you can run it from your screenshot folder and there is then no need to specify the path to your images.
|
||||
|
||||
Note that currently `dau` does not look in subdirectories. Please submit an issue if this is a use case for you.
|
||||
|
||||
The only mandatory command line parameter is the discord webhook URL:
|
||||
The only two mandatory command line parameters are the discord webhook URL:
|
||||
|
||||
`--webhook URL` - the webhook URL (see [here](https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks) for details).
|
||||
|
||||
and the directory to watch:
|
||||
|
||||
`--directory /some/path/here` - the directory that screenshots will appear in.
|
||||
|
||||
You will have to quote the path on windows, or anywhere where the directory path contains spaces. Note that
|
||||
subdirectories will also be scanned.
|
||||
|
||||
Other parameters are:
|
||||
|
||||
`--exclude <string>` - exclude any files that contain this string (commonly used to avoid uploading thumbnails).
|
||||
|
||||
`--watch xx` - specify how many seconds to wait between scanning the directory. The default is 10 seconds.
|
||||
|
||||
`--directory <somedir>` - the directory to watch for images to appear in. If this option is not supplied, will look in the current directory.
|
||||
`--username <username>` - an arbitrary string to show as the bot's username in the channel.
|
||||
|
||||
You will have to quote the path on windows, or anywhere where the directory path contains spaces.
|
||||
`--no-watermark` - don't watermark images with a reference to this tool.
|
||||
|
||||
`--username` - supply a 'username' with the webhook submission. Slightly misleading, it basically provides some extra text next to the "Bot" display on the upload to the channel.
|
||||
`--help` - show command line help.
|
||||
|
||||
In the example screenshot, this was set to "tardisx uploaded from EDD".
|
||||
|
||||
`--debug` - provide extra debugging.
|
||||
`--version` - show the version.
|
||||
|
||||
## Limitations/bugs
|
||||
|
||||
* Only files ending jpg, gif or png are uploaded.
|
||||
* Subdirectories are not scanned.
|
||||
* If multiple screenshots occur quickly (<1 second apart) not all may be uploaded.
|
||||
|
||||
## TODO
|
||||
|
||||
52
build-release.pl
Executable file
52
build-release.pl
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
open my $fh, "<", "dau.go" || die $!;
|
||||
|
||||
my $version;
|
||||
while (<$fh>) {
|
||||
$version = $1 if /^const\s+currentVersion.*?"([\d\.]+)"/;
|
||||
}
|
||||
close $fh;
|
||||
|
||||
die "no version?" unless defined $version;
|
||||
|
||||
# so lazy
|
||||
system "rm", "-rf", "release", "dist";
|
||||
system "mkdir", "release";
|
||||
system "mkdir", "dist";
|
||||
|
||||
my %build = (
|
||||
win => { env => { GOOS => 'windows', GOARCH => '386' }, filename => 'dau.exe' },
|
||||
linux => { env => { GOOS => 'linux', GOARCH => '386' }, filename => 'dau' },
|
||||
mac => { env => { GOOS => 'darwin', GOARCH => '386' }, filename => 'dau' },
|
||||
);
|
||||
|
||||
foreach my $type (keys %build) {
|
||||
mkdir "release/$type";
|
||||
}
|
||||
|
||||
add_extras();
|
||||
|
||||
foreach my $type (keys %build) {
|
||||
local $ENV{GOOS} = $build{$type}->{env}->{GOOS};
|
||||
local $ENV{GOARCH} = $build{$type}->{env}->{GOARCH};
|
||||
system "go", "build", "-o", "release/$type/" . $build{$type}->{filename};
|
||||
system "zip", "-j", "dist/dau-$type-$version.zip", ( glob "release/$type/*" );
|
||||
}
|
||||
|
||||
sub add_extras {
|
||||
# bat file for windows
|
||||
|
||||
open (my $fh, ">", "release/win/dau.bat") || die $!;
|
||||
print $fh 'set WEBHOOK_URL=https://yourdiscordwebhookURLhere' . "\r\n";
|
||||
print $fh 'set SCREENSHOTS="C:\your\screenshot\directory\here"' ."\r\n";
|
||||
print $fh 'set USERNAME="Posted by Joe Bloggs"' . "\r\n";
|
||||
print $fh 'set WATCH=10' . "\r\n";
|
||||
|
||||
print $fh 'dau.exe --webhook %WEBHOOK_URL% --directory %SCREENSHOTS% --username %USERNAME% --watch %WATCH%' . "\r\n";
|
||||
print $fh 'pause' . "\r\n";
|
||||
close $fh;
|
||||
}
|
||||
128
dau
128
dau
@@ -1,128 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use feature 'say';
|
||||
|
||||
use Mojo::UserAgent;
|
||||
use Getopt::Long qw/GetOptions/;
|
||||
use Data::Dumper qw/Dumper/;
|
||||
|
||||
my $webhook_url;
|
||||
my $directory = "./";
|
||||
my $username;
|
||||
my $watch = 10;
|
||||
my $help;
|
||||
my $debug;
|
||||
my $now = time();
|
||||
my $error_count = 0;
|
||||
my $error_max = 10;
|
||||
my $version = '0.1';
|
||||
|
||||
GetOptions(
|
||||
"webhook=s" => \$webhook_url,
|
||||
"directory=s" => \$directory,
|
||||
"username=s" => \$username,
|
||||
"watch=i" => \$watch,
|
||||
"help" => \$help,
|
||||
"debug" => \$debug,
|
||||
) || die usage();
|
||||
|
||||
usage() if $help;
|
||||
|
||||
if (! $webhook_url) {
|
||||
usage("--webhook must be supplied");
|
||||
}
|
||||
|
||||
sub usage {
|
||||
my $error = shift || "";
|
||||
my $indent = " " x length($0);
|
||||
say "dau $version - https://github.com/tardisx/discord-auto-upload\n";
|
||||
say "$0 --webhook <url> [--directory </some/path>]";
|
||||
say "$indent [--username <\"custom username\">] [--watch <n>]\n";
|
||||
say "The current directory will be used if no directory is specified.\n";
|
||||
say "error: $error" if $error;
|
||||
exit defined $error ? 1 : 0;
|
||||
}
|
||||
|
||||
chdir $directory || die "cannot chdir to $directory: $!\n";
|
||||
|
||||
watch_dir();
|
||||
|
||||
sub watch_dir {
|
||||
while (1) {
|
||||
my @files = glob("*");
|
||||
@files = grep { qualifies($_) } @files;
|
||||
foreach my $file (sort { mtime($a) <=> mtime($b) } @files) {
|
||||
debug("examining $file");
|
||||
if (mtime($file) > $now) {
|
||||
$now = mtime($file);
|
||||
upload($file);
|
||||
}
|
||||
}
|
||||
sleep $watch;
|
||||
}
|
||||
}
|
||||
|
||||
sub mtime {
|
||||
my $f = shift;
|
||||
return (stat($f))[9];
|
||||
}
|
||||
|
||||
sub qualifies {
|
||||
my $filename = shift;
|
||||
return 1 if ($filename =~ /\.jpg$|\.gif$|\.png$/i);
|
||||
return;
|
||||
}
|
||||
|
||||
sub info {
|
||||
say "- " . shift;
|
||||
}
|
||||
|
||||
sub debug {
|
||||
return unless $debug;
|
||||
say "! " . shift;
|
||||
}
|
||||
|
||||
sub error {
|
||||
say "* " . shift;
|
||||
}
|
||||
|
||||
sub upload {
|
||||
my $file = shift;
|
||||
info("uploading $file");
|
||||
|
||||
my $ua = Mojo::UserAgent->new;
|
||||
my $data = {
|
||||
upload => { file => $file },
|
||||
$username ? ( username => $username ) : ()
|
||||
};
|
||||
|
||||
my $tx = $ua->post($webhook_url, form => $data);
|
||||
|
||||
if (my $res = $tx->success) {
|
||||
debug(Dumper($res->json));
|
||||
my $url = $res->json->{attachments}->[0]->{url};
|
||||
my $size = $res->json->{attachments}->[0]->{size};
|
||||
my $width = $res->json->{attachments}->[0]->{width};
|
||||
my $height = $res->json->{attachments}->[0]->{height};
|
||||
info("uploaded ${width}x${height} $size bytes images to $url, submitted to webhook successfully");
|
||||
}
|
||||
else {
|
||||
debug(Dumper($tx));
|
||||
|
||||
my $err = $tx->error;
|
||||
if ($err->{code}) {
|
||||
error("$err->{code} response: $err->{message}");
|
||||
}
|
||||
else {
|
||||
error("Connection error: $err->{message}");
|
||||
}
|
||||
$error_count++;
|
||||
if ($error_count >= $error_max) {
|
||||
error("Sorry - too many errors - quitting");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
366
dau.go
Normal file
366
dau.go
Normal file
@@ -0,0 +1,366 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"image"
|
||||
|
||||
_ "image/gif"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
|
||||
"github.com/fogleman/gg"
|
||||
"github.com/pborman/getopt"
|
||||
"golang.org/x/image/font/inconsolata"
|
||||
)
|
||||
|
||||
const currentVersion = "0.6"
|
||||
|
||||
var lastCheck = time.Now()
|
||||
var newLastCheck = time.Now()
|
||||
|
||||
// Config for the application
|
||||
type Config struct {
|
||||
webhookURL string
|
||||
path string
|
||||
watch int
|
||||
username string
|
||||
noWatermark bool
|
||||
exclude string
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
config := parseOptions()
|
||||
|
||||
checkPath(config.path)
|
||||
checkUpdates()
|
||||
|
||||
log.Print("Waiting for images to appear in ", config.path)
|
||||
// wander the path, forever
|
||||
for {
|
||||
err := filepath.Walk(config.path,
|
||||
func(path string, f os.FileInfo, err error) error { return checkFile(path, f, err, config) })
|
||||
if err != nil {
|
||||
log.Fatal("could not watch path", err)
|
||||
}
|
||||
lastCheck = newLastCheck
|
||||
time.Sleep(time.Duration(config.watch) * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func checkPath(path string) {
|
||||
src, err := os.Stat(path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if !src.IsDir() {
|
||||
log.Fatal(path, " is not a directory")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func checkUpdates() {
|
||||
|
||||
type GithubRelease struct {
|
||||
HTMLURL string
|
||||
TagName string
|
||||
Name string
|
||||
Body string
|
||||
}
|
||||
|
||||
client := &http.Client{Timeout: time.Second * 5}
|
||||
resp, err := client.Get("https://api.github.com/repos/tardisx/discord-auto-upload/releases/latest")
|
||||
if err != nil {
|
||||
log.Fatal("could not check for updates:", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Fatal("could not check read update response")
|
||||
}
|
||||
|
||||
var latest GithubRelease
|
||||
err = json.Unmarshal(body, &latest)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("could not parse JSON: ", err)
|
||||
}
|
||||
|
||||
if currentVersion < latest.TagName {
|
||||
fmt.Printf("You are currently on version %s, but version %s is available\n", currentVersion, latest.TagName)
|
||||
fmt.Println("----------- Release Info -----------")
|
||||
fmt.Println(latest.Body)
|
||||
fmt.Println("------------------------------------")
|
||||
fmt.Println("Upgrade at https://github.com/tardisx/discord-auto-upload/releases/latest")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func parseOptions() Config {
|
||||
|
||||
var newConfig Config
|
||||
// Declare the flags to be used
|
||||
webhookFlag := getopt.StringLong("webhook", 'w', "", "discord webhook URL")
|
||||
pathFlag := getopt.StringLong("directory", 'd', "", "directory to scan, optional, defaults to current directory")
|
||||
watchFlag := getopt.Int16Long("watch", 's', 10, "time between scans")
|
||||
usernameFlag := getopt.StringLong("username", 'u', "", "username for the bot upload")
|
||||
excludeFlag := getopt.StringLong("exclude", 'x', "", "exclude files containing this string")
|
||||
noWatermarkFlag := getopt.BoolLong("no-watermark", 'n', "do not put a watermark on images before uploading")
|
||||
helpFlag := getopt.BoolLong("help", 'h', "help")
|
||||
versionFlag := getopt.BoolLong("version", 'v', "show version")
|
||||
getopt.SetParameters("")
|
||||
|
||||
getopt.Parse()
|
||||
|
||||
if *helpFlag {
|
||||
getopt.PrintUsage(os.Stderr)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if *versionFlag {
|
||||
fmt.Println("dau - https://github.com/tardisx/discord-auto-upload")
|
||||
fmt.Printf("Version: %s\n", currentVersion)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if !getopt.IsSet("directory") {
|
||||
*pathFlag = "./"
|
||||
log.Println("Defaulting to current directory")
|
||||
}
|
||||
|
||||
if !getopt.IsSet("webhook") {
|
||||
log.Fatal("ERROR: You must specify a --webhook URL")
|
||||
}
|
||||
|
||||
newConfig.path = *pathFlag
|
||||
newConfig.webhookURL = *webhookFlag
|
||||
newConfig.watch = int(*watchFlag)
|
||||
newConfig.username = *usernameFlag
|
||||
newConfig.noWatermark = *noWatermarkFlag
|
||||
newConfig.exclude = *excludeFlag
|
||||
|
||||
return newConfig
|
||||
}
|
||||
|
||||
func checkFile(path string, f os.FileInfo, err error, config Config) error {
|
||||
|
||||
if f.ModTime().After(lastCheck) && f.Mode().IsRegular() {
|
||||
|
||||
if fileEligible(config, path) {
|
||||
// process file
|
||||
processFile(config, path)
|
||||
}
|
||||
|
||||
if newLastCheck.Before(f.ModTime()) {
|
||||
newLastCheck = f.ModTime()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func fileEligible(config Config, file string) bool {
|
||||
|
||||
if config.exclude != "" && strings.Contains(file, config.exclude) {
|
||||
return false
|
||||
}
|
||||
|
||||
extension := strings.ToLower(filepath.Ext(file))
|
||||
if extension == ".png" || extension == ".jpg" || extension == ".gif" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func processFile(config Config, file string) {
|
||||
|
||||
if !config.noWatermark {
|
||||
log.Print("Copying to temp location and watermarking ", file)
|
||||
file = mungeFile(file)
|
||||
}
|
||||
|
||||
log.Print("Uploading ", file)
|
||||
|
||||
extraParams := map[string]string{}
|
||||
|
||||
if config.username != "" {
|
||||
extraParams["username"] = config.username
|
||||
}
|
||||
|
||||
type DiscordAPIResponseAttachment struct {
|
||||
URL string
|
||||
ProxyURL string
|
||||
Size int
|
||||
Width int
|
||||
Height int
|
||||
Filename string
|
||||
}
|
||||
|
||||
type DiscordAPIResponse struct {
|
||||
Attachments []DiscordAPIResponseAttachment
|
||||
ID int64 `json:",string"`
|
||||
}
|
||||
|
||||
var retriesRemaining = 5
|
||||
for retriesRemaining > 0 {
|
||||
request, err := newfileUploadRequest(config.webhookURL, extraParams, "file", file)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
start := time.Now()
|
||||
client := &http.Client{Timeout: time.Second * 30}
|
||||
resp, err := client.Do(request)
|
||||
if err != nil {
|
||||
log.Print("Error performing request:", err)
|
||||
retriesRemaining--
|
||||
sleepForRetries(retriesRemaining)
|
||||
continue
|
||||
} else {
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
log.Print("Bad response from server:", resp.StatusCode)
|
||||
retriesRemaining--
|
||||
sleepForRetries(retriesRemaining)
|
||||
continue
|
||||
}
|
||||
|
||||
resBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Print("could not deal with body: ", err)
|
||||
retriesRemaining--
|
||||
sleepForRetries(retriesRemaining)
|
||||
continue
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
var res DiscordAPIResponse
|
||||
err = json.Unmarshal(resBody, &res)
|
||||
|
||||
if err != nil {
|
||||
log.Print("could not parse JSON: ", err)
|
||||
fmt.Println("Response was:", string(resBody[:]))
|
||||
retriesRemaining--
|
||||
sleepForRetries(retriesRemaining)
|
||||
continue
|
||||
}
|
||||
if len(res.Attachments) < 1 {
|
||||
log.Print("bad response - no attachments?")
|
||||
retriesRemaining--
|
||||
sleepForRetries(retriesRemaining)
|
||||
continue
|
||||
}
|
||||
var a = res.Attachments[0]
|
||||
elapsed := time.Since(start)
|
||||
rate := float64(a.Size) / elapsed.Seconds() / 1024.0
|
||||
|
||||
log.Printf("Uploaded to %s %dx%d", a.URL, a.Width, a.Height)
|
||||
log.Printf("id: %d, %d bytes transferred in %.2f seconds (%.2f KiB/s)", res.ID, a.Size, elapsed.Seconds(), rate)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !config.noWatermark {
|
||||
log.Print("Removing temporary file ", file)
|
||||
os.Remove(file)
|
||||
}
|
||||
|
||||
if retriesRemaining == 0 {
|
||||
log.Fatal("Failed to upload, even after retries")
|
||||
}
|
||||
}
|
||||
|
||||
func sleepForRetries(retry int) {
|
||||
if retry == 0 {
|
||||
return
|
||||
}
|
||||
retryTime := (6-retry)*(6-retry) + 6
|
||||
log.Printf("Will retry in %d seconds (%d remaining attempts)", retryTime, retry)
|
||||
// time.Sleep(time.Duration(retryTime) * time.Second)
|
||||
}
|
||||
|
||||
func newfileUploadRequest(uri string, params map[string]string, paramName, path string) (*http.Request, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
part, err := writer.CreateFormFile(paramName, filepath.Base(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = io.Copy(part, file)
|
||||
if err != nil {
|
||||
log.Fatal("Could not copy: ", err)
|
||||
}
|
||||
|
||||
for key, val := range params {
|
||||
_ = writer.WriteField(key, val)
|
||||
}
|
||||
err = writer.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", uri, body)
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
return req, err
|
||||
}
|
||||
|
||||
func mungeFile(path string) string {
|
||||
|
||||
reader, err := os.Open(path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
im, _, err := image.Decode(reader)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
bounds := im.Bounds()
|
||||
// var S float64 = float64(bounds.Max.X)
|
||||
|
||||
dc := gg.NewContext(bounds.Max.X, bounds.Max.Y)
|
||||
dc.Clear()
|
||||
dc.SetRGB(0, 0, 0)
|
||||
|
||||
dc.SetFontFace(inconsolata.Regular8x16)
|
||||
|
||||
dc.DrawImage(im, 0, 0)
|
||||
|
||||
dc.DrawRoundedRectangle(0, float64(bounds.Max.Y-18.0), 320, float64(bounds.Max.Y), 0)
|
||||
dc.SetRGB(0, 0, 0)
|
||||
dc.Fill()
|
||||
|
||||
dc.SetRGB(1, 1, 1)
|
||||
|
||||
dc.DrawString("github.com/tardisx/discord-auto-upload", 5.0, float64(bounds.Max.Y)-5.0)
|
||||
|
||||
tempfile, err := ioutil.TempFile("", "dau")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
tempfile.Close()
|
||||
os.Remove(tempfile.Name())
|
||||
actualName := tempfile.Name() + ".png"
|
||||
|
||||
dc.SavePNG(actualName)
|
||||
return actualName
|
||||
}
|
||||
Reference in New Issue
Block a user