├── .gitignore ├── www ├── images │ ├── Save.png │ ├── 1-ChatterCast-Index.png │ ├── 5-ChatterCast-Success.png │ └── ChatterCast-BackgroundGradient.png ├── index.php ├── include │ ├── header.php │ ├── config.template.php │ ├── footer.php │ ├── inc.php │ ├── GeoloqiAPI.php │ └── Twitter.php ├── oauth.php └── prefs.php └── scripts └── seattle-911.php /.gitignore: -------------------------------------------------------------------------------- 1 | www/include/config.php 2 | 3 | -------------------------------------------------------------------------------- /www/images/Save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaronpk/ChatterCast-Seattle/master/www/images/Save.png -------------------------------------------------------------------------------- /www/images/1-ChatterCast-Index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaronpk/ChatterCast-Seattle/master/www/images/1-ChatterCast-Index.png -------------------------------------------------------------------------------- /www/images/5-ChatterCast-Success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaronpk/ChatterCast-Seattle/master/www/images/5-ChatterCast-Success.png -------------------------------------------------------------------------------- /www/images/ChatterCast-BackgroundGradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaronpk/ChatterCast-Seattle/master/www/images/ChatterCast-BackgroundGradient.png -------------------------------------------------------------------------------- /www/index.php: -------------------------------------------------------------------------------- 1 | oauth(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET); 8 | echo '
'; 9 | 10 | include('footer.php'); 11 | 12 | ?> -------------------------------------------------------------------------------- /www/include/header.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /www/include/config.template.php: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /www/include/footer.php: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /www/include/inc.php: -------------------------------------------------------------------------------- 1 | '; 39 | print_r($a); 40 | echo ''; 41 | } 42 | 43 | $geoloqi = new GeoloqiAPI(GEOLOQI_API_KEY, GEOLOQI_API_SECRET); 44 | 45 | if(!array_key_exists('SHELL', $_SERVER)) 46 | session_start(); 47 | 48 | $db = new PDO(PDO_DSN, PDO_USER, PDO_PASS); 49 | 50 | 51 | ?> 52 | -------------------------------------------------------------------------------- /scripts/seattle-911.php: -------------------------------------------------------------------------------- 1 | data; 10 | 11 | foreach($rows as $row) 12 | { 13 | $row_time = $row[10]; 14 | 15 | // Ignore calls older than 2 hours ago (this shouldn't happen once the script starts running regularly) 16 | # if($row_time + 7200 < time()) 17 | # continue; 18 | 19 | $check = $db->prepare('SELECT COUNT(1) AS num FROM seattle_911 WHERE uuid = :u'); 20 | $check->bindParam(':u', $row[1]); 21 | $check->execute(); 22 | $check = $check->fetch(); 23 | if($check['num'] == 0) 24 | { 25 | $insert = $db->prepare('INSERT INTO seattle_911 (uuid, data) VALUES(:u, :d)'); 26 | $insert->bindParam(':u', $row[1]); 27 | $insert->bindParam(':d', json_encode($row)); 28 | $insert->execute(); 29 | 30 | //irc_debug('[ChatterCast] Found new 911 call: ' . $row[9] . ' at ' . $row[8]); 31 | 32 | $query = $db->prepare('SELECT * FROM users WHERE instamapper_key != ""'); 33 | $query->execute(); 34 | foreach($query as $user) 35 | { 36 | $_SESSION['geoloqi_token'] = $user['geoloqi_access']; 37 | $_SESSION['geoloqi_refresh_token'] = $user['geoloqi_refresh']; 38 | 39 | $message = 'ChatterCast: ' . $row[9] . ' at ' . $row[8] . ' ' . date('g:ia', $row_time); 40 | echo 'Setting a geonote for ' . $user['username'] . ': ' . $message . ' expiring at ' . date('c', $row_time + 7200) . "\n"; 41 | 42 | $response = $geoloqi->request('geonote/create', array( 43 | 'text' => $message, 44 | 'latitude' => $row[11], 45 | 'longitude' => $row[12], 46 | 'radius' => 400, 47 | 'date_to' => date('c', $row_time + 7200) 48 | )); 49 | print_r($response); 50 | } 51 | 52 | } 53 | 54 | } 55 | 56 | ?> 57 | -------------------------------------------------------------------------------- /www/oauth.php: -------------------------------------------------------------------------------- 1 | oauth(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET); 7 | $_SESSION['access_token'] = $token['access_token']; 8 | $_SESSION['access_token_secret'] = $token['access_token_secret']; 9 | 10 | #$connection->oauth(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, $token['access_token'], $token['access_token_secret']); 11 | 12 | $obj = $twitter->call('account/verify_credentials'); 13 | 14 | $_SESSION['username'] = $obj->screen_name; 15 | 16 | 17 | $query = $db->prepare('SELECT COUNT(1) AS num FROM users WHERE username = :username'); 18 | $query->bindParam(':username', $_SESSION['username'], PDO::PARAM_STR); 19 | $query->execute(); 20 | $row = $query->fetch(); 21 | 22 | if($row['num'] == 0) 23 | { 24 | // new user! insert a row 25 | $geoloqi_response = $geoloqi->request('user/create', array('username' => 'chattercast_' . $_SESSION['username'], 'email' => 'chattercast.' . $_SESSION['username'] . '@pin13.net')); 26 | 27 | $query = $db->prepare('INSERT INTO users (username, twitter_token, twitter_secret, date_created, geoloqi_access, geoloqi_refresh) VALUES(:u, :t, :s, :d, :ga, :gr)'); 28 | $query->bindParam(':u', $_SESSION['username'], PDO::PARAM_STR); 29 | $query->bindParam(':t', $_SESSION['access_token'], PDO::PARAM_STR); 30 | $query->bindParam(':s', $_SESSION['access_token_secret'], PDO::PARAM_STR); 31 | $query->bindParam(':d', date('Y-m-d H:i:s'), PDO::PARAM_STR); 32 | $query->bindParam(':ga', $geoloqi_response->access_token, PDO::PARAM_STR); 33 | $query->bindParam(':gr', $geoloqi_response->refresh_token, PDO::PARAM_STR); 34 | $query->execute(); 35 | 36 | irc('New ChatterCast user! ' . $_SESSION['username']); 37 | } 38 | else 39 | { 40 | $user = $db->prepare('SELECT * FROM users WHERE username = :username'); 41 | $user->bindParam(':username', $_SESSION['username']); 42 | $user->execute(); 43 | $user = $user->fetch(); 44 | irc('ChatterCast user ' . $_SESSION['username'] . ' logged back in'); 45 | $_SESSION['geoloqi_token'] = $user['geoloqi_access']; 46 | } 47 | 48 | header('Location: /prefs.php'); 49 | 50 | ?> -------------------------------------------------------------------------------- /www/prefs.php: -------------------------------------------------------------------------------- 1 | prepare('SELECT * FROM users WHERE username = :username'); 9 | $query->bindParam(':username', $_SESSION['username'], PDO::PARAM_STR); 10 | $query->execute(); 11 | $user = $query->fetch(); 12 | 13 | if(strtolower($_SERVER['REQUEST_METHOD']) == 'get') 14 | { 15 | ?> 16 |
';
30 |
31 | $ch = curl_init();
32 |
33 | $httpHeader = array();
34 |
35 | // TODO: Change this timezone to the logged-in user's timezone
36 | $httpHeader[] = 'Timezone: ' . date('c') . ';;America/Los_Angeles';
37 |
38 | if(substr($method, 0, 5) == 'oauth' || substr($method, 0, 4) == 'user')
39 | {
40 | $client = array('client_id' => $this->_clientID, 'client_secret' => $this->_clientSecret);
41 | curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
42 | curl_setopt($ch, CURLOPT_USERPWD, implode(':', $client));
43 | $baseURL = $this->_baseURL;
44 | }
45 | else
46 | {
47 | // Pass the OAuth token in the HTTP headers
48 | $httpHeader[] = 'Authorization: OAuth ' . $_SESSION['geoloqi_token'];
49 |
50 | $baseURL = $this->_baseURLSecure;
51 | }
52 |
53 | curl_setopt($ch, CURLOPT_URL, $baseURL . $method);
54 |
55 | if(is_array($post))
56 | {
57 | $post = http_build_query($post, '', '&');
58 | curl_setopt($ch, CURLOPT_POST, TRUE);
59 | curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
60 | }
61 | elseif(is_string($post))
62 | {
63 | $httpHeader[] = 'Content-Type: application/json';
64 | curl_setopt($ch, CURLOPT_POST, TRUE);
65 | curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
66 | }
67 |
68 | curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);
69 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
70 | curl_setopt($ch, CURLOPT_HEADER, TRUE);
71 | curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
72 |
73 | $response = curl_exec($ch);
74 |
75 | echo '';
76 | echo "REQUEST HEADERS:\n";
77 | echo trim(curl_getinfo($ch, CURLINFO_HEADER_OUT)) . "\n\n";
78 | if($post)
79 | {
80 | echo "REQUEST BODY:\n";
81 | echo (is_array($post) ? http_build_query($post) : $post) . "\n\n";
82 | }
83 | echo '';
84 |
85 | echo "RESPONSE HEADERS:\n";
86 | echo $response . "\n\n";
87 |
88 | $headers = array();
89 | $lines = explode("\n", $response);
90 | $endHeaders = FALSE;
91 | while($endHeaders == FALSE && count($lines) > 0)
92 | {
93 | $line = array_shift($lines);
94 | if(substr($line, 0, 1) == '{' || substr($line, 0, 1) == '[')
95 | {
96 | $endHeaders = TRUE;
97 | array_unshift($lines, $line);
98 | }
99 | else
100 | {
101 | $line = explode(': ', $line);
102 | if(count($line) == 2)
103 | {
104 | list($k, $v) = $line;
105 | $headers[trim($k)] = trim($v);
106 | }
107 | }
108 | }
109 |
110 | $body = implode("\n", $lines);
111 |
112 | $data = json_decode($body);
113 |
114 | echo "JSON RESPONSE:\n";
115 |
116 | if(is_object($data) && property_exists($data, 'debug_output'))
117 | {
118 | echo '' . $data->debug_output . '
';
119 | unset($data->debug_output);
120 | }
121 | pa($data);
122 |
123 | if(array_key_exists('WWW-Authenticate', $headers) && preg_match('/error=\'expired_token\'/', $headers['WWW-Authenticate']))
124 | {
125 | // If the token expired, use the refresh token to get a new access token
126 | $response = $this->request('oauth/token', array(
127 | 'grant_type' => 'refresh_token',
128 | 'refresh_token' => $_SESSION['geoloqi_refresh_token']
129 | ));
130 |
131 | // Store the tokens in the session
132 | $_SESSION['geoloqi_token'] = $response->access_token;
133 | $_SESSION['geoloqi_refresh_token'] = $response->refresh_token;
134 |
135 | echo "SESSION\n";
136 | pa($_SESSION);
137 |
138 | // Try the original request again
139 | // return $this->request($method, $post);
140 | die('ERROR');
141 | return FALSE;
142 | }
143 |
144 | echo "\n";
145 |
146 | echo '';
147 | $this->log(ob_get_clean());
148 |
149 | return $data;
150 | }
151 |
152 | protected function log($msg)
153 | {
154 | static $fp = FALSE;
155 | if($fp == FALSE)
156 | $fp = fopen('api-log.htm', 'w');
157 | fwrite($fp, $msg . "\n");
158 | }
159 | }
160 | ?>
--------------------------------------------------------------------------------
/www/include/Twitter.php:
--------------------------------------------------------------------------------
1 | array('http' => 'get', 'auth' => FALSE),
17 | 'statuses/friends_timeline' => array('http' => 'get', 'auth' => TRUE),
18 | 'statuses/user_timeline' => array('http' => 'get', 'auth' => FALSE),
19 | 'statuses/mentions' => array('http' => 'get', 'auth' => TRUE),
20 | 'statuses/show' => array('http' => 'get', 'auth' => FALSE),
21 | 'statuses/update' => array('http' => 'post', 'auth' => TRUE),
22 | 'statuses/destroy' => array('http' => 'post', 'auth' => TRUE),
23 | 'users/show' => array('http' => 'get', 'auth' => FALSE),
24 | 'statuses/friends' => array('http' => 'get', 'auth' => FALSE),
25 | 'statuses/followers' => array('http' => 'get', 'auth' => TRUE),
26 | 'direct_messages' => array('http' => 'get', 'auth' => TRUE),
27 | 'direct_messages/sent' => array('http' => 'get', 'auth' => TRUE),
28 | 'direct_messages/new' => array('http' => 'post', 'auth' => TRUE),
29 | 'direct_messages/destroy' => array('http' => 'post', 'auth' => TRUE),
30 | 'friendships/create' => array('http' => 'post', 'auth' => TRUE),
31 | 'friendships/destroy' => array('http' => 'post', 'auth' => TRUE),
32 | 'friendships/exists' => array('http' => 'get', 'auth' => TRUE),
33 | 'account/verify_credentials' => array('http' => 'get', 'auth' => TRUE),
34 | 'account/rate_limit_status' => array('http' => 'get', 'auth' => FALSE),
35 | 'account/end_session' => array('http' => 'post', 'auth' => TRUE),
36 | 'account/update_delivery_device'=> array('http' => 'post', 'auth' => TRUE),
37 | 'account/update_profile_colors' => array('http' => 'post', 'auth' => TRUE),
38 | 'account/update_profile' => array('http' => 'post', 'auth' => TRUE),
39 | 'favorites' => array('http' => 'get', 'auth' => TRUE),
40 | 'favorites/create' => array('http' => 'post', 'auth' => TRUE),
41 | 'notifications/follow' => array('http' => 'post', 'auth' => TRUE),
42 | 'notifications/leave' => array('http' => 'post', 'auth' => TRUE),
43 | 'blocks/create' => array('http' => 'post', 'auth' => TRUE),
44 | 'blocks/destroy' => array('http' => 'post', 'auth' => TRUE),
45 | 'help/test' => array('http' => 'get', 'auth' => FALSE)
46 |
47 | //'account/update_profile_image' => array('http' => 'post', 'auth' => TRUE),
48 | //'account/account/update_profile_background_image' => array('http' => 'post', 'auth' => TRUE),
49 |
50 | );
51 |
52 | private $_conn;
53 | public $oauth;
54 |
55 | function __construct()
56 | {
57 | $this->_conn = new Twitter_Connection();
58 | }
59 |
60 | public function auth($username, $password)
61 | {
62 | $this->deauth();
63 | $this->_conn->auth($username, $password);
64 | }
65 |
66 | public function oauth($consumer_key, $consumer_secret, $access_token = NULL, $access_token_secret = NULL)
67 | {
68 | $this->deauth();
69 | $this->oauth = new EpiTwitter($consumer_key, $consumer_secret, $access_token, $access_token_secret);
70 | $this->oauth->setToken($access_token, $access_token_secret);
71 |
72 | if ( $access_token === NULL && $access_token_secret === NULL && !isset($_GET['oauth_token']) )
73 | {
74 | // Authenticate URL will seamlessly send the user back if the app is already approved
75 | //$url = $this->oauth->getAuthenticateUrl();
76 | // Authorize URL makes the user approve the app every time
77 | $url = $this->oauth->getAuthorizeUrl();
78 |
79 | return $url;
80 | }
81 | elseif ( $access_token === NULL && $access_token_secret === NULL && isset($_GET['oauth_token']) )
82 | {
83 | $access_token = $_GET['oauth_token'];
84 | $this->oauth->setToken($access_token);
85 |
86 | $info = $this->oauth->getAccessToken();
87 |
88 | if($info->oauth_token && $info->oauth_token_secret)
89 | {
90 | $response = array(
91 | 'access_token' => $info->oauth_token,
92 | 'access_token_secret' => $info->oauth_token_secret
93 | );
94 | $this->oauth->setToken($response['access_token'], $response['access_token_secret']);
95 |
96 | return $response;
97 | }
98 | }
99 |
100 | return TRUE;
101 | }
102 |
103 | public function deauth()
104 | {
105 | $this->oauth = NULL;
106 | $this->_conn->deauth();
107 | }
108 |
109 | public function search($method, $params = array())
110 | {
111 | $url = $this->_url_api_search.$method.'.'.$this->_api_format;
112 |
113 | return $this->_conn->get($url, $params);
114 | }
115 |
116 | public function call($method, $params = array())
117 | {
118 | // Firstly, assume we are using a GET non-authenticated call.
119 |
120 | $http = 'get';
121 | $auth = FALSE;
122 |
123 | // Now we get our http and auth options from the methods array.
124 |
125 | if ( isset($this->_methods[$method]) )
126 | {
127 | $http = $this->_methods[$method]['http'];
128 | $auth = $this->_methods[$method]['auth'];
129 | }
130 |
131 | if ( $auth === TRUE && ( $this->_conn->authed() || $this->oauth === NULL) )
132 | {
133 | // method requires auth, and we have not authed yet.
134 | return NULL;
135 | }
136 |
137 | if ( $this->oauth !== NULL )
138 | {
139 | $parts = explode('/', $method);
140 |
141 | if ( count($parts) > 1 )
142 | {
143 | $method_string = $http.'_'.$parts[0].ucfirst($parts[1]);
144 | }
145 | else
146 | {
147 | $method_string = $http.'_'.$parts[0];
148 | }
149 |
150 | $data = $this->oauth->$method_string($params);
151 | return $data;
152 | }
153 |
154 | $url = $this->_url_api . $method . '.' .$this->_api_format;
155 |
156 | return $this->_conn->$http($url, $params);
157 | }
158 | }
159 |
160 | class Twitter_Connection {
161 |
162 | private $_curl = NULL;
163 | private $_auth_method = NULL;
164 | private $_auth_user = NULL;
165 | private $_auth_pass = NULL;
166 |
167 | function __construct()
168 | {
169 | }
170 |
171 | private function _init()
172 | {
173 | $this->_curl = curl_init();
174 |
175 | curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, TRUE);
176 |
177 | if ( $this->_auth_method == 'basic' )
178 | {
179 | curl_setopt($this->_curl, CURLOPT_USERPWD, "$this->_auth_user:$this->_auth_pass");
180 | }
181 | }
182 |
183 | public function authed()
184 | {
185 | if ( $this->_auth_method === NULL ) return FALSE;
186 |
187 | return TRUE;
188 | }
189 |
190 | public function auth($username, $password)
191 | {
192 | $this->deauth();
193 |
194 | $this->_auth_method = 'basic';
195 | $this->_auth_user = $username;
196 | $this->_auth_pass = $password;
197 | }
198 |
199 | public function deauth($auth_method = NULL)
200 | {
201 | if ( $auth_method == 'basic' || NULL )
202 | {
203 | $this->_auth_user = NULL;
204 | $this->_auth_pass = NULL;
205 | }
206 |
207 | $this->_auth_method = NULL;
208 | }
209 |
210 | public function get($url, $params = array())
211 | {
212 | $this->_init();
213 |
214 | if ( is_array($params) && !empty($params) )
215 | {
216 | $url = $url . '?' . $this->_params_to_query($params);
217 | }
218 |
219 | curl_setopt($this->_curl, CURLOPT_URL, $url);
220 |
221 | return $this->deserialize(curl_exec($this->_curl));
222 | }
223 |
224 | public function post($url, $params = array())
225 | {
226 | $this->_init();
227 |
228 | if ( is_array($params) && !empty($params) )
229 | {
230 | curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $this->_params_to_query($params));
231 | }
232 |
233 | curl_setopt($this->_curl, CURLOPT_POST, TRUE);
234 | curl_setopt($this->_curl, CURLOPT_URL, $url);
235 |
236 | return $this->deserialize(curl_exec($this->_curl));
237 | }
238 |
239 | private function _params_to_query($params)
240 | {
241 | if ( !is_array($params) || empty($params) )
242 | {
243 | return '';
244 | }
245 |
246 | $query = '';
247 |
248 | foreach ( $params as $key => $value )
249 | {
250 | $query .= $key . '=' . $value . '&';
251 | }
252 |
253 | return substr($query, 0, strlen($query) - 1);;
254 | }
255 |
256 | private function deserialize($result)
257 | {
258 | return json_decode($result);
259 | }
260 | }
261 |
262 | ?>
--------------------------------------------------------------------------------