2017-02-20 21:16:44 +10:30
package main
import (
2021-10-10 13:43:36 +10:30
"context"
2021-10-06 23:12:43 +10:30
"flag"
2017-02-22 21:13:07 +10:30
"fmt"
2021-10-06 23:12:43 +10:30
"io/fs"
2017-02-22 21:13:07 +10:30
"log"
"os"
"path/filepath"
"strings"
"time"
2017-02-26 21:06:48 +10:30
_ "image/gif"
_ "image/jpeg"
_ "image/png"
2021-01-31 17:53:32 +10:30
// "github.com/skratchdot/open-golang/open"
2017-07-26 14:24:02 +09:30
2021-01-31 17:53:32 +10:30
"github.com/tardisx/discord-auto-upload/config"
2021-06-03 19:36:48 +09:30
daulog "github.com/tardisx/discord-auto-upload/log"
2021-10-06 23:12:43 +10:30
"github.com/tardisx/discord-auto-upload/upload"
// "github.com/tardisx/discord-auto-upload/upload"
2021-10-04 12:20:16 +10:30
"github.com/tardisx/discord-auto-upload/version"
2021-01-31 18:48:48 +10:30
"github.com/tardisx/discord-auto-upload/web"
2017-02-20 21:16:44 +10:30
)
2021-10-06 23:12:43 +10:30
type watch struct {
lastCheck time . Time
newLastCheck time . Time
config config . Watcher
2021-10-10 14:44:12 +10:30
uploader * upload . Uploader
2021-10-06 23:12:43 +10:30
}
2017-02-21 12:24:14 +10:30
2017-02-20 21:16:44 +10:30
func main ( ) {
2017-02-22 21:13:07 +10:30
2021-01-31 17:53:32 +10:30
parseOptions ( )
2017-07-26 14:24:02 +09:30
2021-10-10 13:43:36 +10:30
// grab the config, register to notice changes
2021-10-06 23:12:43 +10:30
config := config . DefaultConfigService ( )
2021-10-10 13:43:36 +10:30
configChanged := make ( chan bool )
config . Changed = configChanged
2021-10-06 23:12:43 +10:30
config . LoadOrInit ( )
// create the uploader
2021-10-10 14:44:12 +10:30
up := upload . NewUploader ( )
2021-10-06 23:12:43 +10:30
2021-01-31 17:53:32 +10:30
// log.Print("Opening web browser")
// open.Start("http://localhost:9090")
2021-10-10 14:44:12 +10:30
web := web . WebService { Config : config , Uploader : up }
2021-06-02 23:42:29 +09:30
web . StartWebServer ( )
2017-07-27 22:04:47 +09:30
2022-04-03 20:33:20 +09:30
go func ( ) {
version . GetOnlineVersion ( )
if version . UpdateAvailable ( ) {
fmt . Printf ( "You are currently on version %s, but version %s is available\n" , version . CurrentVersion , version . LatestVersionInfo . TagName )
fmt . Println ( "----------- Release Info -----------" )
fmt . Println ( version . LatestVersionInfo . Body )
fmt . Println ( "------------------------------------" )
fmt . Println ( "Upgrade at https://github.com/tardisx/discord-auto-upload/releases/latest" )
daulog . SendLog ( fmt . Sprintf ( "New version available: %s - download at https://github.com/tardisx/discord-auto-upload/releases/latest" , version . LatestVersionInfo . TagName ) , daulog . LogTypeInfo )
}
} ( )
2021-10-06 23:12:43 +10:30
2021-10-10 13:43:36 +10:30
// create the watchers, restart them if config changes
// blocks forever
2021-10-10 14:44:12 +10:30
startWatchers ( config , up , configChanged )
2017-07-26 22:40:21 +09:30
2021-10-10 13:43:36 +10:30
}
2021-10-06 23:12:43 +10:30
2021-10-10 13:43:36 +10:30
func startWatchers ( config * config . ConfigService , up * upload . Uploader , configChange chan bool ) {
for {
2021-10-10 14:54:08 +10:30
daulog . SendLog ( "Creating watchers" , daulog . LogTypeInfo )
2021-10-10 13:43:36 +10:30
ctx , cancel := context . WithCancel ( context . Background ( ) )
for _ , c := range config . Config . Watchers {
log . Printf ( "Creating watcher for %s interval %d" , c . Path , config . Config . WatchInterval )
2021-10-10 14:44:12 +10:30
watcher := watch { uploader : up , lastCheck : time . Now ( ) , newLastCheck : time . Now ( ) , config : c }
2021-10-10 13:43:36 +10:30
go watcher . Watch ( config . Config . WatchInterval , ctx )
}
// wait for single that the config changed
<- configChange
cancel ( )
2021-10-10 14:54:08 +10:30
daulog . SendLog ( "starting new watchers due to config change" , daulog . LogTypeInfo )
2021-10-06 23:12:43 +10:30
}
}
2021-10-10 13:43:36 +10:30
func ( w * watch ) Watch ( interval int , ctx context . Context ) {
2017-02-22 21:13:07 +10:30
for {
2021-10-10 13:43:36 +10:30
select {
case <- ctx . Done ( ) :
2021-10-10 14:54:08 +10:30
daulog . SendLog ( "Killing old watcher" , daulog . LogTypeInfo )
2021-10-10 13:43:36 +10:30
return
default :
newFiles := w . ProcessNewFiles ( )
for _ , f := range newFiles {
w . uploader . AddFile ( f , w . config )
}
// upload them
w . uploader . Upload ( )
daulog . SendLog ( fmt . Sprintf ( "sleeping for %ds before next check of %s" , interval , w . config . Path ) , daulog . LogTypeDebug )
time . Sleep ( time . Duration ( interval ) * time . Second )
2017-02-22 21:13:07 +10:30
}
2017-07-27 12:18:02 +09:30
}
}
2021-10-06 23:12:43 +10:30
// ProcessNewFiles returns an array of new files that have appeared since
// the last time ProcessNewFiles was run.
func ( w * watch ) ProcessNewFiles ( ) [ ] string {
var newFiles [ ] string
// check the path each time around, in case it goes away or something
if w . checkPath ( ) {
// walk the path
err := filepath . WalkDir ( w . config . Path ,
func ( path string , d fs . DirEntry , err error ) error {
2021-10-10 12:00:25 +10:30
return w . checkFile ( path , & newFiles , w . config . Exclude )
2021-10-06 23:12:43 +10:30
} )
if err != nil {
log . Fatal ( "could not watch path" , err )
}
w . lastCheck = w . newLastCheck
}
return newFiles
}
// checkPath makes sure the path exists, and is a directory.
// It logs errors if there are problems, and returns false
func ( w * watch ) checkPath ( ) bool {
src , err := os . Stat ( w . config . Path )
2017-02-22 21:13:07 +10:30
if err != nil {
2021-10-10 14:54:08 +10:30
daulog . SendLog ( fmt . Sprintf ( "Problem with path '%s': %s" , w . config . Path , err ) , daulog . LogTypeError )
2021-02-07 11:42:13 +10:30
return false
2017-02-22 21:13:07 +10:30
}
if ! src . IsDir ( ) {
2021-10-10 14:54:08 +10:30
daulog . SendLog ( fmt . Sprintf ( "Problem with path '%s': is not a directory" , w . config . Path ) , daulog . LogTypeError )
2021-02-07 11:42:13 +10:30
return false
2017-02-22 21:13:07 +10:30
}
2021-02-07 11:42:13 +10:30
return true
2017-02-21 17:10:00 +10:30
}
2021-10-06 23:12:43 +10:30
// checkFile checks if a file is eligible, first looking at extension (to
// avoid statting files uselessly) then modification times.
2021-10-10 12:00:25 +10:30
// If the file is eligible, not excluded and new enough to care we add it
// to the passed in array of files
func ( w * watch ) checkFile ( path string , found * [ ] string , exclusions [ ] string ) error {
2021-10-06 23:12:43 +10:30
extension := strings . ToLower ( filepath . Ext ( path ) )
if ! ( extension == ".png" || extension == ".jpg" || extension == ".gif" ) {
return nil
}
fi , err := os . Stat ( path )
if err != nil {
return err
}
if fi . ModTime ( ) . After ( w . lastCheck ) && fi . Mode ( ) . IsRegular ( ) {
2021-10-10 12:00:25 +10:30
excluded := false
for _ , exclusion := range exclusions {
if strings . Contains ( path , exclusion ) {
excluded = true
}
}
if ! excluded {
* found = append ( * found , path )
}
2021-10-06 23:12:43 +10:30
}
if w . newLastCheck . Before ( fi . ModTime ( ) ) {
w . newLastCheck = fi . ModTime ( )
}
return nil
}
2021-01-31 17:53:32 +10:30
func parseOptions ( ) {
2021-10-06 23:12:43 +10:30
var versionFlag bool
flag . BoolVar ( & versionFlag , "version" , false , "show version" )
flag . Parse ( )
2017-02-20 21:16:44 +10:30
2021-10-06 23:12:43 +10:30
if versionFlag {
2017-02-22 21:13:07 +10:30
fmt . Println ( "dau - https://github.com/tardisx/discord-auto-upload" )
2021-10-04 12:20:16 +10:30
fmt . Printf ( "Version: %s\n" , version . CurrentVersion )
2017-02-22 21:13:07 +10:30
os . Exit ( 0 )
}
2017-02-21 12:24:14 +10:30
2017-02-26 21:06:48 +10:30
}