quran-go

Read Qur'an right in the terminal.
git clone http://git.hanabi.in/repos/quran-go.git
Log | Files | Refs | README | LICENSE

commit 46a2e79afeee3e89c9348f732e6caa33f0e985cf
parent e00e265c7cf29ef5225897bf7c6e967f7fda56d4
Author: Agastya Chandrakant <me@hanabi.in>
Date:   Tue, 26 Apr 2022 18:23:44 +0530

Check if the supplied chapter and verses (if any) are in the range xor
not.

Diffstat:
Mmain.go | 134++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mmakefile | 4+---
2 files changed, 128 insertions(+), 10 deletions(-)

diff --git a/main.go b/main.go @@ -1,26 +1,140 @@ package main import ( + "encoding/json" "flag" "fmt" + "io/ioutil" + "net/http" "os" "regexp" "strconv" ) const DEBUG = true +const API = "https://api.quran.com/api/v4" func main() { input, lang := getInput() if err, chap, ver1, ver2 := parseInput(input); err != nil { printerr(err) } else { - fmt.Println(lang) - fmt.Printf("%d:%d-%d\n", chap, ver1, ver2) - // @TODO -- use chap, ver1 and ver2 to fetch necessary aayat. + debug(lang) + if err := checkVerseRange(chap, ver1, ver2); err != nil { + printerr(err) + } else { + // @CONTINUE + // @TODO -- identify if one ayaat, multiple aayat or the whole chapter needs to be printed. + } } } +func checkVerseRange(chap t_chap, ver1, ver2 t_verse) (err error) { + if err := checkChapRange(chap); err != nil { + return err + } + if ver1 > 0 { + maxVerse, err := getChapMaxVerse(chap) + if err != nil { + return err + } + if ver2 > maxVerse { + err = fmt.Errorf("Verse for the chapter %d is out of range. That chapter has verses only till %d.\n", chap, maxVerse) + return err + } + } + return +} + +func getChapMaxVerse(chap t_chap) (maxVerse t_verse, err error) { + var chapDetails ChapterDetails + uri := fmt.Sprintf("%s/chapters/%d", API, chap) + err = quranHttpGet(uri, &chapDetails) + maxVerse = t_verse(chapDetails.VersesCount) + return +} + +type ChapterDetails struct { + Chapter `json:"chapter"` +} + +type Chapter struct { + ID int `json:"id"` + RevelationPlace string `json:"revelation_place"` + RevelationOrder int `json:"revelation_order"` + BismillahPre bool `json:"bismillah_pre"` + NameSimple string `json:"name_simple"` + NameComplex string `json:"name_complex"` + NameArabic string `json:"name_arabic"` + VersesCount int `json:"verses_count"` + Pages []int `json:"pages"` + TranslatedName TranslatedName `json:"translated_name"` +} + +type TranslatedName struct { + LanguageName string `json:"language_name"` + Name string `json:"name"` +} + +type t_chap uint +type t_verse uint + +func checkChapRange(chap t_chap) (err error) { + maxChap, err := getMaxChap() + if err != nil { + return err + } + + if chap < 1 || chap > maxChap { + err = fmt.Errorf("Chapter is out of range.\n") + } + return +} + +func quranHttpGet(endpoint string, st interface{}) (err error) { + + client := &http.Client{} + req, err := http.NewRequest(http.MethodGet, endpoint, nil) + if err != nil { + return + } + + req.Header.Set("User-Agent", "git.hanabi.in/repos/quran-go.git v2022-04-26") + + resp, err := client.Do(req) + if err != nil { + return + } + + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return + } + + err = json.Unmarshal(body, &st) + if err != nil { + return + } + + return +} + +func getMaxChap() (res t_chap, err error) { + var chapList ChaptersList + if err = quranHttpGet(API+"/chapters", &chapList); err != nil { + return + } + chaps := chapList.Chapters + res = t_chap(chaps[len(chaps)-1].ID) + return +} + +type ChaptersList struct { + Chapters []Chapter `json:"chapters"` +} + func getInput() (input, lang string) { flag.StringVar(&lang, "lang", "en", "Aayat language.") flag.Parse() @@ -28,7 +142,7 @@ func getInput() (input, lang string) { return input, lang } -func parseInput(input string) (err error, chapter, verse1, verse2 uint64) { +func parseInput(input string) (err error, chapter t_chap, verse1, verse2 t_verse) { // Group 1, 3, 5 = Chapter:Verse1-Verse2 re := regexp.MustCompile(`^(\d)+(:(\d+)(-(\d+))?)?$`) @@ -40,15 +154,18 @@ func parseInput(input string) (err error, chapter, verse1, verse2 uint64) { res := re.FindAllStringSubmatch(input, -1) - chapter, err = strconv.ParseUint(res[0][1], 10, 0) + ch, err := strconv.ParseUint(res[0][1], 10, 0) if err != nil { return } + chapter = t_chap(ch) if res[0][3] == "" { res[0][3] = "0" } - verse1, err = strconv.ParseUint(res[0][3], 10, 0) + ve1, err := strconv.ParseUint(res[0][3], 10, 0) + verse1 = t_verse(ve1) + if err != nil { return } @@ -56,7 +173,10 @@ func parseInput(input string) (err error, chapter, verse1, verse2 uint64) { if res[0][5] == "" { res[0][5] = res[0][3] } - verse2, err = strconv.ParseUint(res[0][5], 10, 0) + + ve2, err := strconv.ParseUint(res[0][5], 10, 0) + verse2 = t_verse(ve2) + if err != nil { return } diff --git a/makefile b/makefile @@ -1,4 +1,2 @@ dev: - go run main.go && read && vim main.go -p: - go run main.go -lang=ur 2:14-16 foo bar baz && read && vim main.go + go run main.go -lang=ur 2:14-16 && read && vim main.go