thy word is a lamp unto my feet

master
GeneralHurricane 2022-12-17 22:08:07 -06:00
parent e4b9073ff7
commit 3882939bc5
4 changed files with 279 additions and 26 deletions

2
.gitignore vendored 100644
View File

@ -0,0 +1,2 @@
.env

200
bible.go 100644
View File

@ -0,0 +1,200 @@
package main
import (
"errors"
"fmt"
"regexp"
"strconv"
)
var BibleRegex = regexp.MustCompile(`(?P<prefix>\w*?)? *(?P<book>[a-zA-Z]+?)\s?(?P<chapter>\d{1,3})(?::(?P<startverse>\d{1,3})(?:-(?P<endverse>\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
}

43
main.go 100644
View File

@ -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
}

View File

@ -2,30 +2,32 @@ package main
import ( import (
"encoding/json" "encoding/json"
"io" "fmt"
"net/http" "net/http"
"net/url"
"time"
) )
type APIClient struct { type RDramaClient struct {
baseURL string baseURL string
apiKey string apiKey string
} }
func NewAPIClient(baseURL, apiKey string) *APIClient { func NewRDramaClient(baseURL, apiKey string) *RDramaClient {
return &APIClient{ return &RDramaClient{
baseURL: baseURL, baseURL: baseURL,
apiKey: apiKey, 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 url := c.baseURL + path
req, err := http.NewRequest(method, url, nil) req, err := http.NewRequest(method, url, nil)
if err != nil { if err != nil {
return err return err
} }
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.apiKey)) req.Header.Add("Authorization", fmt.Sprintf("%s", c.apiKey))
client := http.Client{} client := http.Client{}
resp, err := client.Do(req) resp, err := client.Do(req)
@ -34,7 +36,7 @@ func (c *APIClient) makeRequest(method, path string, v interface{}) error {
} }
defer resp.Body.Close() 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) return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
} }
@ -47,30 +49,36 @@ type CommentResponse struct {
type Comment struct { type Comment struct {
ID int `json:"id"` ID int `json:"id"`
Author string `json:"author"` Author string `json:"author_name"`
Text string `json:"text"` 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 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 nil, err
} }
return comments.Data, nil 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
}