]> gitweb.factorcode.org Git - factor.git/blob - extra/twitter/twitter.factor
assocs: Add of and ?of. Change all the things at once! Fixes #701.
[factor.git] / extra / twitter / twitter.factor
1 ! Copyright (C) 2009, 2010 Joe Groff, Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs combinators hashtables http
4 http.client json.reader kernel macros make namespaces sequences
5 io.sockets.secure fry oauth urls ;
6 FROM: assocs => change-at ;
7 IN: twitter
8
9 ! Configuration
10 SYMBOLS: twitter-source twitter-consumer-token twitter-access-token ;
11
12 twitter-source [ "factor" ] initialize
13
14 <PRIVATE
15
16 : with-twitter-oauth ( quot -- )
17     [
18         twitter-consumer-token get consumer-token set
19         twitter-access-token get access-token set
20         call
21     ] with-scope ; inline
22
23 : twitter-url ( string -- string' )
24     ssl-supported?
25     "https://api.twitter.com/" "http://api.twitter.com/" ? prepend ;
26
27 PRIVATE>
28
29 : obtain-twitter-request-token ( -- request-token )
30     [
31         "oauth/request_token" twitter-url
32         <request-token-params>
33         obtain-request-token
34     ] with-twitter-oauth ;
35
36 : twitter-authorize-url ( token -- url )
37     "oauth/authorize" twitter-url >url
38         swap key>> "oauth_token" set-query-param ;
39
40 : obtain-twitter-access-token ( request-token verifier -- access-token )
41     [
42         [ "oauth/access_token" twitter-url ] 2dip
43         <access-token-params>
44             swap >>verifier
45             swap >>request-token
46         obtain-access-token
47     ] with-twitter-oauth ;
48
49 <PRIVATE
50
51 ! Utilities
52 MACRO: keys-boa ( keys class -- )
53     [ [ '[ _ of ] ] map ] dip '[ _ cleave _ boa ] ;
54
55 ! Twitter requests
56 : status-url ( string -- url )
57     "1.1/statuses/" ".json" surround twitter-url ;
58
59 : set-request-twitter-auth ( request -- request )
60     [ <oauth-request-params> set-oauth ] with-twitter-oauth ;
61
62 : twitter-request ( request -- data )
63     set-request-twitter-auth
64     http-request nip ; inline
65
66 PRIVATE>
67
68 ! Data types
69
70 TUPLE: twitter-status
71     created-at
72     id
73     text
74     source
75     truncated?
76     in-reply-to-status-id
77     in-reply-to-user-id
78     favorited?
79     user ;
80
81 TUPLE: twitter-user
82     id
83     name
84     screen-name
85     description
86     location
87     profile-image-url 
88     url
89     protected?
90     followers-count ;
91
92 <PRIVATE
93
94 : <twitter-user> ( assoc -- user )
95     {
96         "id"
97         "name"
98         "screen_name"
99         "description"
100         "location"
101         "profile_image_url"
102         "url"
103         "protected"
104         "followers_count"
105     } twitter-user keys-boa ;
106
107 : <twitter-status> ( assoc -- tweet )
108     clone "user" over [ <twitter-user> ] change-at 
109     {
110         "created_at"
111         "id"
112         "text"
113         "source"
114         "truncated"
115         "in_reply_to_status_id"
116         "in_reply_to_user_id"
117         "favorited"
118         "user"
119     } twitter-status keys-boa ;
120
121 : json>twitter-statuses ( json-array -- tweets )
122     json> [ <twitter-status> ] map ;
123
124 : json>twitter-status ( json-object -- tweet )
125     json> <twitter-status> ;
126
127 PRIVATE>
128
129 ! Updates
130 <PRIVATE
131
132 : update-post-data ( update -- assoc )
133     [
134         "status" ,,
135         twitter-source get "source" ,,
136     ] H{ } make ;
137
138 : (tweet) ( string -- json )
139     update-post-data "update" status-url
140     <post-request> twitter-request ;
141
142 PRIVATE>
143
144 : tweet* ( string -- tweet )
145     (tweet) json>twitter-status ;
146
147 : tweet ( string -- ) (tweet) drop ;
148
149 ! Timelines
150 <PRIVATE
151
152 : timeline ( url -- tweets )
153     status-url <get-request>
154     twitter-request json>twitter-statuses ;
155
156 PRIVATE>
157
158 : public-timeline ( -- tweets )
159     "public_timeline" timeline ;
160
161 : friends-timeline ( -- tweets )
162     "friends_timeline" timeline ;
163
164 : user-timeline ( username -- tweets )
165     "user_timeline/" prepend timeline ;