Skip to content

Commit

Permalink
Add working geo param
Browse files Browse the repository at this point in the history
  • Loading branch information
victrme committed Nov 27, 2024
1 parent e0e7dfd commit 9587a5e
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 53 deletions.
4 changes: 2 additions & 2 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,14 @@ <h2>Test</h2>
<p>
<label>
Latitude <br />
<input type="number" name="lat" placeholder="48.853" />
<input type="text" name="lat" placeholder="48.853" />
</label>
</p>

<p>
<label>
Longitude <br />
<input type="number" name="lon" placeholder="2.348" />
<input type="text" name="lon" placeholder="2.348" />
</label>
</p>

Expand Down
54 changes: 45 additions & 9 deletions src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ACCUWEATHER_STRUCT, FORECA_STRUCT, SIMPLE_STRUCT } from './structs.ts'
import { QueryParams } from './types.ts'
import { STRUCTS } from './structs.ts'
import main from './index.ts'

type OptionalParams = Partial<Record<keyof QueryParams, string>>
Expand All @@ -17,7 +17,7 @@ Deno.test('Provider: Accuweather', async function () {
lat: LAT,
lon: LON,
}),
FORECA_STRUCT,
STRUCTS.FORECA.WEATHER,
)
})

Expand All @@ -28,7 +28,7 @@ Deno.test('Provider: Foreca', async function () {
lat: LAT,
lon: LON,
}),
FORECA_STRUCT,
STRUCTS.FORECA.WEATHER,
)
})

Expand All @@ -39,7 +39,7 @@ Deno.test('Provider: Auto', async function () {
lat: LAT,
lon: LON,
}),
SIMPLE_STRUCT,
STRUCTS.SIMPLE.WEATHER,
)
})

Expand All @@ -50,7 +50,7 @@ Deno.test.ignore('Provider: Wunderground', async function () {
lat: LAT,
lon: LON,
}),
ACCUWEATHER_STRUCT,
STRUCTS.ACCUWEATHER.WEATHER,
)
})

Expand All @@ -64,7 +64,7 @@ Deno.test('Simple data: Accuweather', async function () {
lat: LAT,
lon: LON,
}),
SIMPLE_STRUCT,
STRUCTS.SIMPLE.WEATHER,
)
})

Expand All @@ -76,7 +76,7 @@ Deno.test('Simple data: Foreca', async function () {
lat: LAT,
lon: LON,
}),
SIMPLE_STRUCT,
STRUCTS.SIMPLE.WEATHER,
)
})

Expand All @@ -88,7 +88,43 @@ Deno.test('Simple data: Auto overrides "all" data', async function () {
lat: LAT,
lon: LON,
}),
SIMPLE_STRUCT,
STRUCTS.SIMPLE.WEATHER,
)
})

Deno.test.ignore('Geo: Accuweather', async function () {
compareTypes(
await getJson({
provider: 'accuweather',
geo: 'true',
lat: LAT,
lon: LON,
}),
STRUCTS.ACCUWEATHER.GEO,
)
})

Deno.test.ignore('Geo: Foreca', async function () {
compareTypes(
await getJson({
provider: 'accuweather',
geo: 'true',
lat: LAT,
lon: LON,
}),
STRUCTS.ACCUWEATHER.GEO,
)
})

Deno.test.ignore('Geo: Simple', async function () {
compareTypes(
await getJson({
provider: 'accuweather',
geo: 'true',
lat: LAT,
lon: LON,
}),
STRUCTS.ACCUWEATHER.GEO,
)
})

Expand Down Expand Up @@ -129,8 +165,8 @@ Deno.test('Params: Wrong unit falls back to C', async function () {
Deno.test('Params: Has provider & no query/coords', async function () {
const req = new Request(`https://example.com?provider=accuweather`)
const resp = await main.fetch(req)

assert(resp.status === 503)
console.clear()
})

// Helpers
Expand Down
19 changes: 12 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import './parser.ts'
import * as foreca from './providers/foreca.ts'
import * as weathercom from './providers/weathercom.ts'
import * as accuweather from './providers/accuweather.ts'
import toSimpleWeather from './providers/simple.ts'
import { isAccuweather, isForeca } from './types.ts'
import toSimpleWeather, { toSimpleLocations } from './providers/simple.ts'
import { isAccuweather, isAccuweatherLocation, isForeca, isForecaLocation } from './types.ts'

import type { AccuWeather, Foreca, QueryParams } from './types.ts'
import type { AccuWeather, Foreca, QueryParams, Simple } from './types.ts'

/**
* Racle-météo can be called like a Cloudflare Worker, using fetch().
Expand Down Expand Up @@ -84,16 +84,21 @@ async function main(request: Request) {
}

if (params.geo && params.provider) {
let list: AccuWeather.Locations | Foreca.Location = []
let list: unknown[] = []

if (params.provider === 'accuweather') {
if (params.provider === 'accuweather' || params.provider === 'auto') {
list = await accuweather.geo(params)
}

if (params.provider === 'foreca') {
if (params.provider === 'foreca' || (params.provider === 'auto' && list.length === 0)) {
list = await foreca.geo(params)
}

if (params.provider === 'auto' || params.data === 'simple') {
if (isAccuweatherLocation(list) || isForecaLocation(list)) {
list = toSimpleLocations(list)
}
}

return new Response(JSON.stringify(list), {
status,
headers: {
Expand Down
6 changes: 3 additions & 3 deletions src/providers/accuweather.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default async function accuweather(params: QueryParams): Promise<AccuWeat
return api
}

export async function geo(params: QueryParams): Promise<AccuWeather.Locations> {
export async function geo(params: QueryParams): Promise<AccuWeather.Location[]> {
return await geolocationFromQuery(params.query)
}

Expand Down Expand Up @@ -215,7 +215,7 @@ async function fetchPageContent(params: QueryParams): Promise<string> {
return html
}

async function geolocationFromQuery(query: string): Promise<AccuWeather.Locations> {
async function geolocationFromQuery(query: string): Promise<AccuWeather.Location[]> {
const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0',
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
Expand All @@ -226,7 +226,7 @@ async function geolocationFromQuery(query: string): Promise<AccuWeather.Location

const path = `https://www.accuweather.com/web-api/autocomplete?query=${query}&language=en-us&r=${new Date().getTime()}`
const resp = await fetch(path, { headers })
const result = (await resp?.json()) as AccuWeather.Locations
const result = (await resp?.json()) as AccuWeather.Location[]

if (result.length > 1) {
return result
Expand Down
35 changes: 22 additions & 13 deletions src/providers/foreca.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ export default async function foreca(params: QueryParams): Promise<Foreca.Weathe
return api
}

export async function geo(params: QueryParams): Promise<Foreca.Location> {
return await getForecaLocation({
lat: params.lat,
lon: params.lon,
query: params.query,
})
export async function geo(params: QueryParams): Promise<Foreca.Location[]> {
return [
await getForecaLocation({
lat: params.lat,
lon: params.lon,
query: params.query,
}),
]
}

export async function debugContent(params: QueryParams): Promise<Foreca.Content> {
Expand Down Expand Up @@ -213,11 +215,18 @@ export async function fetchPageContent({ lat, lon, query, lang, unit }: QueryPar
}

export async function getForecaLocation({ lat, lon, query }: Partial<QueryParams>): Promise<Foreca.Location> {
type LocationSearch = {
query: string
language: string
results: Foreca.Location[]
}

if (query) {
const path = `https://api.foreca.net/locations/search/${query}.json`
const resp = await fetch(path)
const json = await resp.json()
return json.results[0]
const json = await resp.json() as LocationSearch
const location = json.results[0]
return location
} else {
const path = `https://api.foreca.net/locations/${lon},${lat}.json`
const resp = await fetch(path)
Expand All @@ -226,8 +235,8 @@ export async function getForecaLocation({ lat, lon, query }: Partial<QueryParams
}
}

// export async function getForecaData(lat, lon) {
// const { id } = await getForecaLocation(lat, lon)
// const resp = await fetch(`https://api.foreca.net/data/favorites/${id}.json`)
// return await resp.json()
// }
async function _getForecaData(lat: string, lon: string) {
const { id } = await getForecaLocation({ lat, lon })
const resp = await fetch(`https://api.foreca.net/data/favorites/${id}.json`)
return await resp.json()
}
14 changes: 13 additions & 1 deletion src/providers/simple.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AccuWeather, Foreca, QueryParams, Simple } from '../types.ts'
import { isAccuweather, isForeca } from '../types.ts'
import { isAccuweather, isAccuweatherLocation, isForeca, isForecaLocation } from '../types.ts'

export default function toSimpleWeather(json: AccuWeather.Weather | Foreca.Weather, params: QueryParams): Simple.Weather {
const { provider, unit } = params
Expand Down Expand Up @@ -57,6 +57,18 @@ export default function toSimpleWeather(json: AccuWeather.Weather | Foreca.Weath
return simple
}

export function toSimpleLocations(json: AccuWeather.Location[] | Foreca.Location[]): Simple.Locations {
if (isAccuweatherLocation(json)) {
return json.map((loc) => ({ name: loc.name, detail: loc.longName }))
}

if (isForecaLocation(json)) {
return json.map((loc) => ({ name: loc.name, detail: loc.defaultName }))
}

throw new Error('Cannot get a valid location')
}

function transformToSimpleIcon(id: string, provider: 'accuweather' | 'foreca'): string {
for (const [simpleId, providerIds] of Object.entries(SIMPLE_ICONS)) {
const list = providerIds[provider]
Expand Down
42 changes: 39 additions & 3 deletions src/structs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const SIMPLE_STRUCT = {
const SIMPLE_STRUCT = {
meta: {
url: 'string',
lang: 'string',
Expand Down Expand Up @@ -29,7 +29,14 @@ export const SIMPLE_STRUCT = {
],
}

export const ACCUWEATHER_STRUCT = {
const SIMPLE_GEO_STRUCT = [
{
name: 'string',
details: 'string',
},
]

const ACCUWEATHER_STRUCT = {
meta: {
url: 'string',
lang: 'string',
Expand Down Expand Up @@ -69,7 +76,14 @@ export const ACCUWEATHER_STRUCT = {
],
}

export const FORECA_STRUCT = {
const ACCUWEATHER_GEO_STRUCT = [
{
name: 'string',
details: 'string',
},
]

const FORECA_STRUCT = {
meta: {
url: 'string',
lang: 'string',
Expand Down Expand Up @@ -102,3 +116,25 @@ export const FORECA_STRUCT = {
},
],
}

const FORECA_GEO_STRUCT = [
{
name: 'string',
details: 'string',
},
]

export const STRUCTS = {
ACCUWEATHER: {
WEATHER: ACCUWEATHER_STRUCT,
GEO: ACCUWEATHER_GEO_STRUCT,
},
FORECA: {
WEATHER: FORECA_STRUCT,
GEO: FORECA_GEO_STRUCT,
},
SIMPLE: {
WEATHER: SIMPLE_STRUCT,
GEO: SIMPLE_GEO_STRUCT,
},
}
Loading

0 comments on commit 9587a5e

Please sign in to comment.