Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 54 additions & 39 deletions src/pubg_clj/api.clj
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@
~@body))

(defn- api-url
"Constructs a valid PubG API URL given a platform, region, and endpoint. region
is optional. Query parameters are not included, and should be added by the
HTTP client mechanism."
[{:keys [platform region endpoint]}]
"Constructs a valid PubG API URL given a platform or platform-region,
and endpoint. region is optional. Query parameters are not included,
and should be added by the HTTP client mechanism."
[{:keys [platform-region endpoint]}]
(cond-> "https://api.pubg.com/"
(or platform region) (concat "shards/")
platform (concat platform)
region (concat "-" region)
endpoint (concat "/" endpoint)
platform-region (concat "shards/" platform-region)
endpoint (concat "/" endpoint)
true str/join))

(defn- parse-response-body
Expand All @@ -41,11 +39,12 @@
(update resp :body #(json/parse-string % ->kebab-case-keyword)))

(defn pubg-fetch
"Makes a request to the PubG API using the given api-key, platform,
region (optional), endpoint and query parameters (qparams). Platform, region
and endpoint are all used to construct the final URL, but this can be
overidden using the url key. Returns the response map."
[{:keys [api-key platform region endpoint qparams url] :as opts}]
"Makes a request to the PubG API using the given api-key, platform or
platform-region, endpoint and query parameters (qparams).
platform(-region) and endpoint are used to construct the final URL,
but this can be overidden using the url key. Returns the response
map."
[{:keys [api-key platform-region endpoint qparams url] :as opts}]
(let [api-key (or api-key *api-key*)
url (or url (api-url opts))
resp (http/get url
Expand All @@ -55,12 +54,13 @@
(parse-response-body resp)))

(defn pubg-fetch-async
"Asynchronously makes a request to the PubG API using the given api-key, platform,
region (optional), endpoint and query parameters (qparams). Platform, region
and endpoint are all used to construct the final URL, but this can be
overidden with the url key. Passes the response map to succ upon success, or
exception data to err upon failure."
[{:keys [api-key platform region endpoint qparams url] :as opts} succ err]
"Asynchronously makes a request to the PubG API using the given
api-key, platform or platform-region, endpoint and query
parameters (qparams). platform(-region) and endpoint are used to
construct the final URL, but this can be overidden with the url key.
Passes the response map to succ upon success, or exception data to
err upon failure."
[{:keys [api-key platform-region endpoint qparams url] :as opts} succ err]
(let [api-key (or api-key *api-key*)]
(let [url (or url (api-url opts))]
(http/get url {:accept "application/vnd.api+json"
Expand Down Expand Up @@ -91,6 +91,9 @@
(defn- season-stats-endpoint
[player-id season-id]
(str "players/" player-id "/seasons/" season-id))
(defn- season-ranked-stats-endpoint
[player-id season-id]
(str "players/" player-id "/seasons/" season-id "/ranked"))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Status
Expand All @@ -115,7 +118,7 @@
"Internal implementation of player fetching given a filter query parameter key,
platform, and player identifier(s) (name or ID). "
[filter-key platform pident]
(->> (pubg-fetch {:platform platform
(->> (pubg-fetch {:platform-region platform
:endpoint (player-endpoint)
:qparams {filter-key pident}})
:body
Expand Down Expand Up @@ -154,7 +157,7 @@
(defn fetch-match
"Retrieves a match by its ID on the given platform."
[platform match-id]
(->> (pubg-fetch {:platform platform
(->> (pubg-fetch {:platform-region platform
:endpoint (match-endpoint match-id)})
:body
p/match-parse))
Expand All @@ -170,7 +173,7 @@
(wrap-err [f]
(fn [e]
(f (merge e {::match-id match-id}))))]
(pubg-fetch-async {:platform platform
(pubg-fetch-async {:platform-region platform
:endpoint (match-endpoint match-id)}
(wrap-succ succ)
(wrap-err err))))
Expand All @@ -197,9 +200,8 @@

(defn fetch-match-samples
"Fetches n random matches for the given platform and region in parallel."
[n platform region]
(let [match-samples (->> (pubg-fetch {:platform platform
:region region
[n platform]
(let [match-samples (->> (pubg-fetch {:platform-region platform
:endpoint (match-samples-endpoint)})
:body :data :relationships :matches :data
(map :id))]
Expand All @@ -210,10 +212,10 @@
accepts an err callback that will be passed exception data for every match
that fails to load. Exception data will contain ::pubg/match-id for
reference."
[player & [err]]
(let [{:keys [pubg.player/matches pubg/shard-id]} player
match-ids (map :pubg.match/id matches)]
(batch-get-matches shard-id match-ids err)))
[player platform & [err]]
(let [{:keys [pubg.player/matches]} player
match-ids (map :pubg.match/id matches)]
(batch-get-matches platform match-ids err)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Telemetry
Expand All @@ -233,8 +235,8 @@
(defn fetch-leaderboard
"Retrieves the leaderboard for the given platform and game mode. Currently
leaderboards are only available on PC."
[platform game-mode]
(->> (pubg-fetch {:platform platform
[platform-region game-mode]
(->> (pubg-fetch {:platform-region platform-region
:endpoint (leaderboard-endpoint game-mode)})
:body
p/leaderboard-parse))
Expand All @@ -244,17 +246,17 @@

(defn fetch-seasons
"Fetches a list of available seasons for the given platform."
[platform]
(->> (pubg-fetch {:platform platform
[platform-region]
(->> (pubg-fetch {:platform-region platform-region
:endpoint (seasons-endpoint)})
:body
:data
(mapv p/season-parse)))

(defn fetch-current-season
"Fetches the season that is currently in progress for the given platform."
[platform]
(->> (fetch-seasons platform)
[platform-region]
(->> (fetch-seasons platform-region)
(filter :pubg.season/is-current?)
first))

Expand All @@ -264,10 +266,23 @@
division.bro.official.2018-09. It is probably best to always include the
region, as the API will respond with stats for EVERY region in the cases where
it is depracated."
[player season-id & [region]]
(let [{:keys [pubg.player/id pubg/shard-id]} player]
(->> (pubg-fetch {:platform shard-id
:region (or region "")
[platform-region player season-id]
(let [{:keys [pubg.player/id]} player]
(->> (pubg-fetch {:platform-region platform-region
:endpoint (season-stats-endpoint id season-id)})
:body
p/player-season-stats-parse)))

(defn fetch-player-season-ranked-stats
"Fetches the ranked season stats for a given player and season. The
region is required for PS4, Xbox, and for stats of PC players prior
to and including division.bro.official.2018-09. It is probably best
to always include the region, as the API will respond with stats for
EVERY region in the cases where it is depracated."
[platform-region player season-id]
(let [{:keys [pubg.player/id]} player]
(->> (pubg-fetch
{:platform-region platform-region,
:endpoint (season-ranked-stats-endpoint id season-id)})
:body
p/player-season-ranked-stats-parse)))
41 changes: 40 additions & 1 deletion src/pubg_clj/api/parsers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,39 @@
:pubg.season.stats/wins {:from [:wins]}
})

(defparser season-ranked-stats-parse
{:pubg/game-mode {:from [:game-mode]},
:pubg.season.stats/kills {:from [:kills]},
:pubg.season.stats/kill-streak {:from [:kill-streak]},
:pubg.season.stats/boosts {:from [:boosts]},
:pubg.season.stats/team-kills {:from [:team-kills]},
:pubg.season.stats/revives {:from [:revives]},
:pubg.season.stats/assists {:from [:assists]},
:pubg.season.stats/kdr {:from [:kdr]},
:pubg.season.stats/revive-ratio {:from [:revive-ratio]},
:pubg.season.stats/avg-rank {:from [:avg-rank]},
:pubg.season.stats/deaths {:from [:deaths]},
:pubg.season.stats/damage-dealt {:from [:damage-dealt]},
:pubg.season.stats/weapons-acquired {:from [:weapons-acquired]},
:pubg.season.stats/heals {:from [:heals]},
:pubg.season.stats/play-time {:from [:play-time]},
:pubg.season.stats/top-10-ratio {:from [:top-10-ratio]},
:pubg.season.stats/kda {:from [:kda]},
:pubg.season.stats/headshot-kill-ratio {:from [:headshot-kill-ratio]},
:pubg.season.stats/current-rank-point {:from [:current-rank-point]},
:pubg.season.stats/dbnos {:from [:d-bn-os]},
:pubg.season.stats/best-tier {:from [:best-tier :tier]},
:pubg.season.stats/avg-survival-time {:from [:avg-survival-time]},
:pubg.season.stats/round-most-kills {:from [:round-most-kills]},
:pubg.season.stats/headshot-kills {:from [:headshot-kills]},
:pubg.season.stats/current-tier {:from [:current-tier :tier]},
:pubg.season.stats/current-sub-tier {:from [:current-tier :sub-tier]},
:pubg.season.stats/best-rank-point {:from [:best-rank-point]},
:pubg.season.stats/longest-kill {:from [:longest-kill]},
:pubg.season.stats/wins {:from [:wins]},
:pubg.season.stats/win-ratio {:from [:win-ratio]},
:pubg.season.stats/rounds-played {:from [:rounds-played]}})

(defn- pack-game-mode-stats
[[game-mode-key stats-map]]
(assoc stats-map :game-mode (name game-mode-key)))
Expand All @@ -184,6 +217,13 @@
:using #(let [stats (map pack-game-mode-stats %)]
(mapv season-stats-parse stats))}})

(defparser
player-season-ranked-stats-parse
{:pubg.player/id {:from [:data :relationships :player :data :id]},
:pubg.player/season-ranked-stats {:from [:data :attributes :ranked-game-mode-stats]
:using #(let [stats (map pack-game-mode-stats %)]
(mapv season-ranked-stats-parse stats))}})

(defparser telemetry-common-parse
{:pubg.match.telemetry.common/is-game {:from [:is-game]}})

Expand Down Expand Up @@ -366,4 +406,3 @@
maybe-discard (fn [x]
(if (map? x) (discard-nil-vals x) x))]
(walk/postwalk maybe-discard evts))}})