Explorar el Código

Initial commit

Foppe Hemminga hace 6 años
commit
0a548cba9c
Se han modificado 2 ficheros con 327 adiciones y 0 borrados
  1. 2 0
      .gitignore
  2. 325 0
      main.go

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+secret.go
+/.idea

+ 325 - 0
main.go

@@ -0,0 +1,325 @@
+package main
+
+import (
+	"bytes"
+	"database/sql"
+	"encoding/json"
+	"fmt"
+	"log"
+	"net/http"
+	"regexp"
+	"strconv"
+	"strings"
+	"time"
+
+	// https://golang.org/ref/spec#Import_declarations
+	_ "github.com/lib/pq"
+)
+
+// Faction is a struct that holds data about a faction
+type Faction struct {
+	webhookGeneral string
+	webhookWar     string
+	name           string
+	id             int
+}
+
+// Event from http://api.orn.com/user
+type Event struct {
+	id        int
+	timestamp time.Time
+	news      string
+}
+
+// Events array of Event
+type Events []Event
+
+// Attack struct
+type Attack struct {
+	id        int
+	timestamp time.Time
+	news      string
+}
+
+// Attacks array of Attack
+type Attacks []Attack
+
+// News to be broadcast
+type News struct {
+	Content string `json:"content"`
+}
+
+func main() {
+	duration := time.Duration(10) * time.Second
+	time.Sleep(duration)
+	var err error
+	var e Event
+	timeFormat := "2006-01-02 15:04:05"
+	relentless := Faction{
+		webhookGeneral: "https://discordapp.com/api/webhooks/330506556820946946/gzReDE9EKFei05twvoFSZgRkAdAG523YTNLy2T_c5NDwagapwgGyhTrjFq_Y2_zu1fOK",
+		webhookWar:     "https://discordapp.com/api/webhooks/330163061573025792/m9qS_4FawQwaWN11Y-qDKC2CeBlcR2r7Q9muISiVjW7LVpKrPNcYudNkPf2Y_ZD3sWf6",
+		name:           "Relentless",
+		id:             8336}
+	unrelenting := Faction{
+		webhookGeneral: "https://discordapp.com/api/webhooks/330303142367461376/R9v8SQqZz8J-nyQuDAcU-xA7GNt_DsMzZ30LI6qJmebDJzLOfQoCLvX07YBrjoZTHAVI",
+		webhookWar:     "https://discordapp.com/api/webhooks/330303142367461376/R9v8SQqZz8J-nyQuDAcU-xA7GNt_DsMzZ30LI6qJmebDJzLOfQoCLvX07YBrjoZTHAVI",
+		name:           "Unrelenting",
+		id:             20747}
+	factions := []Faction{relentless, unrelenting}
+	for _, faction := range factions {
+		e, err = getEventsFromDatabase(faction.name)
+		if err != nil {
+			log.Println("Database error:", err)
+		}
+		if e.id > 0 {
+			fmt.Println("*** Processing: " + faction.name)
+			var code int
+			e.news = strings.Replace(e.news, "[", "\\[", -1)
+			news := replaceLinks(e.news)
+			news = strings.Replace(news, "http:", "https:", -1)
+			news = "`" + e.timestamp.UTC().Format(timeFormat) + "`: " + news
+			fmt.Println(faction.name + ": " + news)
+			code, err = broadcastNews(news, faction.webhookGeneral) // general
+			if err != nil {
+				log.Println("broadcast error:", err)
+			}
+			fmt.Println(faction.name + ": " + strconv.Itoa(code))
+			if code == 204 {
+				// Assuming sent
+				setBroadcastTrue(e.id)
+			}
+		}
+
+		// Attacks
+		attacks, err := getAttackFromDatabase(faction.name)
+		if err != nil {
+			log.Println("Database error:", err)
+		}
+		for key, attack := range attacks {
+			fmt.Printf("attacks[%d].id: %d\n", key, attack.id)
+			err = broadcastSingleAttack(attack, faction)
+			if err != nil {
+				log.Println(err)
+			}
+		}
+		//a := attacks[0]
+
+	}
+}
+
+func getEventsFromDatabase(factionName string) (Event, error) {
+	var err error
+	var e Event
+	db, err := sql.Open("postgres", "user="+pgUser+" dbname="+pgTable+" password="+pgPasswd)
+	if err != nil {
+		return e, err
+	}
+	defer db.Close()
+
+	rows, err := db.Query(`SELECT id, timestamp, news FROM events WHERE faction = '` +
+		factionName + `' AND broadcast = FALSE ORDER BY id ASC LIMIT 1;`)
+	if err != nil {
+		return e, err
+	}
+	defer rows.Close()
+	for rows.Next() {
+		rows.Scan(&e.id, &e.timestamp, &e.news)
+		if err != nil {
+			return e, err
+		}
+		fmt.Println(e)
+	}
+	if err := rows.Err(); err != nil {
+		return e, err
+	}
+	return e, nil
+}
+
+func getAttackFromDatabase(factionName string) (Attacks, error) {
+	var err error
+	var a Attack
+	var attacks Attacks
+	db, err := sql.Open("postgres", "user="+pgUser+" dbname="+pgTable+" password="+pgPasswd)
+	if err != nil {
+		return attacks, err
+	}
+	defer db.Close()
+
+	rows, err := db.Query("SELECT id, timestamp, news FROM attacks WHERE faction = '" +
+		factionName + "' AND broadcast = FALSE ORDER BY id ASC;")
+	if err != nil {
+		return attacks, err
+	}
+	defer rows.Close()
+	for rows.Next() {
+		rows.Scan(&a.id, &a.timestamp, &a.news)
+		if err != nil {
+			return attacks, err
+		}
+		attacks = append(attacks, a)
+		fmt.Println(a)
+	}
+	if err := rows.Err(); err != nil {
+		return attacks, err
+	}
+	return attacks, nil
+}
+
+func (e Event) String() string {
+	line := fmt.Sprintf("{\n\t\"id\": %d,", e.id)
+	line += fmt.Sprintf("\n\t\"timestamp\": %s,", e.timestamp)
+	line += fmt.Sprintf("\n\t\"news\": %s", e.news)
+	line += fmt.Sprintf("\n}")
+	return line
+}
+
+func (a Attack) String() string {
+	line := fmt.Sprintf("{\n\t\"id\": %d,", a.id)
+	line += fmt.Sprintf("\n\t\"timestamp\": %s,", a.timestamp)
+	line += fmt.Sprintf("\n\t\"news\": %s", a.news)
+	line += fmt.Sprintf("\n}")
+	return line
+}
+
+func replaceLinks(news string) string {
+	re := regexp.MustCompile(`<[aA].*?href\s?=\s?"?(.*?)[ "]?(?: .*?)?>(.*?)<\/a>`)
+	fmt.Println(re.FindAllStringSubmatch(news, -1))
+	return re.ReplaceAllString(news, "[${2}](${1})")
+	//return news
+}
+
+func broadcastNews(new string, webhook string) (int, error) {
+	// var err error
+	var news News
+	news.Content = new
+	jsonValue, err := json.Marshal(news)
+	if err != nil {
+		return -1, err
+	}
+	fmt.Println(string(jsonValue))
+	resp, err := http.Post(webhook, "application/json", bytes.NewBuffer(jsonValue))
+	if err != nil {
+		return -1, err
+	}
+	return resp.StatusCode, nil
+}
+
+func broadcastSingleAttack(attack Attack, faction Faction) error {
+	timeFormat := "2006-01-02 15:04:05"
+	if attack.id > 0 {
+		members, err := getRelentlessMembers()
+		if err != nil {
+			log.Println("Database error:", err)
+		}
+		news := replaceLinks(attack.news)
+		news = strings.Replace(news, "http:", "https:", -1)
+		for _, val := range members {
+			news = strings.Replace(news, val, "**"+val+"**", -1)
+		}
+		news = strings.Replace(news, "_", "\\_", -1)
+		news = attack.timestamp.UTC().Format(timeFormat) + ": " + news
+		code, err := broadcastNews(news, faction.webhookWar) // war
+		if err != nil {
+			log.Println("broadcast error:", err)
+		}
+		fmt.Println(faction.name + ": " + strconv.Itoa(code))
+		if code == 204 {
+			// Assuming sent
+			setAttackBroadcastTrue(attack.id)
+		}
+	}
+	return nil
+}
+
+func setBroadcastTrue(id int) error {
+	fmt.Println(id)
+	var err error
+	db, err := sql.Open("postgres", "user="+pgUser+" dbname="+pgTable+" password="+pgPasswd)
+	if err != nil {
+		return err
+	}
+	defer db.Close()
+
+	tx, err := db.Begin()
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer tx.Rollback()
+
+	tx.Exec(`SET TIME ZONE 'utc'`)
+	stmt, err := tx.Prepare("UPDATE events SET broadcast = TRUE WHERE id = $1;")
+	if err != nil {
+		return err
+	}
+	_, err = stmt.Exec(fmt.Sprintf("%d", id))
+	if err != nil {
+		return err
+	}
+	err = tx.Commit()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func setAttackBroadcastTrue(id int) error {
+	fmt.Println(id)
+	var err error
+	db, err := sql.Open("postgres", "user="+pgUser+" dbname="+pgTable+" password="+pgPasswd)
+	if err != nil {
+		return err
+	}
+	defer db.Close()
+
+	tx, err := db.Begin()
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer tx.Rollback()
+
+	tx.Exec(`SET TIME ZONE 'utc'`)
+	stmt, err := tx.Prepare("UPDATE attacks SET broadcast = TRUE WHERE id = $1;")
+	if err != nil {
+		return err
+	}
+	_, err = stmt.Exec(fmt.Sprintf("%d", id))
+	if err != nil {
+		return err
+	}
+	err = tx.Commit()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func getRelentlessMembers() ([]string, error) {
+	var members []string
+	var err error
+	db, err := sql.Open("postgres", "user="+pgUser+" dbname="+pgTable+" password="+pgPasswd)
+	if err != nil {
+		return members, err
+	}
+	defer db.Close()
+
+	rows, err := db.Query("SELECT member_name FROM members WHERE status = 'joined';")
+	if err != nil {
+		return members, err
+	}
+	defer rows.Close()
+	var name string
+	for rows.Next() {
+		rows.Scan(&name)
+		if err != nil {
+			return members, err
+		}
+		members = append(members, name)
+	}
+	if err := rows.Err(); err != nil {
+		return members, err
+	}
+	return members, nil
+
+}