mirror of
https://github.com/skidoodle/ncore-stats.git
synced 2025-02-15 05:09:14 +01:00
Init
This commit is contained in:
commit
614504e933
9 changed files with 564 additions and 0 deletions
180
main.go
Normal file
180
main.go
Normal file
|
@ -0,0 +1,180 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
type ProfileData struct {
|
||||
Owner string `json:"owner"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Rank string `json:"rank"`
|
||||
Upload string `json:"upload"`
|
||||
CurrentUpload string `json:"current_upload"`
|
||||
CurrentDownload string `json:"current_download"`
|
||||
Points string `json:"points"`
|
||||
}
|
||||
|
||||
var (
|
||||
profiles = map[string]string{}
|
||||
jsonFile = "data.json"
|
||||
nick string
|
||||
pass string
|
||||
client *http.Client
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := godotenv.Load(); err != nil {
|
||||
log.Fatal("Error loading .env file")
|
||||
}
|
||||
|
||||
nick = os.Getenv("NICK")
|
||||
pass = os.Getenv("PASS")
|
||||
|
||||
for i := 1; i <= 10; i++ {
|
||||
profileKey := fmt.Sprintf("PROFILE_%d", i)
|
||||
if profileURL := os.Getenv(profileKey); profileURL != "" {
|
||||
profiles[profileURL] = profileURL
|
||||
}
|
||||
}
|
||||
|
||||
client = &http.Client{}
|
||||
}
|
||||
|
||||
func fetchProfile(url string) (*ProfileData, error) {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Cookie", fmt.Sprintf("nick=%s; pass=%s", nick, pass))
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("failed to fetch profile: %s", url)
|
||||
}
|
||||
|
||||
doc, err := goquery.NewDocumentFromReader(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
owner := strings.TrimSpace(doc.Find(".fobox_fej").Text())
|
||||
owner = strings.Replace(owner, " profilja", "", 1)
|
||||
|
||||
profile := &ProfileData{
|
||||
Owner: owner,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
doc.Find(".userbox_tartalom_mini .profil_jobb_elso2").Each(func(i int, s *goquery.Selection) {
|
||||
label := s.Text()
|
||||
value := s.Next().Text()
|
||||
|
||||
switch label {
|
||||
case "Helyezés:":
|
||||
profile.Rank = value
|
||||
case "Feltöltés:":
|
||||
profile.Upload = value
|
||||
case "Aktuális feltöltés:":
|
||||
profile.CurrentUpload = value
|
||||
case "Aktuális letöltés:":
|
||||
profile.CurrentDownload = value
|
||||
case "Pontok száma:":
|
||||
profile.Points = value
|
||||
}
|
||||
})
|
||||
|
||||
return profile, nil
|
||||
}
|
||||
|
||||
func readExistingProfiles() ([]ProfileData, error) {
|
||||
if _, err := os.Stat(jsonFile); os.IsNotExist(err) {
|
||||
return []ProfileData{}, nil
|
||||
}
|
||||
|
||||
file, err := os.Open(jsonFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var profiles []ProfileData
|
||||
byteValue, _ := io.ReadAll(file)
|
||||
err = json.Unmarshal(byteValue, &profiles)
|
||||
return profiles, err
|
||||
}
|
||||
|
||||
func logToJSON(profile *ProfileData) error {
|
||||
existingProfiles, err := readExistingProfiles()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
existingProfiles = append(existingProfiles, *profile)
|
||||
|
||||
file, err := os.OpenFile(jsonFile, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
enc := json.NewEncoder(file)
|
||||
enc.SetIndent("", " ")
|
||||
return enc.Encode(existingProfiles)
|
||||
}
|
||||
|
||||
func dataHandler(w http.ResponseWriter, r *http.Request) {
|
||||
profiles, err := readExistingProfiles()
|
||||
if err != nil {
|
||||
http.Error(w, "Could not read data", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(profiles)
|
||||
}
|
||||
|
||||
func serveHTML(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, "index.html")
|
||||
}
|
||||
|
||||
func main() {
|
||||
ticker := time.NewTicker(24 * time.Hour)
|
||||
defer ticker.Stop()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
for _, url := range profiles {
|
||||
profile, err := fetchProfile(url)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := logToJSON(profile); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
<-ticker.C
|
||||
}
|
||||
}()
|
||||
|
||||
http.HandleFunc("/data", dataHandler)
|
||||
http.HandleFunc("/", serveHTML)
|
||||
log.Fatal(http.ListenAndServe(":3000", nil))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue