mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-17 21:12:42 +00:00
Merge pull request #6504 from Yardanico/patch-8
[JSON] getBVal -> getBool; getFNum -> getFloat; getNum -> getBiggestInt; add getInt
This commit is contained in:
@@ -8,3 +8,5 @@
|
||||
- Arrays of char cannot be converted to ``cstring`` anymore, pointers to
|
||||
arrays of char can! This means ``$`` for arrays can finally exist
|
||||
in ``system.nim`` and do the right thing.
|
||||
- JSON: Deprecated `getBVal`, `getFNum`, and `getNum` in favour to
|
||||
`getBool`, `getFloat`, `getBiggestInt`. Also `getInt` procedure was added.
|
||||
@@ -37,15 +37,15 @@
|
||||
## Retrieving the value of a JSON node can then be achieved using one of the
|
||||
## helper procedures, which include:
|
||||
##
|
||||
## * ``getNum``
|
||||
## * ``getFNum``
|
||||
## * ``getInt``
|
||||
## * ``getFloat``
|
||||
## * ``getStr``
|
||||
## * ``getBVal``
|
||||
## * ``getBool``
|
||||
##
|
||||
## To retrieve the value of ``"key"`` you can do the following:
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## doAssert jsonNode["key"].getFNum() == 3.14
|
||||
## doAssert jsonNode["key"].getFloat() == 3.14
|
||||
##
|
||||
## The ``[]`` operator will raise an exception when the specified field does
|
||||
## not exist. If you wish to avoid this behaviour you can use the ``{}``
|
||||
@@ -681,14 +681,23 @@ proc getStr*(n: JsonNode, default: string = ""): string =
|
||||
if n.isNil or n.kind != JString: return default
|
||||
else: return n.str
|
||||
|
||||
proc getNum*(n: JsonNode, default: BiggestInt = 0): BiggestInt =
|
||||
proc getInt*(n: JsonNode, default: int = 0): int =
|
||||
## Retrieves the int value of a `JInt JsonNode`.
|
||||
##
|
||||
## Returns ``default`` if ``n`` is not a ``JInt``, or if ``n`` is nil.
|
||||
if n.isNil or n.kind != JInt: return default
|
||||
else: return int(n.num)
|
||||
|
||||
proc getBiggestInt*(n: JsonNode, default: BiggestInt = 0): BiggestInt =
|
||||
## Retrieves the BiggestInt value of a `JInt JsonNode`.
|
||||
##
|
||||
## Returns ``default`` if ``n`` is not a ``JInt``, or if ``n`` is nil.
|
||||
if n.isNil or n.kind != JInt: return default
|
||||
else: return n.num
|
||||
|
||||
proc getFNum*(n: JsonNode, default: float = 0.0): float =
|
||||
{.deprecated: [getNum: getBiggestInt].}
|
||||
|
||||
proc getFloat*(n: JsonNode, default: float = 0.0): float =
|
||||
## Retrieves the float value of a `JFloat JsonNode`.
|
||||
##
|
||||
## Returns ``default`` if ``n`` is not a ``JFloat`` or ``JInt``, or if ``n`` is nil.
|
||||
@@ -698,13 +707,17 @@ proc getFNum*(n: JsonNode, default: float = 0.0): float =
|
||||
of JInt: return float(n.num)
|
||||
else: return default
|
||||
|
||||
proc getBVal*(n: JsonNode, default: bool = false): bool =
|
||||
{.deprecated: [getFNum: getFloat].}
|
||||
|
||||
proc getBool*(n: JsonNode, default: bool = false): bool =
|
||||
## Retrieves the bool value of a `JBool JsonNode`.
|
||||
##
|
||||
## Returns ``default`` if ``n`` is not a ``JBool``, or if ``n`` is nil.
|
||||
if n.isNil or n.kind != JBool: return default
|
||||
else: return n.bval
|
||||
|
||||
{.deprecated: [getBVal: getBool].}
|
||||
|
||||
proc getFields*(n: JsonNode,
|
||||
default = initOrderedTable[string, JsonNode](4)):
|
||||
OrderedTable[string, JsonNode] =
|
||||
@@ -1342,7 +1355,7 @@ proc getEnum(node: JsonNode, ast: string, T: typedesc): T =
|
||||
# TODO: I shouldn't need this proc.
|
||||
proc convert[T](x: BiggestInt): T = T(x)
|
||||
verifyJsonKind(node, {JInt}, ast)
|
||||
return convert[T](node.getNum())
|
||||
return convert[T](node.getBiggestInt())
|
||||
else:
|
||||
verifyJsonKind(node, {JString}, ast)
|
||||
return parseEnum[T](node.getStr())
|
||||
|
||||
@@ -87,8 +87,8 @@ when isMainModule:
|
||||
|
||||
result = to(node, TestVariant)
|
||||
doAssert result.name == node["name"].getStr()
|
||||
doAssert result.age == node["age"].getNum().uint8
|
||||
doAssert result.other == node["other"].getNum()
|
||||
doAssert result.age == node["age"].getInt().uint8
|
||||
doAssert result.other == node["other"].getBiggestInt()
|
||||
|
||||
# TODO: Test object variant with set in of branch.
|
||||
# TODO: Should we support heterogenous arrays?
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
# Based on bountysource.cr located at https://github.com/crystal-lang/crystal-website/blob/master/scripts/bountysource.cr
|
||||
import httpclient, asyncdispatch, json, strutils, os, strtabs, sequtils, future,
|
||||
algorithm, times
|
||||
|
||||
type
|
||||
BountySource = ref object
|
||||
client: AsyncHttpClient
|
||||
team: string
|
||||
|
||||
Sponsor = object
|
||||
name, url, logo: string
|
||||
amount, allTime: float
|
||||
since: TimeInfo
|
||||
|
||||
const
|
||||
team = "nim"
|
||||
apiUrl = "https://api.bountysource.com"
|
||||
githubApiUrl = "https://api.github.com"
|
||||
|
||||
proc newBountySource(team, token: string): BountySource =
|
||||
result = BountySource(
|
||||
client: newAsyncHttpClient(userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"),
|
||||
team: team
|
||||
)
|
||||
|
||||
# Set up headers
|
||||
result.client.headers["Accept"] = "application/vnd.bountysource+json; version=2"
|
||||
result.client.headers["Authorization"] = "token " & token
|
||||
result.client.headers["Referer"] = "https://salt.bountysource.com/teams/nim/admin/supporters"
|
||||
result.client.headers["Origin"] = "https://salt.bountysource.com/"
|
||||
|
||||
proc getSupporters(self: BountySource): Future[JsonNode] {.async.} =
|
||||
let response = await self.client.get(apiUrl &
|
||||
"/supporters?order=monthly&per_page=200&team_slug=" & self.team)
|
||||
doAssert response.status.startsWith($Http200)
|
||||
return parseJson(await response.body)
|
||||
|
||||
proc getGithubUser(username: string): Future[JsonNode] {.async.} =
|
||||
let client = newAsyncHttpClient()
|
||||
let response = await client.get(githubApiUrl & "/users/" & username)
|
||||
if response.status.startsWith($Http200):
|
||||
return parseJson(await response.body)
|
||||
else:
|
||||
echo("Could not get Github user: ", username, ". ", response.status)
|
||||
return nil
|
||||
|
||||
proc processSupporters(supporters: JsonNode) =
|
||||
var before = supporters.elems.len
|
||||
supporters.elems.keepIf(
|
||||
item => item["display_name"].getStr != "Anonymous"
|
||||
)
|
||||
echo("Discarded ", before - supporters.elems.len, " anonymous sponsors.")
|
||||
echo("Found ", supporters.elems.len, " named sponsors.")
|
||||
|
||||
supporters.elems.sort(
|
||||
(x, y) => cmp(y["alltime_amount"].getFNum, x["alltime_amount"].getFNum)
|
||||
)
|
||||
|
||||
|
||||
proc quote(text: string): string =
|
||||
if {' ', ','} in text:
|
||||
return "\"" & text & "\""
|
||||
else:
|
||||
return text
|
||||
|
||||
proc getLevel(amount: float): int =
|
||||
result = 0
|
||||
const levels = [250, 150, 75, 25, 10, 5, 1]
|
||||
for i in levels:
|
||||
if amount.int <= i:
|
||||
result = i
|
||||
|
||||
proc writeCsv(sponsors: seq[Sponsor], filename="sponsors.new.csv") =
|
||||
var csv = ""
|
||||
csv.add "logo, name, url, this_month, all_time, since, level\n"
|
||||
for sponsor in sponsors:
|
||||
csv.add "$#,$#,$#,$#,$#,$#,$#\n" % [
|
||||
sponsor.logo.quote, sponsor.name.quote,
|
||||
sponsor.url.quote, $sponsor.amount.int,
|
||||
$sponsor.allTime.int, sponsor.since.format("MMM d, yyyy").quote,
|
||||
$sponsor.amount.getLevel
|
||||
]
|
||||
writeFile(filename, csv)
|
||||
echo("Written csv file to ", filename)
|
||||
|
||||
when isMainModule:
|
||||
if paramCount() == 0:
|
||||
quit("You need to specify the BountySource access token on the command\n" &
|
||||
"line, you can find it by going onto https://www.bountysource.com/people/25278-dom96\n" &
|
||||
"and looking at your browser's network inspector tab to see the token being\n" &
|
||||
"sent to api.bountysource.com")
|
||||
|
||||
let token = paramStr(1)
|
||||
let bountysource = newBountySource(team, token)
|
||||
|
||||
echo("Getting sponsors...")
|
||||
let supporters = waitFor bountysource.getSupporters()
|
||||
processSupporters(supporters)
|
||||
|
||||
echo("Generating sponsors list... (please be patient)")
|
||||
var activeSponsors: seq[Sponsor] = @[]
|
||||
var inactiveSponsors: seq[Sponsor] = @[]
|
||||
for supporter in supporters:
|
||||
let name = supporter["display_name"].getStr
|
||||
var url = ""
|
||||
let ghUser = waitFor getGithubUser(name)
|
||||
if not ghUser.isNil:
|
||||
if ghUser["blog"].kind != JNull:
|
||||
url = ghUser["blog"].getStr
|
||||
else:
|
||||
url = ghUser["html_url"].getStr
|
||||
|
||||
if url.len > 0 and not url.startsWith("http"):
|
||||
url = "http://" & url
|
||||
|
||||
let amount = supporter["monthly_amount"].getFNum()
|
||||
# Only show URL when user donated at least $5.
|
||||
if amount < 5:
|
||||
url = ""
|
||||
|
||||
#let supporter = getSupporter(supporters,
|
||||
# supportLevel["owner"]["display_name"].getStr)
|
||||
#if supporter.isNil: continue
|
||||
var logo = ""
|
||||
if amount >= 75:
|
||||
discard # TODO
|
||||
|
||||
let sponsor = Sponsor(name: name, url: url, logo: logo, amount: amount,
|
||||
allTime: supporter["alltime_amount"].getFNum(),
|
||||
since: parse(supporter["created_at"].getStr, "yyyy-MM-dd'T'hh:mm:ss")
|
||||
)
|
||||
if supporter["monthly_amount"].getFNum > 0.0:
|
||||
activeSponsors.add(sponsor)
|
||||
else:
|
||||
inactiveSponsors.add(sponsor)
|
||||
|
||||
echo("Generated ", activeSponsors.len, " active sponsors")
|
||||
echo("Generated ", inactiveSponsors.len, " inactive sponsors")
|
||||
writeCsv(activeSponsors)
|
||||
writeCsv(inactiveSponsors, "inactive_sponsors.new.csv")
|
||||
@@ -1 +0,0 @@
|
||||
-d:ssl
|
||||
Reference in New Issue
Block a user