From 3ac9b475e0b0b6d7d652ec0d87a6908204b2d664 Mon Sep 17 00:00:00 2001 From: "Romain J." Date: Tue, 19 Mar 2024 17:20:55 +0100 Subject: [PATCH] first commit --- .gitignore | 118 +++++++++++++++++++++++++++++++++++++++++++++ Makefile | 7 +++ api/content.go | 31 ++++++++++++ api/guest.go | 55 +++++++++++++++++++++ app.go | 17 +++++++ go.mod | 10 ++++ go.sum | 17 +++++++ misc/constants.go | 4 ++ misc/fetch.go | 39 +++++++++++++++ misc/generator.go | 21 ++++++++ misc/logger.go | 11 +++++ structs/content.go | 32 ++++++++++++ structs/guest.go | 33 +++++++++++++ 13 files changed, 395 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 api/content.go create mode 100644 api/guest.go create mode 100644 app.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 misc/constants.go create mode 100644 misc/fetch.go create mode 100644 misc/generator.go create mode 100644 misc/logger.go create mode 100644 structs/content.go create mode 100644 structs/guest.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3b3bb22 --- /dev/null +++ b/.gitignore @@ -0,0 +1,118 @@ +# Created by https://www.toptal.com/developers/gitignore/api/goland+all,go +# Edit at https://www.toptal.com/developers/gitignore?templates=goland+all,go + +### Go ### +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work + +### GoLand+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### GoLand+all Patch ### +# Ignore everything but code style settings and run configurations +# that are supposed to be shared within teams. + +.idea/* + +!.idea/codeStyles +!.idea/runConfigurations + +# End of https://www.toptal.com/developers/gitignore/api/goland+all,go + + +build/* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1fca6c2 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +.PHONY all: +all: + go build -o build/scrapper && chmod +x build/scrapper + +.PHONY clean: +clean: + rm -rfv build/* diff --git a/api/content.go b/api/content.go new file mode 100644 index 0000000..d5862bd --- /dev/null +++ b/api/content.go @@ -0,0 +1,31 @@ +package api + +import ( + "GofileScrapper/misc" + "GofileScrapper/structs" + "bytes" + "encoding/json" + "fmt" +) + +func GetContent(guest structs.Guest, id string) (structs.Content, error) { + body, err := misc.Fetch( + "GET", + misc.API_URL+"/contents/"+id+"?wt=4fd6sg89d7s6", + bytes.NewBuffer([]byte(`{}`)), + []misc.HeaderType{ + {Key: "Authorization", Value: fmt.Sprintf("Bearer %s", guest.Data.Token)}, + }, + ) + if err != nil { + return structs.Content{}, fmt.Errorf("error reading response body: %v", err) + } + + var content structs.Content + err = json.Unmarshal(body, &content) + if err != nil { + return structs.Content{}, fmt.Errorf("error unmarshalling JSON: %v", err) + } + + return content, nil +} diff --git a/api/guest.go b/api/guest.go new file mode 100644 index 0000000..eb4d739 --- /dev/null +++ b/api/guest.go @@ -0,0 +1,55 @@ +package api + +import ( + "GofileScrapper/misc" + "GofileScrapper/structs" + "bytes" + "encoding/json" + "fmt" +) + +func GetGuest() (structs.Guest, error) { + body, err := misc.Fetch( + "POST", + misc.API_URL+"/accounts", + bytes.NewBuffer([]byte(`{}`)), + []misc.HeaderType{}, + ) + if err != nil { + return structs.Guest{}, fmt.Errorf("error reading response body: %v", err) + } + + var preGuest structs.CreatedGuest + err = json.Unmarshal(body, &preGuest) + if err != nil { + return structs.Guest{}, fmt.Errorf("error unmarshalling JSON: %v", err) + } + + if preGuest.Status != "ok" { + return structs.Guest{}, fmt.Errorf("unknown response from api: %v", string(body)) + } + + body, err = misc.Fetch( + "GET", + misc.API_URL+"/accounts/"+preGuest.Data.Id, + bytes.NewBuffer([]byte(`{}`)), + []misc.HeaderType{ + {Key: "Authorization", Value: fmt.Sprintf("Bearer %s", preGuest.Data.Token)}, + }, + ) + if err != nil { + return structs.Guest{}, fmt.Errorf("error reading response body: %v", err) + } + + var guest structs.Guest + err = json.Unmarshal(body, &guest) + if err != nil { + return structs.Guest{}, fmt.Errorf("error unmarshalling JSON: %v", err) + } + + if preGuest.Status != "ok" { + return structs.Guest{}, fmt.Errorf("unknown response from api: %v", string(body)) + } + + return guest, nil +} diff --git a/app.go b/app.go new file mode 100644 index 0000000..e09cd4a --- /dev/null +++ b/app.go @@ -0,0 +1,17 @@ +package main + +import ( + "GofileScrapper/api" + "GofileScrapper/misc" + "fmt" +) + +func main() { + id := misc.GetRandomContent() + guest, err := api.GetGuest() + if err != nil { + misc.Logger.Error().Msg(err.Error()) + } + + fmt.Println(api.GetContent(guest, id)) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7e7736f --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module GofileScrapper + +go 1.22 + +require ( + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/rs/zerolog v1.32.0 // indirect + golang.org/x/sys v0.18.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..5556e48 --- /dev/null +++ b/go.sum @@ -0,0 +1,17 @@ +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/misc/constants.go b/misc/constants.go new file mode 100644 index 0000000..7510ad2 --- /dev/null +++ b/misc/constants.go @@ -0,0 +1,4 @@ +package misc + +var CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +var API_URL = "https://api.gofile.io" diff --git a/misc/fetch.go b/misc/fetch.go new file mode 100644 index 0000000..5bf8667 --- /dev/null +++ b/misc/fetch.go @@ -0,0 +1,39 @@ +package misc + +import ( + "fmt" + "io" + "net/http" +) + +type HeaderType struct { + Key string + Value string +} + +func Fetch(method string, url string, body io.Reader, headers []HeaderType) ([]byte, error) { + req, err := http.NewRequest(method, url, body) + Logger.Info().Msg( + fmt.Sprintf("'%s' request for '%s'", method, url), + ) + + if err != nil { + return []byte{}, fmt.Errorf("error creating request: %v", err) + } + + req.Header.Set("Content-Type", "application/json") + if len(headers) > 0 { + for _, header := range headers { + req.Header.Set(header.Key, header.Value) + } + } + + client := &http.Client{} + response, err := client.Do(req) + if err != nil { + return []byte{}, fmt.Errorf("error sending request: %v", err) + } + defer response.Body.Close() + + return io.ReadAll(response.Body) +} diff --git a/misc/generator.go b/misc/generator.go new file mode 100644 index 0000000..64c3ae7 --- /dev/null +++ b/misc/generator.go @@ -0,0 +1,21 @@ +package misc + +import ( + "math/rand" + "strings" + "time" +) + +func GetRandomContent() string { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + + var result strings.Builder + charsetLength := len(CHARSET) + + for i := 0; i < 6; i++ { + randomIndex := r.Intn(charsetLength) + result.WriteByte(CHARSET[randomIndex]) + } + + return result.String() +} diff --git a/misc/logger.go b/misc/logger.go new file mode 100644 index 0000000..80fc045 --- /dev/null +++ b/misc/logger.go @@ -0,0 +1,11 @@ +package misc + +import ( + "github.com/rs/zerolog" + "os" + "time" +) + +var Logger = zerolog.New( + zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}, +).Level(zerolog.TraceLevel).With().Timestamp().Caller().Logger() diff --git a/structs/content.go b/structs/content.go new file mode 100644 index 0000000..31b4aa2 --- /dev/null +++ b/structs/content.go @@ -0,0 +1,32 @@ +package structs + +type ContentChild struct { + Id string `json:"id"` + Type string `json:"type"` + Name string `json:"name"` + CreateTime int `json:"createTime"` + Size int `json:"size"` + DownloadCount int `json:"downloadCount"` + Md5 string `json:"md5"` + Mimetype string `json:"mimetype"` + ServerSelected string `json:"serverSelected"` + Link string `json:"link"` + Thumbnail string `json:"thumbnail"` +} + +type Content struct { + Status string `json:"status"` + Data struct { + Id string `json:"id"` + Type string `json:"type"` + Name string `json:"name"` + ParentFolder string `json:"parentFolder"` + Code string `json:"code"` + CreateTime int `json:"createTime"` + Public bool `json:"public"` + TotalDownloadCount int `json:"totalDownloadCount"` + TotalSize int `json:"totalSize"` + ChildrenIds []string `json:"childrenIds"` + Children map[string]ContentChild `json:"children"` + } `json:"data"` +} diff --git a/structs/guest.go b/structs/guest.go new file mode 100644 index 0000000..0606f6b --- /dev/null +++ b/structs/guest.go @@ -0,0 +1,33 @@ +package structs + +type CreatedGuest struct { + Status string `json:"status"` + Data struct { + Id string `json:"id"` + Token string `json:"token"` + } `json:"data"` +} + +type Guest struct { + Status string `json:"status"` + Data struct { + Id string `json:"id"` + Email string `json:"email"` + Tier string `json:"tier"` + Token string `json:"token"` + RootFolder string `json:"rootFolder"` + StatsCurrent struct { + FileCount int `json:"fileCount"` + FolderCount int `json:"folderCount"` + Storage int `json:"storage"` + } `json:"statsCurrent"` + StatsHistory struct { + } `json:"statsHistory"` + FilesCount int `json:"filesCount"` + TotalSize int `json:"totalSize"` + Total30DDLTraffic int `json:"total30DDLTraffic"` + Credit int `json:"credit"` + Currency string `json:"currency"` + CurrencySign string `json:"currencySign"` + } `json:"data"` +}