feat: Return location info and Hijri date from the prayer times endpoint
This commit is contained in:
+45
-24
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/imroc/req/v3"
|
||||
|
||||
"prayertimes/pkg/hijricalendar"
|
||||
"prayertimes/pkg/prayer"
|
||||
)
|
||||
|
||||
@@ -21,18 +22,20 @@ func New(c *req.Client) Provider {
|
||||
}
|
||||
}
|
||||
|
||||
func (d Provider) GetByCoords(ctx context.Context, coords prayer.Coordinates) ([]prayer.Times, error) {
|
||||
func (d Provider) GetByCoords(ctx context.Context, coords prayer.Coordinates) (prayer.TimesResult, error) {
|
||||
locationID, err := d.getLocationIDByCoords(ctx, coords)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve location by coordinates: %w", err)
|
||||
return prayer.TimesResult{}, fmt.Errorf("failed to resolve location by coordinates: %w", err)
|
||||
}
|
||||
|
||||
times, err := d.Get(ctx, locationID)
|
||||
result, err := d.Get(ctx, locationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get prayer times by coordinates: %w", err)
|
||||
return prayer.TimesResult{}, fmt.Errorf("failed to get prayer times by coordinates: %w", err)
|
||||
}
|
||||
result.Location.Latitude = coords.Latitude
|
||||
result.Location.Longitude = coords.Longitude
|
||||
|
||||
return times, nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (d Provider) getLocationIDByCoords(ctx context.Context, coords prayer.Coordinates) (string, error) {
|
||||
@@ -66,27 +69,32 @@ func (d Provider) getLocationIDByCoords(ctx context.Context, coords prayer.Coord
|
||||
return fmt.Sprintf("%d", response.ResultObject[0].ID), nil
|
||||
}
|
||||
|
||||
func (d Provider) Get(ctx context.Context, locationID string) ([]prayer.Times, error) {
|
||||
func (d Provider) Get(ctx context.Context, locationID string) (prayer.TimesResult, 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)
|
||||
return prayer.TimesResult{}, fmt.Errorf("failed to get prayer times by location id: %w", err)
|
||||
}
|
||||
|
||||
times, err := d.parseResponse(res)
|
||||
result, err := d.parseResponse(res)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse prayer times response: %w", err)
|
||||
return prayer.TimesResult{}, fmt.Errorf("failed to parse prayer times response: %w", err)
|
||||
}
|
||||
result.Location.ID = parseIntOrZero(locationID)
|
||||
|
||||
return times, nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (d Provider) parseResponse(res *req.Response) ([]prayer.Times, error) {
|
||||
func (d Provider) parseResponse(res *req.Response) (prayer.TimesResult, error) {
|
||||
var response struct {
|
||||
Success bool `json:"success"`
|
||||
ResultObject struct {
|
||||
Location struct {
|
||||
ID int `json:"konum_Id"`
|
||||
Timezone string `json:"timezone"`
|
||||
} `json:"konum"`
|
||||
PrayerTimes []struct {
|
||||
Date time.Time `json:"miladi_tarih_uzun_Iso8601"`
|
||||
DateIslamic string `json:"hicri_tarih_uzun"`
|
||||
@@ -101,14 +109,14 @@ func (d Provider) parseResponse(res *req.Response) ([]prayer.Times, error) {
|
||||
} `json:"resultObject"`
|
||||
}
|
||||
if err := res.Unmarshal(&response); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal as json: %w", err)
|
||||
return prayer.TimesResult{}, 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()))
|
||||
return prayer.TimesResult{}, fmt.Errorf("failed to get prayer times from upstream: %w", errors.New(res.String()))
|
||||
}
|
||||
|
||||
if len(response.ResultObject.PrayerTimes) == 0 {
|
||||
return nil, nil
|
||||
return prayer.TimesResult{}, nil
|
||||
}
|
||||
|
||||
var times []prayer.Times
|
||||
@@ -120,16 +128,29 @@ func (d Provider) parseResponse(res *req.Response) ([]prayer.Times, error) {
|
||||
}
|
||||
|
||||
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"),
|
||||
Date: pt.Date.UTC(),
|
||||
DateHijri: hijricalendar.ToISODate(pt.Date.UTC()),
|
||||
Fajr: pt.Fajr.UTC(),
|
||||
Sunrise: pt.Sunrise.UTC(),
|
||||
Dhuhr: pt.Dhuhr.UTC(),
|
||||
Asr: pt.Asr.UTC(),
|
||||
Sunset: pt.Sunset.UTC(),
|
||||
Maghrib: pt.Maghrib.UTC(),
|
||||
Isha: pt.Isha.UTC(),
|
||||
})
|
||||
}
|
||||
return times, nil
|
||||
|
||||
return prayer.TimesResult{
|
||||
Location: prayer.Location{
|
||||
ID: response.ResultObject.Location.ID,
|
||||
Timezone: response.ResultObject.Location.Timezone,
|
||||
},
|
||||
Times: times,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseIntOrZero(value string) int {
|
||||
var out int
|
||||
_, _ = fmt.Sscanf(value, "%d", &out)
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -15,37 +15,37 @@ func TestDiyanetAPI_GetByCoords(t *testing.T) {
|
||||
t.Run("by coords", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
times, err := p.GetByCoords(context.Background(), prayer.Coordinates{
|
||||
result, err := p.GetByCoords(context.Background(), prayer.Coordinates{
|
||||
Latitude: 52.5100846,
|
||||
Longitude: 13.4518284,
|
||||
})
|
||||
if err != nil {
|
||||
t.Skipf("skipping live endpoint test due to upstream/network error: %v", err)
|
||||
}
|
||||
if len(times) == 0 {
|
||||
if len(result.Times) == 0 {
|
||||
t.Skip("skipping live endpoint test because upstream returned no times")
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, times)
|
||||
t.Logf("%#+v", times[0])
|
||||
assert.NotEmpty(t, result.Times)
|
||||
t.Logf("location=%+v first=%+v", result.Location, result.Times[0])
|
||||
})
|
||||
|
||||
t.Run("by id", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
times, err := p.Get(context.Background(), "11104")
|
||||
result, err := p.Get(context.Background(), "11104")
|
||||
if err != nil {
|
||||
t.Skipf("skipping live endpoint test due to upstream/network error: %v", err)
|
||||
}
|
||||
if len(times) == 0 {
|
||||
if len(result.Times) == 0 {
|
||||
t.Skip("skipping live endpoint test because upstream returned no times")
|
||||
}
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, times)
|
||||
for _, time := range times {
|
||||
t.Log(time)
|
||||
assert.NotEmpty(t, result.Times)
|
||||
for _, item := range result.Times {
|
||||
t.Log(item)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user