You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.8 KiB
Go
136 lines
3.8 KiB
Go
package diyanetapi
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/imroc/req/v3"
|
|
|
|
"prayertimes/pkg/prayer"
|
|
)
|
|
|
|
type Provider struct {
|
|
http *req.Client
|
|
}
|
|
|
|
func New(c *req.Client) Provider {
|
|
return Provider{
|
|
http: c.Clone().SetCommonBasicAuth("diyanet", "Q6Y3vYt5F3x2txPaaMF3uPgbK99EJhpM"),
|
|
}
|
|
}
|
|
|
|
func (d Provider) GetByCoords(ctx context.Context, coords prayer.Coordinates) ([]prayer.Times, error) {
|
|
locationID, err := d.getLocationIDByCoords(ctx, coords)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to resolve location by coordinates: %w", err)
|
|
}
|
|
|
|
times, err := d.Get(ctx, locationID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get prayer times by coordinates: %w", err)
|
|
}
|
|
|
|
return times, nil
|
|
}
|
|
|
|
func (d Provider) getLocationIDByCoords(ctx context.Context, coords prayer.Coordinates) (string, error) {
|
|
res, err := d.http.NewRequest().
|
|
SetContext(ctx).
|
|
SetQueryParams(map[string]string{
|
|
"latitude": fmt.Sprintf("%f", coords.Latitude),
|
|
"longitude": fmt.Sprintf("%f", coords.Longitude),
|
|
}).
|
|
Get("https://namazvakti.diyanet.gov.tr/api/ilce/GetByCoordinat")
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to get location by coords: %w", err)
|
|
}
|
|
|
|
var response struct {
|
|
Success bool `json:"success"`
|
|
ResultObject []struct {
|
|
ID int `json:"cityID"`
|
|
} `json:"resultObject"`
|
|
}
|
|
if err := res.Unmarshal(&response); err != nil {
|
|
return "", fmt.Errorf("failed to unmarshal city response: %w", err)
|
|
}
|
|
if !response.Success {
|
|
return "", fmt.Errorf("failed to get location by coordinates from upstream: %w", errors.New(res.String()))
|
|
}
|
|
if len(response.ResultObject) == 0 {
|
|
return "", fmt.Errorf("failed to resolve location by coordinates: %w", errors.New("empty location result"))
|
|
}
|
|
|
|
return fmt.Sprintf("%d", response.ResultObject[0].ID), nil
|
|
}
|
|
|
|
func (d Provider) Get(ctx context.Context, locationID string) ([]prayer.Times, error) {
|
|
res, err := d.http.NewRequest().
|
|
SetContext(ctx).
|
|
SetQueryParam("ilceId", locationID).
|
|
Get("https://namazvakti.diyanet.gov.tr/api/NamazVakti/Gunluk")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get prayer times by location id: %w", err)
|
|
}
|
|
|
|
times, err := d.parseResponse(res)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse prayer times response: %w", err)
|
|
}
|
|
|
|
return times, nil
|
|
}
|
|
|
|
func (d Provider) parseResponse(res *req.Response) ([]prayer.Times, error) {
|
|
var response struct {
|
|
Success bool `json:"success"`
|
|
ResultObject struct {
|
|
PrayerTimes []struct {
|
|
Date time.Time `json:"miladi_tarih_uzun_Iso8601"`
|
|
DateIslamic string `json:"hicri_tarih_uzun"`
|
|
Fajr time.Time `json:"imsak"`
|
|
Sunrise time.Time `json:"gunes"`
|
|
Dhuhr time.Time `json:"ogle"`
|
|
Asr time.Time `json:"ikindi"`
|
|
Sunset time.Time `json:"gunes_batis"`
|
|
Maghrib time.Time `json:"aksam"`
|
|
Isha time.Time `json:"yatsi"`
|
|
} `json:"namazVakti"`
|
|
} `json:"resultObject"`
|
|
}
|
|
if err := res.Unmarshal(&response); err != nil {
|
|
return nil, fmt.Errorf("failed to unmarshal as json: %w", err)
|
|
}
|
|
if !response.Success {
|
|
return nil, fmt.Errorf("failed to get prayer times from upstream: %w", errors.New(res.String()))
|
|
}
|
|
|
|
if len(response.ResultObject.PrayerTimes) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
var times []prayer.Times
|
|
today := time.Now().UTC().Truncate(time.Hour * 24)
|
|
for _, pt := range response.ResultObject.PrayerTimes {
|
|
then := pt.Date.UTC().Truncate(time.Hour * 24)
|
|
if then.Before(today) {
|
|
continue
|
|
}
|
|
|
|
times = append(times, prayer.Times{
|
|
Date: pt.Date.Format(time.DateOnly),
|
|
DateIslamic: pt.DateIslamic,
|
|
Fajr: pt.Fajr.Format("15:04"),
|
|
Sunrise: pt.Sunrise.Format("15:04"),
|
|
Dhuhr: pt.Dhuhr.Format("15:04"),
|
|
Asr: pt.Asr.Format("15:04"),
|
|
Sunset: pt.Sunset.Format("15:04"),
|
|
Maghrib: pt.Maghrib.Format("15:04"),
|
|
Isha: pt.Isha.Format("15:04"),
|
|
})
|
|
}
|
|
return times, nil
|
|
}
|