-
Notifications
You must be signed in to change notification settings - Fork 0
/
github_search.clj
77 lines (67 loc) · 2.41 KB
/
github_search.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
(ns eamonnsullivan.github-search
(:require [clojure.string :as string]
[clj-http.client :as client]
[clojure.data.json :as json]))
(def ^:dynamic *default-page-size* 25)
(def github-url "https://api.github.com/graphql")
(defn request-opts
[access-token]
{:ssl? true :headers {"Authorization" (str "bearer " access-token)}})
(def repo-query "query($first:Int!, $after: String, $query: String!) {
search(type:REPOSITORY, query:$query, first: $first, after: $after) {
repositoryCount
nodes {
... on Repository {
name
description
url
sshUrl
updatedAt
languages(first: 2 orderBy:{field: SIZE, direction:DESC}) {
nodes {
name
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}")
(defn http-post
[url payload opts]
(client/post url (merge {:content-type :json :body payload} opts)))
(defn get-query
[org topics]
(string/trim (str "org:" org " " (string/join " " (doall (map #(str "topic:" %) topics))))))
(defn fix-languages
[result]
(map (fn [repo] (merge repo {:languages (into [] (map #(str (% :name)) (-> repo :languages :nodes)))})) result))
(defn get-nodes
[page]
(fix-languages (-> page :data :search :nodes)))
(defn get-page-of-repos
[access-token org topics page-size cursor]
(let [variables {:first page-size :query (get-query org topics) :after cursor}
payload (json/write-str {:query repo-query :variables variables})
response (http-post github-url payload (request-opts access-token))]
(json/read-str (response :body) :key-fn keyword)))
(defn get-all-pages
[access-token org topics page-size]
(let [page (get-page-of-repos access-token org topics page-size nil)]
(loop [page page
result []]
(let [pageInfo (-> page :data :search :pageInfo)
has-next (pageInfo :hasNextPage)
cursor (pageInfo :endCursor)
result (concat result (get-nodes page))]
(if-not has-next
(into [] result)
(recur (get-page-of-repos access-token org topics page-size cursor)
(get-nodes page)))))))
(defn get-repos
"Get information about repos in a given organisation, with the specified topics"
([access-token org topics] (get-all-pages access-token org topics *default-page-size*))
([access-token org topics page-size] (get-all-pages access-token org topics page-size)))