From 3882939bc5d6a5c536617eeaa411e70c64f81573 Mon Sep 17 00:00:00 2001 From: GeneralHurricane Date: Sat, 17 Dec 2022 22:08:07 -0600 Subject: [PATCH] thy word is a lamp unto my feet --- .gitignore | 2 + bible.go | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 43 ++++++++++++ rdrama.go | 60 +++++++++------- 4 files changed, 279 insertions(+), 26 deletions(-) create mode 100644 .gitignore create mode 100644 bible.go create mode 100644 main.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..30bd623 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env + diff --git a/bible.go b/bible.go new file mode 100644 index 0000000..b69ec7b --- /dev/null +++ b/bible.go @@ -0,0 +1,200 @@ +package main + +import ( + "errors" + "fmt" + "regexp" + "strconv" +) + +var BibleRegex = regexp.MustCompile(`(?P\w*?)? *(?P[a-zA-Z]+?)\s?(?P\d{1,3})(?::(?P\d{1,3})(?:-(?P\d{1,3})?)?)`) + +var MatchError = errors.New("Error matching verse") + +var Books = map[string]int{ + "GEN": 1, + "EXO": 2, + "EX": 2, + "LEV": 3, + "LV": 3, + "NUM": 4, + "DEU": 5, + "DT": 5, + "JOS": 6, + "JUDGES": 7, + "JDG": 7, + "JDGS": 7, + "JG": 7, + "RUT": 8, + "1 SAM": 9, + "2 SAM": 10, + "1 KIN": 11, + "2 KIN": 12, + "1 CHR": 13, + "2 CHR": 14, + "EZR": 15, + "NEH": 16, + "EST": 17, + "JOB": 18, + "PSA": 19, + "PS": 19, + "PRO": 20, + "PRV": 20, + "ECC": 21, + "SOL": 22, + "SON": 22, + "ISA": 23, + "JER": 24, + "LAM": 25, + "EZE": 26, + "DAN": 27, + "HOS": 28, + "JOE": 29, + "AMO": 30, + "OBA": 31, + "JON": 32, + "MIC": 33, + "NAH": 34, + "HAB": 35, + "ZEP": 36, + "HAG": 37, + "ZEC": 38, + "MAL": 39, + "MAT": 40, + "MAR": 41, + "LUK": 42, + "JOH": 43, + "ACT": 44, + "ROM": 45, + "1 COR": 46, + "2 COR": 47, + "GAL": 48, + "EPH": 49, + "PHILIPPIANS": 50, + "COL": 51, + "1 THE": 52, + "2 THE": 53, + "1 TIM": 54, + "2 TIM": 55, + "TIT": 56, + "PHILEMON": 57, + "HEB": 58, + "JAM": 59, + "1 PET": 60, + "2 PET": 61, + "1 JOH": 62, + "2 JOH": 63, + "3 JOH": 64, + "JUDE": 65, + "REV": 66, +} + +var FirstPrefixes = []string{ + "FIRST", + "1ST", + "1", + "I", +} +var SecondPrefixes = []string{ + "SECOND", + "2nd", + "2", + "II", +} + +type BibleReference struct { + RegexMatch string + Prefix string + Book string + BookNum int + Chapter string + StartVerse string + EndVerse string + StartKey string // key format is BBCCCVVV + EndKey string +} + +func GetReferences(text string) []*BibleReference { + matches := BibleRegex.FindAllStringSubmatch(text, -1) + refs := make([]*BibleReference, 0, len(matches)) + for _, match := range matches { + ref, err := NewBibleReference(match) + if err != nil { + fmt.Printf(`Couldn't parse "%s" +`, match[0]) + continue + } + + fmt.Printf(`parsed "%s": %s - %s +`, ref.RegexMatch, ref.StartKey, ref.EndKey) + refs = append(refs, ref) + } + return refs +} + +func NewBibleReference(match []string) (*BibleReference, error) { + if len(match) < 6 { + return nil, MatchError + } + ref := &BibleReference{ + RegexMatch: match[0], + Prefix: match[1], + Book: match[2], + Chapter: match[3], + StartVerse: match[4], + EndVerse: match[5], + } + err := ref.Validate() + return ref, err +} + +func contains(s []string, str string) bool { + for _, v := range s { + if v == str { + return true + } + } + + return false +} + +func (b *BibleReference) Validate() error { + if contains(FirstPrefixes, b.Prefix) { + b.Prefix = "1" + } else if contains(SecondPrefixes, b.Prefix) { + b.Prefix = "2" + } else { + b.Prefix = "" + } + if b.Prefix != "" { + b.Book = fmt.Sprintf("%s %s", b.Prefix, b.Book) + } + num, ok := Books[b.Book] + if !ok { + num, ok = Books[fmt.Sprintf("%.5s", b.Book)] + } + if !ok { + num, ok = Books[fmt.Sprintf("%.3s", b.Book)] + } + if !ok { + return MatchError + } + + chapter, err := strconv.Atoi(b.Chapter) + if err != nil { + return err + } + startverse, err := strconv.Atoi(b.StartVerse) + if err != nil { + return err + } + endverse, err := strconv.Atoi(b.EndVerse) + if err != nil { + endverse = startverse + } + + b.StartKey = fmt.Sprintf("%02d%03d%03d", num, chapter, startverse) + b.EndKey = fmt.Sprintf("%02d%03d%03d", num, chapter, endverse) + return nil + +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..00a18c2 --- /dev/null +++ b/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "fmt" + "log" + "os" + "strings" + "time" +) + +func main() { + fmt.Printf("Running...\n") + siteURL := os.Getenv("RDRAMA_URL") + if siteURL == "" { + log.Fatal("RDRAMA_URL environment variable not set") + } + + siteToken := os.Getenv("RDRAMA_API_TOKEN") + if siteToken == "" { + log.Fatal("RDRAMA_API_TOKEN environment variable not set") + } + + client := NewRDramaClient(siteURL, siteToken) + now := time.Now() + + comments, err := client.GetComments(SearchParams{ + Hole: "dankchristianmemes", + After: time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC), + }) + + if err != nil { + log.Fatal(err) + panic(err) + } + fmt.Printf("Found comments: %d\n", len(comments)) + + for _, comment := range comments { +// fmt.Printf("%s: %s\n", comment.Author, comment.Text) + _ = GetReferences(strings.ToUpper(comment.Text)) + } + + // Use the client to make API requests +} diff --git a/rdrama.go b/rdrama.go index 6801b54..c88eace 100644 --- a/rdrama.go +++ b/rdrama.go @@ -2,30 +2,32 @@ package main import ( "encoding/json" - "io" + "fmt" "net/http" + "net/url" + "time" ) -type APIClient struct { +type RDramaClient struct { baseURL string apiKey string } -func NewAPIClient(baseURL, apiKey string) *APIClient { - return &APIClient{ +func NewRDramaClient(baseURL, apiKey string) *RDramaClient { + return &RDramaClient{ baseURL: baseURL, apiKey: apiKey, } } -func (c *APIClient) makeRequest(method, path string, v interface{}) error { +func (c *RDramaClient) makeRequest(method, path string, v interface{}) error { url := c.baseURL + path req, err := http.NewRequest(method, url, nil) if err != nil { return err } - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.apiKey)) + req.Header.Add("Authorization", fmt.Sprintf("%s", c.apiKey)) client := http.Client{} resp, err := client.Do(req) @@ -34,7 +36,7 @@ func (c *APIClient) makeRequest(method, path string, v interface{}) error { } defer resp.Body.Close() - if resp.StatusCode >= 200 && resp.StatusCode < 300 { + if !(resp.StatusCode >= 200 && resp.StatusCode < 300) { return fmt.Errorf("unexpected status code: %d", resp.StatusCode) } @@ -47,30 +49,36 @@ type CommentResponse struct { type Comment struct { ID int `json:"id"` - Author string `json:"author"` - Text string `json:"text"` + Author string `json:"author_name"` + Text string `json:"body"` } -func (c *APIClient) GetComments() ([]Comment, error) { +type SearchParams struct { + Hole string + After time.Time + Before time.Time +} + +func (c *RDramaClient) GetComments(params SearchParams) ([]Comment, error) { + var s string + if params.Hole != "" { + s += fmt.Sprintf("hole:%s", params.Hole) + } + nullTime := time.Time{} + if params.After != nullTime { + s += fmt.Sprintf(" after:%d", params.After.Unix()) + } + if params.Before != nullTime { + s += fmt.Sprintf(" before:%d", params.Before.Unix()) + } + v := url.Values{} + v.Set("q", s) + url := "/search/comments?" + v.Encode() + fmt.Printf("URL: %s\n", url) var comments CommentResponse - if err := c.makeRequest("GET", "/comments", &comments); err != nil { + if err := c.makeRequest("GET", url, &comments); err != nil { return nil, err } return comments.Data, nil } - -func (c *APIClient) MakeComment(author, text string) error { - body := bytes.NewBuffer([]byte(fmt.Sprintf(`{"author": "%s", "text": "%s"}`, author, text))) - resp, err := c.makeRequest("POST", "/comments", body) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("unexpected status code: %d", resp.StatusCode) - } - - return nil -}