1+ #r " packages/Hopac/lib/net45/Hopac.Core.dll"
2+ #r " packages/Hopac/lib/net45/Hopac.Platform.dll"
3+ #r " packages/Hopac/lib/net45/Hopac.dll"
4+ #r " packages/Hopac/lib/net45/Hopac.dll"
5+ #r " packages/FSharp.Data/lib/net45/FSharp.Data.dll"
6+ #r " packages/Http.fs/lib/net461/HttpFs.dll"
7+ #r " packages/System.Net.Http/lib/net46/System.Net.Http.dll"
8+
9+ open Hopac
10+ open FSharp.Data
11+ open HttpFs.Client
12+
13+ type UserTypeProvider = JsonProvider< " https://api.github.com/users/tamizhvendan" >
14+ type User = UserTypeProvider.Root
15+
16+ type ReposTypeProvider = JsonProvider< " https://api.github.com/users/tamizhvendan/repos" >
17+ type Repo = ReposTypeProvider.Root
18+
19+
20+ let httpGet url =
21+ Request.createUrl Get url
22+ |> Request.setHeader ( UserAgent " FsHopac" )
23+ |> getResponse
24+ |> Job.bind Response.readBodyAsString
25+
26+ let host = " https://api.github.com"
27+ let userUrl = sprintf " %s /users/%s " host
28+
29+ let getUser username : Job < User > =
30+ userUrl username
31+ |> httpGet
32+ |> Job.map UserTypeProvider.Parse
33+
34+ let userReposUrl = sprintf " %s /users/%s /repos" host
35+
36+ let topThreeUserRepos ( repos : Repo []) =
37+ let takeCount =
38+ let reposCount = Array.length repos
39+ if reposCount > 3 then 3 else reposCount
40+ repos
41+ |> Array.filter ( fun repo -> not repo.Fork)
42+ |> Array.sortByDescending ( fun repo -> repo.StargazersCount)
43+ |> Array.take takeCount
44+
45+ let getTopThreeUserRepos username : Job < Repo []> =
46+ userReposUrl username
47+ |> httpGet
48+ |> Job.map ReposTypeProvider.Parse
49+ |> Job.map topThreeUserRepos
50+
51+ let languagesUrl userName repoName =
52+ sprintf " %s /repos/%s /%s /languages" host userName repoName
53+
54+ let parseLanguagesJson languagesJson =
55+ languagesJson
56+ |> JsonValue.Parse
57+ |> JsonExtensions.Properties
58+ |> Array.map fst
59+
60+ let getUserRepoLanguages username repoName =
61+ languagesUrl username repoName
62+ |> httpGet
63+ |> Job.map parseLanguagesJson
64+
65+ type RepoDto = {
66+ Name : string
67+ StargazersCount : int
68+ Languages : string []
69+ }
70+
71+ type UserDto = {
72+ Name : string
73+ AvatarUrl : string
74+ TopThreeRepos : RepoDto []
75+ }
76+
77+ let repoDto ( repo : Repo ) languages = {
78+ Name = repo.Name
79+ StargazersCount = repo.StargazersCount
80+ Languages = languages
81+ }
82+
83+ open Hopac.Infixes
84+
85+ let getRepoDto username ( repo : Repo ) =
86+ getUserRepoLanguages username repo.Name
87+ |> Job.map ( repoDto repo)
88+
89+ let getUserDto username = job {
90+ let! user , repos =
91+ getUser username <*> getTopThreeUserRepos username
92+ let! repoDtos =
93+ repos
94+ |> Array.map ( getRepoDto username)
95+ |> Job.conCollect
96+ return {
97+ Name = user.Name
98+ AvatarUrl = user.AvatarUrl
99+ TopThreeRepos = repoDtos.ToArray()
100+ }
101+ }
0 commit comments