Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
Signed-off-by: George Lemon <[email protected]>
  • Loading branch information
georgelemon committed Sep 15, 2024
1 parent c976773 commit 14c740a
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 6 deletions.
Binary file added .github/pexels.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ testresults/
/tests/*
!/tests/*.nim
!/tests/*.nims
/bin
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<p align="center">
<img src="https://github.com/openpeeps/PKG/blob/main/.github/logo.png" width="90px"><br>
OpenPeeps repository template for developing libraries,<br>projects and other cool things. 👑 Written in Nim language
<img src="https://github.com/openpeeps/pexels-nim/blob/main/.github/pexels.png" width="210px"><br>
👑 Nim library for the Pexels API
</p>

<p align="center">
<code>nimble install {PKG}</code>
<code>nimble install pexels</code>
</p>

<p align="center">
<a href="https://github.com/">API reference</a><br>
<img src="https://github.com/openpeeps/pistachio/workflows/test/badge.svg" alt="Github Actions"> <img src="https://github.com/openpeeps/pistachio/workflows/docs/badge.svg" alt="Github Actions">
<img src="https://github.com/openpeeps/pexels-nim/workflows/test/badge.svg" alt="Github Actions"> <img src="https://github.com/openpeeps/pexels-nim/workflows/docs/badge.svg" alt="Github Actions">
</p>

## 😍 Key Features
Expand All @@ -26,5 +26,5 @@
- 🥰 [Donate via PayPal address](https://www.paypal.com/donate/?hosted_button_id=RJK3ZTDWPL55C)

### 🎩 License
{PKG} | MIT license. [Made by Humans from OpenPeeps](https://github.com/openpeeps).<br>
Copyright &copy; 2023 OpenPeeps & Contributors &mdash; All rights reserved.
Pexels for Nim language | MIT license. [Made by Humans from OpenPeeps](https://github.com/openpeeps).<br>
Copyright &copy; 2024 OpenPeeps & Contributors &mdash; All rights reserved.
42 changes: 42 additions & 0 deletions pexels.nimble
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Package

version = "0.1.0"
author = "George Lemon"
description = "Nim library for the Pexels API"
license = "MIT"
srcDir = "src"


# Dependencies

requires "nim >= 2.0.2"
requires "jsony"

import std/[os, macros]
proc targetSource(x: string): string {.compileTime.} =
result = x & " src" / "pexels" / x & ".nim"

macro genTaskBuilders*(modules: static seq[string]) =
result = newStmtList()
for k in modules:
add result,
nnkCommand.newTree(
ident"task",
ident("build_" & k),
newLit("build /" & k),
nnkStmtList.newTree(
nnkCommand.newTree(
ident"exec",
nnkInfix.newTree(
ident"&",
newLit"nim c -d:ssl -o:./bin/",
newCall(
ident"targetSource",
newLit(k)
)
)
)
)
)

genTaskBuilders(@["photo", "video"])
2 changes: 2 additions & 0 deletions src/pexels.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import pexels/[photo]
export photo
119 changes: 119 additions & 0 deletions src/pexels/metaclient.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# This package provides a Nim API client for the
# Pexels.com API: https://www.pexels.com/api/
#
# (c) 2024 George Lemon | MIT License
# Made by Humans from OpenPeeps
# https://github.com/openpeeps/pexels-nim

import std/[asyncdispatch, httpclient, tables,
strutils, sequtils, times]

from std/httpcore import HttpMethod

import pkg/jsony

export HttpMethod, asyncdispatch, httpclient,
tables, sequtils

type
PexelsEndpoint* = enum
epSearchPhotos = "search"
epCuratedPhotos = "curated"
epGetPhoto = "photos/$1"
epSearchVideos = "videos/search"
epPopularVideos = "videos/popular"
epGetVideo = "videos/videos/$1"
epFeaturedCollections = "collections/featured"
epMyCollections = "collections"
epCollectionMedia = "collections/$1"

PexelsLocale* = enum
localeAny
localeEN = "en-US"
localePT = "pt-BR"
localeES = "es-ES"
localeCA = "ca-ES"
localeDE = "de-DE"
localeIT = "it-IT"
localeFR = "fr-FR"
localeSV = "sv-SE"
localeID = "id-ID"
localePL = "pl-PL"
localeJA = "ja-JP"
localeZH_TW = "zh-TW"
localeZH = "zh-CN"
localeKO = "ko-KR"
localeTH = "th-TH"
localeNL = "nl-NL"
localeHU = "hu-HU"
localeVI = "vi-VN"
localeCS = "cs-CZ"
localeDA = "da-DK"
localeFI = "fi-FI"
localeUK = "uk-UA"
localeEL = "el-GR"
localeRO = "ro-RO"
localeNB = "nb-NO"
localeSK = "sk-SK"
localeTR = "tr-TR"
localeRU = "ru-RU"

PexelsListingResponse* = object of RootObj
page*, per_page*, total_results*: uint
next_page*, prev_page*: string

Pexels* = ref object
apiKey*: string
client*: AsyncHttpClient
query*: QueryTable

QueryTable* = OrderedTable[string, string]

const
basePexelsUri = "https://api.pexels.com/v1/"

proc newPexelsClient*(apiKey: sink string): Pexels =
## Creates a new instance of `Pexels`.
new(result)
result.apiKey = apiKey
result.client = newAsyncHttpClient()
result.client.headers = newHttpHeaders({
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": result.apiKey,
})

#
# JSONY hooks
#
proc parseHook*(s: string, i: var int, v: var Time) =
var str: string
parseHook(s, i, str)
v = parseTime(str, "yyyy-MM-dd'T'hh:mm:ss'.'ffffffz", local())

proc dumpHook*(s: var string, v: Time) =
add s, '"'
add s, v.format("yyyy-MM-dd'T'hh:mm:ss'.'ffffffz", local())
add s, '"'

proc `$`*(query: QueryTable): string =
## Convert `query` QueryTable to string
if query.len > 0:
add result, "?"
add result, join(query.keys.toSeq.mapIt(it & "=" & query[it]), "&")

#
# Http Request Handles
#
proc endpoint*(uri: PexelsEndpoint,
query: QueryTable, args: seq[string]): string =
## Return the url string of an endpoint
result = basePexelsUri & $uri & $query
if args.len > 0:
result = result % args

proc httpGet*(client: Pexels, ep: PexelsEndpoint,
args: seq[string] = newSeq[string](0)): Future[AsyncResponse] {.async.} =
## Makes a `GET` request to some `PexelsEndpoint`
let uri = endpoint(ep, client.query, args)
result = await client.client.request(uri, HttpGet)
122 changes: 122 additions & 0 deletions src/pexels/photo.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# This package provides a Nim API client for the
# Pexels.com API: https://www.pexels.com/api/
#
# (c) 2024 George Lemon | MIT License
# Made by Humans from OpenPeeps
# https://github.com/openpeeps/pexels-nim
import std/[strutils, colors]
import pkg/jsony

import ./metaclient

type
PexelsPhotoSizes* = object
original*, large2x*, large*,
medium*, small*, portrait*,
landscape*, tiny*: string

PexelsPhotoResponse* = object
id*, width*, height*: uint
url*, photographer*, photographer_url*,
avg_color*: string
src*: PexelsPhotoSizes
liked*: bool # ? not sure what's this
alt*: string

PexelsPhotosResponse* = object of PexelsListingResponse
photos*: seq[PexelsPhotoResponse]

PexelsOrientationParameter* = enum
orientationAny
orientationLandscape = "landscape",
orientationPortrait = "portrait",
orientationSquare = "square"

PexelsSizeParameter* = enum
sizeAny
sizeLarge = "large"
sizeMedium = "medium"
sizeSmall = "small"

PexelsColorParameter* = enum
colorAny
colorRed = "red"
colorOrange = "orange"
colorYellow = "yellow"
colorGreen = "green"
colorTurquoise = "turquoise"
colorBlue = "blue"
colorViolet = "violet"
colorPink = "pink"
colorBrown = "brown"
colorBlack = "black"
colorGray = "gray"
colorWhite = "white"
colorHex

PexelsSearchParameters* = ref object
orientation*: PexelsOrientationParameter
size*: PexelsSizeParameter
case color*: PexelsColorParameter
of colorHex:
hexColor*: Color
else: discard
locale*: PexelsLocale
perPage*: uint = 15
page*: uint = 1


proc `$`*(photosResponse: PexelsPhotosResponse): string =
## Convert `PexelsPhotosResponse` object to JSON
photosResponse.toJson()

proc `$`*(photoResponse: PexelsPhotoResponse): string =
## Convert `PexelsPhotoResponse` object to JSON
photoResponse.toJson()

proc search*(pexels: Pexels, query: string): Future[PexelsPhotosResponse] {.async.} =
pexels.query["query"] = query
let res: AsyncResponse = await pexels.httpGet(PexelsEndpoint.epSearchPhotos, @[])
let body = await res.body
result = fromJson(body, PexelsPhotosResponse)
pexels.client.close()

proc search*(pexels: Pexels, query: string, perPage: uint): Future[PexelsPhotosResponse] {.async.} =
pexels.query["query"] = query
pexels.query["per_page"] = $(perPage)
let res: AsyncResponse = await pexels.httpGet(PexelsEndpoint.epSearchPhotos, @[])
let body = await res.body
result = fromJson(body, PexelsPhotosResponse)
pexels.client.close()

proc insert*(q: var QueryTable, p: PexelsSearchParameters) =
case p.locale
of localeAny: discard
else:
q["locale"] = $(p.locale)
case p.color
of colorAny: discard
else:
q["color"] = $(p.color)
case p.size:
of sizeAny: discard
else:
q["size"] = $(p.size)
case p.orientation:
of orientationAny: discard
else:
q["orientation"] = $(p.orientation)
q["page"] = $(p.page)
q["per_page"] = $(p.perPage)

proc search*(pexels: Pexels, query: string, params: PexelsSearchParameters): Future[PexelsPhotosResponse] {.async.} =
pexels.query["query"] = query
insert pexels.query, params
let res: AsyncResponse = await pexels.httpGet(PexelsEndpoint.epSearchPhotos, @[])
let body = await res.body
result = fromJson(body, PexelsPhotosResponse)
pexels.client.close()

iterator items*(photosResponse: PexelsPhotosResponse): PexelsPhotoResponse =
for p in photosResponse.photos:
yield p

0 comments on commit 14c740a

Please sign in to comment.