package handler import ( "context" "fmt" "strconv" "strings" "github.com/micro/micro/v3/service/errors" "github.com/micro/micro/v3/service/logger" "github.com/micro/services/pkg/api" "github.com/micro/services/sunnah/domain" pb "github.com/micro/services/sunnah/proto" ) var ( apiUrl = "https://api.sunnah.com/v1/" ) type Sunnah struct { apiKey string } func New(key string) *Sunnah { api.SetKey("X-API-Key", key) return &Sunnah{ apiKey: key, } } func (s *Sunnah) Collections(ctx context.Context, req *pb.CollectionsRequest, rsp *pb.CollectionsResponse) error { var resp *domain.CollectionRequest if req.Limit <= 0 { req.Limit = 50 } if req.Page <= 0 { req.Page = 1 } uri := fmt.Sprintf("%scollections?limit=%d&page=%d", apiUrl, req.Limit, req.Page) if err := api.Get(uri, &resp); err != nil { logger.Errorf("Failed to retrieve collections: %v", err) return errors.InternalServerError("sunnah.collections", "Failed to retrieve collections") } for _, c := range resp.Data { var arabicTitle string if len(c.Collection) > 1 && c.Collection[1].Lang == "ar" { arabicTitle = c.Collection[1].Title } rsp.Collections = append(rsp.Collections, &pb.Collection{ Name: c.Name, Title: c.Collection[0].Title, ArabicTitle: arabicTitle, Hadiths: c.TotalHadith, Summary: c.Collection[0].ShortIntro, }) } return nil } func (s *Sunnah) Books(ctx context.Context, req *pb.BooksRequest, rsp *pb.BooksResponse) error { var resp *domain.BookRequest if len(req.Collection) == 0 { return errors.BadRequest("sunnah.books", "missing collection name") } if req.Limit <= 0 { req.Limit = 50 } if req.Page <= 0 { req.Page = 1 } uri := fmt.Sprintf("%scollections/%s/books?limit=%d&page=%d", apiUrl, req.Collection, req.Limit, req.Page) if err := api.Get(uri, &resp); err != nil { logger.Errorf("Failed to retrieve books: %v", err) return errors.InternalServerError("sunnah.books", "Failed to retrieve books") } rsp.Collection = req.Collection rsp.Total = resp.Total rsp.Limit = req.Limit rsp.Page = req.Page for _, b := range resp.Data { if len(b.Book) == 0 { continue } var arabicName string if len(b.Book) > 1 && b.Book[1].Lang == "ar" { arabicName = b.Book[1].Name } bkId, _ := strconv.Atoi(b.BookNumber) rsp.Books = append(rsp.Books, &pb.Book{ Id: int32(bkId), Name: b.Book[0].Name, ArabicName: arabicName, Hadiths: b.NumberOfHadith, }) } return nil } func (s *Sunnah) Chapters(ctx context.Context, req *pb.ChaptersRequest, rsp *pb.ChaptersResponse) error { var resp *domain.ChaptersRequest if len(req.Collection) == 0 { return errors.BadRequest("sunnah.chapters", "missing collection name") } if req.Book == 0 { req.Book = 1 } if req.Limit <= 0 { req.Limit = 50 } if req.Page <= 0 { req.Page = 1 } uri := fmt.Sprintf("%scollections/%s/books/%d/chapters?limit=%d&page=%d", apiUrl, req.Collection, req.Book, req.Limit, req.Page) if err := api.Get(uri, &resp); err != nil { logger.Errorf("Failed to retrieve chapters: %v", err) return errors.InternalServerError("sunnah.chapters", "Failed to retrieve chapters") } rsp.Collection = req.Collection rsp.Book = req.Book rsp.Total = resp.Total rsp.Limit = req.Limit rsp.Page = req.Page for _, c := range resp.Data { if len(c.Chapter) == 0 { continue } var arabicTitle string if len(c.Chapter) > 1 && c.Chapter[1].Lang == "ar" { arabicTitle = c.Chapter[1].ChapterTitle } bkId, _ := strconv.Atoi(c.BookNumber) chNumber, _ := strconv.Atoi(strings.Split(c.ChapterId, ".")[0]) rsp.Chapters = append(rsp.Chapters, &pb.Chapter{ Id: int32(chNumber), Key: c.ChapterId, Book: int32(bkId), Title: c.Chapter[0].ChapterTitle, ArabicTitle: arabicTitle, }) } return nil } func (s *Sunnah) Hadiths(ctx context.Context, req *pb.HadithsRequest, rsp *pb.HadithsResponse) error { var resp *domain.HadithsRequest if len(req.Collection) == 0 { return errors.BadRequest("sunnah.hadiths", "missing collection name") } if req.Book == 0 { req.Book = 1 } if req.Limit <= 0 { req.Limit = 50 } if req.Page <= 0 { req.Page = 1 } uri := fmt.Sprintf("%scollections/%s/books/%d/hadiths?limit=%d&page=%d", apiUrl, req.Collection, req.Book, req.Limit, req.Page) if err := api.Get(uri, &resp); err != nil { logger.Errorf("Failed to retrieve hadiths: %v", err) return errors.InternalServerError("sunnah.hadiths", "Failed to retrieve hadiths") } rsp.Collection = req.Collection rsp.Book = req.Book rsp.Total = resp.Total rsp.Limit = req.Limit rsp.Page = req.Page for _, h := range resp.Data { if len(h.Hadith) == 0 { continue } var arabicTitle string var arabicText string if len(h.Hadith) > 1 && h.Hadith[1].Lang == "ar" { arabicTitle = h.Hadith[1].ChapterTitle arabicText = h.Hadith[1].Body } chNumber, _ := strconv.Atoi(strings.Split(h.ChapterId, ".")[0]) hId, _ := strconv.Atoi(h.HadithNumber) rsp.Hadiths = append(rsp.Hadiths, &pb.Hadith{ Id: int32(hId), Chapter: int32(chNumber), ChapterKey: h.ChapterId, ChapterTitle: h.Hadith[0].ChapterTitle, Text: h.Hadith[0].Body, ArabicText: arabicText, ArabicChapterTitle: arabicTitle, }) } return nil }