function flickr_faves_add_fave(&$viewer, &$photo, $date_faved = 0) { if (!$date_faved) { $date_faved = time(); } $cluster_id = $viewer['cluster_id']; $fave = array('user_id' => $viewer['id'], 'photo_id' => $photo['id'], 'owner_id' => $photo['user_id'], 'date_faved' => $date_faved); $insert = array(); foreach ($fave as $k => $v) { $insert[$k] = AddSlashes($v); } $rsp = db_insert_users($cluster_id, 'FlickrFaves', $insert); if (!$rsp['ok'] && $rsp['error_code'] != 1062) { return $rsp; } # now update the photo owner side of things $owner = users_get_by_id($photo['user_id']); $cluster_id = $owner['cluster_id']; $fave = array('user_id' => $owner['id'], 'photo_id' => $photo['id'], 'viewer_id' => $viewer['id']); $insert = array(); foreach ($fave as $k => $v) { $insert[$k] = AddSlashes($v); } $rsp = db_insert_users($cluster_id, 'FlickrFavesUsers', $insert); if (!$rsp['ok'] && $rsp['error_code'] != 1062) { return $rsp; } # TO DO: index/update the photo in solr and insert $viewer['id'] # into the faved_by column (20111123/straup) return okay(); }
function privatesquare_export_geojson($fh, $checkins, $more = array()) { $features = array(); $swlat = null; $swlon = null; $nelat = null; $nelon = null; foreach ($checkins as $row) { # See notes in privatesquare_export_csv for why we're # doing this explicitly (20120227/straup) $more = array('inflate_weather' => 1); privatesquare_export_massage_checkin($row, $more); $lat = floatval($row['latitude']); $lon = floatval($row['longitude']); $swlat = isset($swlat) ? min($swlat, $lat) : $lat; $swlon = isset($swlon) ? min($swlon, $lon) : $lon; $nelat = isset($nelat) ? max($nelat, $lat) : $lat; $nelon = isset($nelon) ? max($nelon, $lon) : $lon; $features[] = array('type' => 'Feature', 'id' => $row['id'], 'properties' => $row, 'geometry' => array('type' => 'Point', 'coordinates' => array($lon, $lat))); } $geojson = array('type' => 'FeatureCollection', 'bbox' => array($swlon, $swlat, $nelon, $nelat), 'features' => $features); fwrite($fh, json_encode($geojson)); if (isset($more['donot_send'])) { return okay(); } $map = privatesquare_export_valid_formats(); $headers = array('Content-type' => $map['geojson']); privatesquare_export_send($fh, $headers, $more); }
function flickr_photos_exif_read(&$photo) { $map = flickr_photos_media_map(); if ($map[$photo['media']] == 'video') { return not_okay("video does not contain EXIF data"); } $fname = "{$photo['id']}_{$photo['originalsecret']}_o.{$photo['originalformat']}"; $froot = $GLOBALS['cfg']['flickr_static_path'] . flickr_photos_id_to_path($photo['id']); $path = "{$froot}/{$fname}"; if (!preg_match("/\\.jpe?g\$/i", $path)) { return not_okay("not a JPEG photo"); } if (!file_exists($path)) { return not_okay("original photo not found"); } if (!filesize($path)) { return not_okay("original photo is empty"); } # TO DO: cache me? $exif = exif_read_data($path); if (!$exif) { return not_okay("failed to read EXIF data"); } # TO DO: expand EXIF tag values $to_simplejoin = array('SubjectLocation', 'GPSLatitude', 'GPSLongitude', 'GPSTimeStamp'); foreach ($to_simplejoin as $tag) { if (is_array($exif[$tag])) { $exif[$tag] = implode(",", $exif[$tag]); } } # TO DO: work out how/where individual EXIF tags get # "prettified" ... ksort($exif); return okay(array("rows" => $exif)); }
function weather_google_conditions($lat, $lon) { $enc_lat = geo_utils_prepare_coordinate($lat); $enc_lon = geo_utils_prepare_coordinate($lon); $query = array('weather' => ",,,{$enc_lat},{$enc_lon}"); $url = $GLOBALS['weather_google_endpoint'] . "?" . http_build_query($query); $rsp = http_get($url); if (!$rsp['ok']) { return $rsp; } libxml_use_internal_errors(true); $doc = new DOMDocument(); $doc->loadXML($rsp['body']); $xpath = new DOMXpath($doc); $cond = $xpath->query("*/current_conditions"); $current = array(); foreach ($cond as $c) { foreach ($c->childNodes as $node) { $k = $node->nodeName; $v = $node->getAttribute("data"); if ($k == 'icon') { continue; } $current[$k] = $v; } break; } if (!count($current)) { return not_okay("failed to parse conditions"); } $rsp = array('latitude' => $lat, 'longitude' => $lon, 'timestamp' => time(), 'source' => 'google', 'conditions' => $current); return okay($rsp); }
function api_spec_utils_example_for_method($method) { $path = FLAMEWORK_INCLUDE_DIR . "config.api.examples/{$method}.json"; if (!file_exists($path)) { return not_okay("no example defined for {$method} method"); } return okay(array('example' => file_get_contents($path))); }
function flickr_geobookmarks_import_for_nsid($nsid, $more = array()) { $flickr_user = flickr_users_get_by_nsid($nsid); $user = users_get_by_id($flickr_user['user_id']); if (!$user) { return not_okay("Not a valid user"); } $flickr_user = flickr_users_get_by_user_id($user['id']); $method = 'flickr.people.geoBookmarks.getList'; $args = array('auth_token' => $flickr_user['auth_token']); $rsp = flickr_api_call($method, $args); if (!$rsp['ok']) { return $rsp; } if (!$rsp['rsp']['bookmarks']['count']) { return okay(); } $bookmarks = array(); # mark everything as private for now since none of that stuff # got turned on before I left, sad face... (20120217/straup) $geo_perms = flickr_geo_permissions_map("string keys"); $geo_private = $geo_perms['private']; foreach ($rsp['rsp']['bookmarks']['bookmark'] as $bm) { $bm['user_id'] = $user['id']; $bm['name'] = $bm['label']; $bm['geocontext'] = $bm['context']; $bm['geoperms'] = $geo_private; $bm['woeid'] = 0; unset($bm['label']); unset($bm['pretty_name']); unset($bm['context']); $geo_method = 'flickr.places.findByLatLon'; $geo_args = array('lat' => $bm['latitude'], 'lon' => $bm['longitude'], 'accuracy' => $bm['accuracy']); $geo_rsp = flickr_api_call($geo_method, $geo_args); if ($geo_rsp['ok']) { # I still miss xpath... $bm['woeid'] = $geo_rsp['rsp']['places']['place'][0]['woeid']; } $bookmarks[] = $bm; } $rsp = flickr_geobookmarks_purge_for_user($user); if (!$rsp['ok']) { return $rsp; } $count = 0; foreach ($bookmarks as $bm) { $rsp = flickr_geobookmarks_add($bm); $count += $rsp['ok']; } return okay(array('count_imported' => $count)); }
function foursquare_api_get_auth_token($code) { $callback = $GLOBALS['cfg']['abs_root_url'] . $GLOBALS['cfg']['foursquare_oauth_callback']; $args = array('client_id' => $GLOBALS['cfg']['foursquare_oauth_key'], 'client_secret' => $GLOBALS['cfg']['foursquare_oauth_secret'], 'grant_type' => 'authorization_code', 'redirect_uri' => $callback, 'code' => $code); $query = http_build_query($args); $url = "{$GLOBALS['foursquare_oauth_endpoint']}access_token?{$query}"; $rsp = http_get($url); if (!$rsp['ok']) { return $rsp; } $data = json_decode($rsp['body'], 'as hash'); if (!$data || !$data['access_token']) { return not_okay("failed to parse response"); } return okay(array('oauth_token' => $data['access_token'])); }
function flickr_photos_metadata_fetch(&$photo, $inflate = 0) { loadlib("flickr_api"); loadlib("flickr_users"); $flickr_user = flickr_users_get_by_user_id($photo['user_id']); $method = 'flickr.photos.getInfo'; $args = array('photo_id' => $photo['id'], 'auth_token' => $flickr_user['auth_token']); $more = array(); if (!$inflate) { $more['raw'] = 1; } $rsp = flickr_api_call($method, $args, $more); if ($rsp['ok']) { $data = $inflate ? $rsp['rsp'] : $rsp['body']; $rsp = okay(array('data' => $data)); } return $rsp; }
function _reverse_geoplanet_remote($lat, $lon, $remote_endpoint) { $cache_key = _reverse_geoplanet_cache_key($lat, $lon); $cache = cache_get($cache_key); if ($cache['ok']) { return okay($cache); } # $query = http_build_query(array('lat' => $lat, 'lon' => $lon)); $url = "{$remote_endpoint}?{$query}"; $rsp = http_get($url); if (!$rsp['ok']) { return $rsp; } $data = json_decode($rsp['body'], 'as hash'); if (!$data) { return not_okay("failed to parse response"); } # cache_set($cache_key, $data, "cache locally"); return okay(array('data' => $data, 'source' => $remote_endpoint)); }
function flickr_photos_places_contexts_for_user_and_place(&$user, &$place, $more = array()) { $defaults = array('viewer_id' => 0); $more = array_merge($defaults, $more); $more['enforce_geoperms'] = 1; if (!flickr_places_is_valid_placetype($place['place_type'])) { return not_okay("not a valid placetype"); } $query = array("user_id" => $user['id'], $place['place_type'] => $place['woeid']); $map = flickr_photos_geo_context_map(); $contexts = array(); foreach ($map as $ctx => $ignore) { $contexts[$ctx] = 0; } $rsp = flickr_photos_search_facet($query, 'geocontext', $more); if (!$rsp['ok']) { return $rsp; } foreach ($rsp['facets'] as $ctx => $count) { $contexts[$ctx] = $count; } return okay(array('contexts' => $contexts)); }
function privatesquare_export_csv($fh, $checkins, $more = array()) { # TO DO: this works fine until we want to "explode" specific # fields (like 'weather') because we need to find all the distinct # keys that might be used (across both fields and potential # providers: google weather versus some other api). This is # either a head scratch or a pain in the ass or both... # (2012027/straup) $header = 0; foreach ($checkins as $row) { privatesquare_export_massage_checkin($row); if (!$header) { fputcsv($fh, array_keys($row)); $header = 1; } fputcsv($fh, array_values($row)); } if (isset($more['donot_send'])) { return okay(); } $map = privatesquare_export_valid_formats(); $headers = array('Content-type' => $map['csv']); privatesquare_export_send($fh, $headers, $more); }
function flickr_photos_import_get_recent($nsid, $more = array()) { $flickr_user = flickr_users_get_by_nsid($nsid); $user = users_get_by_id($flickr_user['user_id']); if (!$user) { return array('ok' => 0, 'error' => 'not a valid user'); } $method = 'flickr.photos.recentlyUpdated'; if (!isset($more['min_date'])) { $offset_days = 1; $offset = intval(60 * 60 * 24 * $offset_days); $min_date = time() - $offset; } else { $min_date = intval($more['min_date']); } $args = array('auth_token' => $flickr_user['auth_token'], 'min_date' => $min_date, 'extras' => 'original_format,tags,media,date_upload,date_taken,geo', 'per_page' => 100, 'page' => 1); $pages = null; $imported = 0; # TO DO: capture dateupdate for each photo and return that # if there's a fatal error so that the FlickrBackups database # can be set with something other than 0 (20111206/straup) while (!isset($pages) || $pages >= $args['page']) { # because the Flickr API has an annoying habit of # timing out and this causes an initial import of # photos to fail and be repeated in-toto over and # over again (20111206/straup) $tries = 1; $max_tries = 5; $ok = 0; while (!$ok && $tries < $max_tries) { $rsp = flickr_api_call($method, $args); $ok = $rsp['ok']; $tries++; if ($ok) { $photos = $rsp['rsp']['photos']['photo']; if (!is_array($photos)) { $rsp = not_okay("no photos"); $ok = 0; } } } if (!$ok) { return $rsp; } if (!isset($pages)) { $pages = $rsp['rsp']['photos']['pages']; } # TO DO: date update stuff (see above) foreach ($photos as $photo) { flickr_photos_import_photo($photo, $more); $imported++; } $args['page'] += 1; } return okay(array('count_imported' => $imported)); }
function flickr_backups_toggle_push_subscription(&$backup, $enable) { $push_features = array("flickr_push", "flickr_push_backups"); if (!features_is_enabled($push_features)) { return null; } # First, figure out if this backup type is a valid push # backup topic - this duplicates most/all of the code in # flickr_backups_is_push_backups but since we'll need the # stub subscription (and the topic map) in order to create # new subscriptions we're just not going to worry about it # too much (20120608/straup) $type_id = $backup['type_id']; $map = flickr_backups_push_topics_map(); if (!isset($map[$type_id])) { return null; } # Stub subscription data $user = users_get_by_id($backup['user_id']); $topic_id = $map[$type_id]; $sub = array('user_id' => $user['id'], 'topic_id' => $topic_id); if (!flickr_backups_is_registered_push_subscription($sub)) { return null; } if ($enable) { $push_rsp = flickr_push_subscriptions_register_subscription($sub); } else { # Okay, now fetch the actual subscription in order to unsubscribe $sub = flickr_push_subscriptions_get_by_user_and_topic($user, $topic_id); # Keeping in mind that it may not actually exist... if (!$sub) { return okay(); } $push_rsp = flickr_push_subscriptions_remove_subscription($sub, 1); } return $push_rsp; }
function privatesquare_checkins_for_user_nearby(&$user, $lat, $lon, $more = array()) { loadlib("geo_utils"); $dist = isset($more['dist']) ? floatval($more['dist']) : 0.2; $unit = geo_utils_is_valid_unit($more['unit']) ? $more['unit'] : 'm'; # TO DO: sanity check to ensure max $dist $bbox = geo_utils_bbox_from_point($lat, $lon, $dist, $unit); $cluster_id = $user['cluster_id']; $enc_user = AddSlashes($user['id']); # TO DO: group by venue_id in memory since the following will always # result in a filesort (20120301/straup) $sql = "SELECT venue_id, COUNT(id) AS count FROM PrivatesquareCheckins WHERE user_id='{$enc_user}'"; $sql .= " AND latitude BETWEEN {$bbox[0]} AND {$bbox[2]} AND longitude BETWEEN {$bbox[1]} AND {$bbox[3]}"; $sql .= " GROUP BY venue_id"; $rsp = db_fetch_users($cluster_id, $sql, $more); if (!$rsp['ok']) { return $rsp; } $tmp = array(); foreach ($rsp['rows'] as $row) { $tmp[$row['venue_id']] = $row['count']; } arsort($tmp); $venues = array(); foreach ($tmp as $venue_id => $count) { $venue = foursquare_venues_get_by_venue_id($venue_id); $venue['count_checkins'] = $count; $venues[] = $venue; } return okay(array('rows' => $venues)); }
function flickr_photos_get_bookends_for_user(&$user, $more = array()) { $defaults = array('viewer_id' => 0, 'context' => 'datetaken'); $more = array_merge($defaults, $more); if (!in_array($more['context'], array('datetaken', 'dateupload'))) { return not_okay("invalid date context"); } $cluster_id = $user['cluster_id']; $enc_user = AddSlashes($user['id']); if ($perms = flickr_photos_permissions_photos_where($user['id'], $more['viewer_id'])) { $str_perms = implode(",", $perms); $extra = " AND perms IN ({$str_perms})"; } # TO DO: INDEXES $sql = "SELECT MIN(`{$more['context']}`) AS start, MAX(`{$more['context']}`) AS end FROM FlickrPhotos WHERE user_id = '{$enc_user}' {$extra}"; $rsp = db_fetch_users($cluster_id, $sql); if (!$rsp['ok']) { return $rsp; } $row = db_single($rsp); if (!$row) { return not_okay("no photos to bookend!"); } return okay($row); }