]> gitweb.factorcode.org Git - factor.git/blob - extra/hacker-news/hacker-news.factor
core: cramp -> bound (was short)
[factor.git] / extra / hacker-news / hacker-news.factor
1 ! Copyright (C) 2012 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3
4 USING: accessors assocs calendar calendar.format
5 calendar.holidays.us colors combinators concurrency.combinators
6 formatting hashtables http.client io io.styles json.reader
7 kernel make math sequences ui ui.theme urls ;
8
9 IN: hacker-news
10
11 CONSTANT: christmas-red COLOR: #bc2c21
12 CONSTANT: christmas-green COLOR: #376627
13
14 <PRIVATE
15 : hacker-news-ids ( endpoint -- ids )
16     "https://hacker-news.firebaseio.com/v0/%s.json?print=pretty" sprintf
17     http-get nip json> ;
18
19 : hacker-news-id>json-url ( n -- url )
20     "https://hacker-news.firebaseio.com/v0/item/%d.json?print=pretty" sprintf ;
21
22 : hacker-news-items ( n endpoint -- seq )
23     hacker-news-ids swap bound head
24     [ hacker-news-id>json-url http-get nip json> ] parallel-map ;
25
26 : hacker-news-top-stories ( n -- seq )
27     "topstories" hacker-news-items ;
28
29 : hacker-news-new-stories ( n -- seq )
30     "newstories" hacker-news-items ;
31
32 : hacker-news-best-stories ( n -- seq )
33     "beststories" hacker-news-items ;
34
35 : hacker-news-ask-stories ( n -- seq )
36     "askstories" hacker-news-items ;
37
38 : hacker-news-show-stories ( n -- seq )
39     "showstories" hacker-news-items ;
40
41 : hacker-news-job-stories ( n -- seq )
42     "jobstories" hacker-news-items ;
43
44 : christmas-day? ( -- ? )
45     now dup christmas-day same-day? ;
46
47 : number-color ( n -- color )
48     christmas-day? [
49         odd? christmas-red christmas-green ?
50     ] [
51         drop COLOR: #a0a0a0
52     ] if ;
53
54 : background-color ( -- color )
55     christmas-day? COLOR: #bc2c21 COLOR: #ff6600 ? ;
56
57 : write-number ( n -- )
58     [ "%2d. " sprintf H{ } clone ] keep
59     number-color foreground pick set-at format ;
60
61 : write-title ( title url -- )
62     '[
63         _ presented ,,
64         ui-running? text-color COLOR: white ? foreground ,,
65     ] H{ } make format ;
66
67 : write-link ( title url -- )
68     '[
69         _ presented ,,
70         COLOR: #888888 foreground ,,
71     ] H{ } make format ;
72
73 : write-text ( str -- )
74     text-color foreground associate format ;
75
76 : post>user-url ( post -- user-url )
77     "by" of "http://news.ycombinator.com/user?id=" prepend >url ;
78
79 : post>comments-url ( post -- user-url )
80     "id" of "http://news.ycombinator.com/item?id=%d" sprintf >url ;
81
82 ! Api is funky, gives id=0 and /comment/2342342 for self-post ads
83 : post>url ( post -- url )
84     dup "url" of "self" = [ post>comments-url ] [ "url" of >url ] if ;
85
86 PRIVATE>
87
88 : post. ( post index -- )
89     write-number
90     {
91         [ [ "title" of ] [ "url" of ] bi write-title ]
92         [ post>url host>> " (" ")" surround write-text nl ]
93         [ "score" of "    %d points" sprintf write-text ]
94         [ dup "by" of [ " by " write-text [ "by" of ] [ post>user-url ] bi write-link ] [ drop ] if ]
95         [ "time" of [ " " write-text unix-time>timestamp relative-time write-text ] when* ]
96         [
97             dup "descendants" of [
98                 " | " write-text
99                 [ "descendants" of [ "discuss" ] [ "%d comments" sprintf ] if-zero ]
100                 [ post>comments-url ] bi write-link
101             ] [
102                 drop
103             ] if nl nl
104         ]
105     } cleave ;
106
107 : banner. ( str -- )
108     "http://news.ycombinator.com" >url presented associate
109     H{
110         { font-size 20 }
111         { font-style bold }
112         { foreground COLOR: black }
113     } assoc-union
114     background-color background pick set-at
115     format nl ;
116
117 : hacker-news-feed. ( seq -- )
118     [ 1 + post. ] each-index ;
119
120 : hacker-news. ( str seq -- )
121     [ banner. ]
122     [ hacker-news-feed. ] bi* ;
123
124 : hacker-news-top. ( -- )
125     "Hacker News - Top"
126     30 hacker-news-top-stories
127     hacker-news. ;
128
129 : hacker-news-new. ( -- )
130     "Hacker News - New"
131     50 hacker-news-new-stories
132     hacker-news. ;
133
134 : hacker-news-best. ( -- )
135     "Hacker News - Best"
136     50 hacker-news-best-stories
137     hacker-news. ;
138
139 : hacker-news-ask. ( -- )
140     "Hacker News - Ask"
141     50 hacker-news-ask-stories
142     hacker-news. ;
143
144 : hacker-news-show. ( -- )
145     "Hacker News - Show"
146     50 hacker-news-show-stories
147     hacker-news. ;
148
149 : hacker-news-job. ( -- )
150     "Hacker News - Job"
151     50 hacker-news-job-stories
152     hacker-news. ;