<commit_before><?php // This is the salsa right here.

include(OPENFUEGO_DIR . '/openfuego-helper-functions.php');
include(OPENFUEGO_DIR . '/openfuego-metadata-functions.php');

function openfuego_get_universe($min_influence = 1) {
	
	try {
		$dbh = openfuego_get_dbh();
		$sth = $dbh->prepare("SELECT user_id FROM openfuego_citizens WHERE influence >= :min_influence;");
		$sth->bindParam('min_influence', $min_influence);
		$sth->execute();
		
		$user_ids = $sth->fetchAll(PDO::FETCH_COLUMN);

		return $user_ids;

	} catch (PDOException $e) {
		openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $e);
		return FALSE;
	}
}


function openfuego_clean_up() {

	$expiration_int = OPENFUEGO_EXPIRATION_INT;
	$now = time();
	$date = date('Y-m-d H:i:s', $now);
	
	$dbh = openfuego_get_dbh();
	
	$sql = "DELETE FROM openfuego_links WHERE first_seen < DATE_SUB(:date, INTERVAL :expiration_int DAY);
			DELETE FROM openfuego_short_links WHERE last_seen < DATE_SUB(:date, INTERVAL :expiration_int DAY);";
	$sth = $dbh->prepare($sql);
	$sth->bindParam('date', $date, PDO::PARAM_INT);
	$sth->bindParam('expiration_int', $expiration_int, PDO::PARAM_INT);
	$sth->execute();

  return TRUE;
 }


function openfuego_get_items($quantity = 10, $hours = 24, $scoring = TRUE, $metadata = FALSE) {

	$now = time();
	
	$quantity = (int)$quantity;
	$hours = (int)$hours;
	// $scoring = (int)$scoring;

	$date = date('Y-m-d H:i:s', $now);	

	if ($scoring) {
		$min_weighted_count = floor($hours/2.5+8);
		$limit = 100;	
	} else {
		$min_weighted_count = 1;
		$limit = $quantity;
	}
		
	try {
		$dbh = openfuego_get_dbh();
		$sql = "SELECT link_id, url, first_seen, first_user, weighted_count, count FROM openfuego_links WHERE weighted_count >= :min_weighted_count AND count > 1 AND first_seen BETWEEN DATE_SUB(:date, INTERVAL :hours HOUR) AND :date ORDER BY weighted_count DESC LIMIT :limit;";
		$sth = $dbh->prepare($sql);
		$sth->bindParam('date', $date, PDO::PARAM_STR);
		$sth->bindParam('hours', $hours, PDO::PARAM_INT);
		$sth->bindParam('min_weighted_count', $min_weighted_count, PDO::PARAM_INT);
		$sth->bindParam('limit', $limit, PDO::PARAM_INT);
			$sth->execute();
		
	} catch (PDOException $e) {
		openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $e);
		return FALSE;
	}

	$openfuego_items = $sth->fetchAll(PDO::FETCH_ASSOC);
			
	if (!$openfuego_items) {
		openfuego_notify('OpenFuego exception in ' . __FUNCTION__, "The following query returned 0 results: $sql");
		return FALSE;
	}

	foreach ($openfuego_items as $openfuego_item) {
	
		$link_id = (int)$openfuego_item['link_id'];
		
		$url = $openfuego_item['url'];
// 	$url_encoded = urlencode($url);
		$weighted_count = $openfuego_item['weighted_count'];
		$multiplier = NULL;
		$score = NULL;

		$first_seen = $openfuego_item['first_seen'];
		$first_seen = strtotime($first_seen);
		$age = $now - $first_seen;
		$age = $age / 3600; // to get hours
		$age = round($age, 1);
		
		$first_user = $openfuego_item['first_user'];
		
		    if ($age <  ($hours/6))								{ $multiplier = 1.20-$age/$hours; } // freshness boost!
		elseif ($age >= ($hours/6) && $age < ($hours/2))		{ $multiplier = 1.05-$age/$hours; }
		elseif ($age  > ($hours/2))								{ $multiplier = 1.01-$age/$hours; }
		
		$score = round($weighted_count * $multiplier);
		
		$openfuego_items_filtered[] = array('link_id' => $link_id, 'url' => $url, 'weighted_count' => $weighted_count, 'first_seen' => $first_seen, 'first_user' => $first_user, 'age' => $age, 'multiplier' => $multiplier, 'score' => $score);
		
		unset($link_id, $url, $weighted_count, $first_seen, $age, $multiplier, $score);
	}
	
	unset($openfuego_items);

	foreach ($openfuego_items_filtered as $key => $row) {
		$score[$key] = $scoring ? $row['score'] : $row['weighted_count'];
		$age[$key] = $row['age'];
	}
	
	array_multisort($score, SORT_DESC, $age, SORT_ASC, $openfuego_items_filtered);	// sort by score, then by age

	unset($age, $score);
	
	$openfuego_items_filtered = array_slice($openfuego_items_filtered, 0, $quantity);

	if ($metadata && defined('OPENFUEGO_EMBEDLY_API_KEY') && OPENFUEGO_EMBEDLY_API_KEY) {

		$metadata_params = is_array($metadata) ? $metadata : NULL;
		
		foreach ($openfuego_items_filtered as $openfuego_item_filtered) {
			$urls[] = $openfuego_item_filtered['url'];
		}
		
		$link_meta = array();
		$urls_chunked = array_chunk($urls, 20); // Embedly handles maximum 20 URLs per request
		foreach ($urls_chunked as $urls_chunk) {
			$link_meta_chunk = openfuego_get_metadata($urls_chunk, $metadata_params);
			$link_meta_chunk = json_decode($link_meta_chunk, TRUE);
			$link_meta = array_merge($link_meta, $link_meta_chunk);
		}
		unset($urls, $urls_chunked, $urls_chunk, $link_meta_chunk);
	}
	
	$row_count = count($openfuego_items_filtered);

	for ($i = 0; $i <= ($row_count - 1); $i++) {
	
		$link_id = $openfuego_items_filtered[$i]['link_id'];
		$url = $openfuego_items_filtered[$i]['url'];

		preg_match('@^(?:https?://)?([^/]+)@i', $url, $matches);	
		$domain = $matches[1];
		$domain = str_replace(array('www.', 'www10.'), '', $domain);

		if (strlen($domain) > 24) {
			preg_match('/[^.]+\.[^.]+$/', $domain, $matches);
			$domain = $matches[0];
		}
		
		$openfuego_items_filtered[$i]['domain'] = $domain;

		$openfuego_items_filtered[$i]['rank'] = $i+1;
			
		$status = openfuego_get_tweet($link_id);

		$tw_id_str = $status['id_str'];
		$tw_screen_name = $status['screen_name'];
		$tw_text = $status['text'];
		$tw_profile_image_url = $status['profile_image_url'];
		$tw_profile_image_url_bigger = null;
		$tw_tweet_url = null;
		
		if ($tw_profile_image_url && $tw_screen_name && $tw_id_str) {
			$tw_profile_image_url_bigger = str_replace('_normal.', '_bigger.', $tw_profile_image_url);
			$tw_tweet_url = 'https://twitter.com/' . $tw_screen_name . '/status/' . $tw_id_str;
		}

		$openfuego_items_filtered[$i]['tw_id_str'] = $tw_id_str;
 		$openfuego_items_filtered[$i]['tw_screen_name'] = $tw_screen_name;
		$openfuego_items_filtered[$i]['tw_text'] = $tw_text;
		$openfuego_items_filtered[$i]['tw_profile_image_url'] = $tw_profile_image_url;
		$openfuego_items_filtered[$i]['tw_profile_image_url_bigger'] = $tw_profile_image_url_bigger;
		$openfuego_items_filtered[$i]['tw_tweet_url'] = $tw_tweet_url;

		if (isset($link_meta)) {
			$openfuego_items_filtered[$i]['metadata'] = $link_meta[$i];
		}
		
		unset($openfuego_items_filtered[$i]['html']);
	}

 return $openfuego_items_filtered;
}


function openfuego_get_tweet($link_id) {

	$dbh = openfuego_get_dbh();

	try {
		$sth = $dbh->prepare("SELECT id_str, screen_name, text, profile_image_url FROM openfuego_tweets_cache WHERE link_id = :link_id LIMIT 1;");
		$sth->bindParam('link_id', $link_id);
		$sth->execute();

	} catch (PDOException $e) {
		openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $e);
		return FALSE;
	}
	
	$tweets_cache_row = $sth->fetch();

	if ($tweets_cache_row) {  // if tweet CACHED

		$id_str = $tweets_cache_row[0];
		$screen_name = $tweets_cache_row[1];
		$text = $tweets_cache_row[2];
		$profile_image_url = $tweets_cache_row[3];

	} else { // if associated tweet is NOT cached
	
		try {
			$query = $dbh->prepare("SELECT first_tweet FROM openfuego_links WHERE link_id = :link_id LIMIT 1");
			$query->bindParam('link_id', $link_id);
			$query->execute();

			$id_str = $query->fetchColumn(0);

		} catch (PDOException $e) {
			openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $e);
			return FALSE;
		}
		
		if (empty($id_str) || $id_str == NULL) {
			$status = openfuego_update_tweet($link_id);
			$id_str = $status['id_str'];
			$screen_name = $status['screen_name'];
			$text = $status['text'];
			$profile_image_url = $status['profile_image_url'];

		} else {

			$twitter = openfuego_twitter_connect();
			$status = $twitter->get("statuses/show/$id_str", array('include_entities' => false));

			if (preg_match("/2../", $twitter->http_code)) {
				$id_str = $status['id_str'];
				$screen_name = $status['user']['screen_name'];
				$text = $status['text'];
				$profile_image_url = $status['user']['profile_image_url'];

				try {
					$sth = $dbh->prepare("INSERT IGNORE INTO openfuego_tweets_cache (link_id, id_str, screen_name, text, profile_image_url) VALUES (:link_id, :id_str, :screen_name, :text, :profile_image_url);");
					$sth->bindParam('link_id', $link_id);
					$sth->bindParam('id_str', $id_str);
					$sth->bindParam('screen_name', $screen_name);
					$sth->bindParam('text', $text);
					$sth->bindParam('profile_image_url', $profile_image_url);
					$sth->execute();
		
				} catch (PDOException $e) {
					openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $e);
					return FALSE;
				}
			}

			elseif (preg_match("/4../", $twitter->http_code)) {
				$status = openfuego_update_tweet($link_id);
				$id_str = $status['id_str'];
				$screen_name = $status['screen_name'];
				$text = $status['text'];
				$profile_image_url = $status['profile_image_url'];
			}
						
			else {
				openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $twitter->http_code . "\n\n" . $twitter->url . "\n\n" . openfuego_curl($twitter->url));
				return FALSE;
			}
		}
	}

	$tweet = array('id_str' => $id_str, 'screen_name' => $screen_name, 'text' => $text, 'profile_image_url' => $profile_image_url);
		
	return $tweet;
}


function openfuego_update_tweet($link_id) {
	
	$dbh = openfuego_get_dbh();

	$sth = $dbh->query("SELECT sl.input_url, l.url, l.first_user_id FROM openfuego_links AS l LEFT JOIN (openfuego_short_links AS sl) ON (sl.long_url = l.url) WHERE l.link_id = $link_id;");
	
	$row = $sth->fetch(PDO::FETCH_ASSOC);

	$short_url = $row['input_url'];	
	$long_url = $row['url'];	
	$first_user_id = $row['first_user_id'];
	
	$query = $short_url ? $short_url . ' OR ' . $long_url : $long_url;

	$twitter = openfuego_twitter_connect();

	$search = $twitter->get("search/tweets", array('q' => $query, 'count' => 100, 'result_type' => 'mixed'));
	
	if ($search['statuses']) {
		$search_results = $search['statuses'];

		foreach ($search_results as $search_result) {
			if ($search_result['user']['id_str'] == $first_user_id) {
				break;
			}
		}
	}
	else {
		openfuego_notify('No Twitter search results on openfuego_update_tweet()', 'Query: ' . $twitter->url);
		return false; // no results. not sure what else to do, really.
	}
	
	$id_str = $search_result['user']['id_str'];
	$screen_name = $search_result['user']['screen_name'];
	$profile_image_url = $search_result['user']['profile_image_url'];
	$text = $search_result['text'];

	try {
		$sth = $dbh->prepare("INSERT INTO openfuego_tweets_cache (link_id, id_str, screen_name, text, profile_image_url) VALUES (:link_id, :id_str, :screen_name, :text, :profile_image_url) ON DUPLICATE KEY UPDATE id_str=VALUES(id_str), screen_name=VALUES(screen_name), text=VALUES(text), profile_image_url=VALUES(profile_image_url);");
		$sth->bindParam('link_id', $link_id);
		$sth->bindParam('id_str', $id_str);
		$sth->bindParam('screen_name', $screen_name);
		$sth->bindParam('text', $text);
		$sth->bindParam('profile_image_url', $profile_image_url);
		$sth->execute();

	} catch (PDOException $e) {
		openfuego_notify('PDO exception in ' . __FILE__ . ', ' . __LINE__, $e . "\n\n link_id: $link_id \n\n id_str: $id_str \n\n screen_name: $screen_name \n\n text: $text \n\n profile_image_url: $profile_image_url");

		return FALSE;
	}

	$tweet = array('id_str' => $id_str, 'screen_name' => $screen_name, 'text' => $text, 'profile_image_url' => $profile_image_url);
	
 return $tweet;
}


function openfuego_last_updated() {

	$dbh = openfuego_get_dbh();

	try {
		$sth = $dbh->prepare('SELECT last_seen FROM openfuego_links ORDER BY last_seen DESC LIMIT 1;');
		$sth->execute();
		$updated = $sth->fetchColumn(0);	
		$updated = strtotime($updated);
		return $updated;

	} catch (PDOException $e) {
		openfuego_notify('Could not get last_updated', $e);
		return FALSE;
	}
}

function openfuego_populate_universe($authorities, $min_influence = 1) {

	$owner_screen_name = strtolower(OPENFUEGO_TW_SCREEN_NAME);

	$twitter = openfuego_twitter_connect();
	
	$authorities = $twitter->get('users/lookup', array('screen_name' => implode(',', $authorities)));
<commit_msg>Remove @ sign in authority screen names<commit_after><?php // This is the salsa right here.

include(OPENFUEGO_DIR . '/openfuego-helper-functions.php');
include(OPENFUEGO_DIR . '/openfuego-metadata-functions.php');

function openfuego_get_universe($min_influence = 1) {
	
	try {
		$dbh = openfuego_get_dbh();
		$sth = $dbh->prepare("SELECT user_id FROM openfuego_citizens WHERE influence >= :min_influence;");
		$sth->bindParam('min_influence', $min_influence);
		$sth->execute();
		
		$user_ids = $sth->fetchAll(PDO::FETCH_COLUMN);

		return $user_ids;

	} catch (PDOException $e) {
		openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $e);
		return FALSE;
	}
}


function openfuego_clean_up() {

	$expiration_int = OPENFUEGO_EXPIRATION_INT;
	$now = time();
	$date = date('Y-m-d H:i:s', $now);
	
	$dbh = openfuego_get_dbh();
	
	$sql = "DELETE FROM openfuego_links WHERE first_seen < DATE_SUB(:date, INTERVAL :expiration_int DAY);
			DELETE FROM openfuego_short_links WHERE last_seen < DATE_SUB(:date, INTERVAL :expiration_int DAY);";
	$sth = $dbh->prepare($sql);
	$sth->bindParam('date', $date, PDO::PARAM_INT);
	$sth->bindParam('expiration_int', $expiration_int, PDO::PARAM_INT);
	$sth->execute();

  return TRUE;
 }


function openfuego_get_items($quantity = 10, $hours = 24, $scoring = TRUE, $metadata = FALSE) {

	$now = time();
	
	$quantity = (int)$quantity;
	$hours = (int)$hours;
	// $scoring = (int)$scoring;

	$date = date('Y-m-d H:i:s', $now);	

	if ($scoring) {
		$min_weighted_count = floor($hours/2.5+8);
		$limit = 100;	
	} else {
		$min_weighted_count = 1;
		$limit = $quantity;
	}
		
	try {
		$dbh = openfuego_get_dbh();
		$sql = "SELECT link_id, url, first_seen, first_user, weighted_count, count FROM openfuego_links WHERE weighted_count >= :min_weighted_count AND count > 1 AND first_seen BETWEEN DATE_SUB(:date, INTERVAL :hours HOUR) AND :date ORDER BY weighted_count DESC LIMIT :limit;";
		$sth = $dbh->prepare($sql);
		$sth->bindParam('date', $date, PDO::PARAM_STR);
		$sth->bindParam('hours', $hours, PDO::PARAM_INT);
		$sth->bindParam('min_weighted_count', $min_weighted_count, PDO::PARAM_INT);
		$sth->bindParam('limit', $limit, PDO::PARAM_INT);
			$sth->execute();
		
	} catch (PDOException $e) {
		openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $e);
		return FALSE;
	}

	$openfuego_items = $sth->fetchAll(PDO::FETCH_ASSOC);
			
	if (!$openfuego_items) {
		openfuego_notify('OpenFuego exception in ' . __FUNCTION__, "The following query returned 0 results: $sql");
		return FALSE;
	}

	foreach ($openfuego_items as $openfuego_item) {
	
		$link_id = (int)$openfuego_item['link_id'];
		
		$url = $openfuego_item['url'];
// 	$url_encoded = urlencode($url);
		$weighted_count = $openfuego_item['weighted_count'];
		$multiplier = NULL;
		$score = NULL;

		$first_seen = $openfuego_item['first_seen'];
		$first_seen = strtotime($first_seen);
		$age = $now - $first_seen;
		$age = $age / 3600; // to get hours
		$age = round($age, 1);
		
		$first_user = $openfuego_item['first_user'];
		
		    if ($age <  ($hours/6))								{ $multiplier = 1.20-$age/$hours; } // freshness boost!
		elseif ($age >= ($hours/6) && $age < ($hours/2))		{ $multiplier = 1.05-$age/$hours; }
		elseif ($age  > ($hours/2))								{ $multiplier = 1.01-$age/$hours; }
		
		$score = round($weighted_count * $multiplier);
		
		$openfuego_items_filtered[] = array('link_id' => $link_id, 'url' => $url, 'weighted_count' => $weighted_count, 'first_seen' => $first_seen, 'first_user' => $first_user, 'age' => $age, 'multiplier' => $multiplier, 'score' => $score);
		
		unset($link_id, $url, $weighted_count, $first_seen, $age, $multiplier, $score);
	}
	
	unset($openfuego_items);

	foreach ($openfuego_items_filtered as $key => $row) {
		$score[$key] = $scoring ? $row['score'] : $row['weighted_count'];
		$age[$key] = $row['age'];
	}
	
	array_multisort($score, SORT_DESC, $age, SORT_ASC, $openfuego_items_filtered);	// sort by score, then by age

	unset($age, $score);
	
	$openfuego_items_filtered = array_slice($openfuego_items_filtered, 0, $quantity);

	if ($metadata && defined('OPENFUEGO_EMBEDLY_API_KEY') && OPENFUEGO_EMBEDLY_API_KEY) {

		$metadata_params = is_array($metadata) ? $metadata : NULL;
		
		foreach ($openfuego_items_filtered as $openfuego_item_filtered) {
			$urls[] = $openfuego_item_filtered['url'];
		}
		
		$link_meta = array();
		$urls_chunked = array_chunk($urls, 20); // Embedly handles maximum 20 URLs per request
		foreach ($urls_chunked as $urls_chunk) {
			$link_meta_chunk = openfuego_get_metadata($urls_chunk, $metadata_params);
			$link_meta_chunk = json_decode($link_meta_chunk, TRUE);
			$link_meta = array_merge($link_meta, $link_meta_chunk);
		}
		unset($urls, $urls_chunked, $urls_chunk, $link_meta_chunk);
	}
	
	$row_count = count($openfuego_items_filtered);

	for ($i = 0; $i <= ($row_count - 1); $i++) {
	
		$link_id = $openfuego_items_filtered[$i]['link_id'];
		$url = $openfuego_items_filtered[$i]['url'];

		preg_match('@^(?:https?://)?([^/]+)@i', $url, $matches);	
		$domain = $matches[1];
		$domain = str_replace(array('www.', 'www10.'), '', $domain);

		if (strlen($domain) > 24) {
			preg_match('/[^.]+\.[^.]+$/', $domain, $matches);
			$domain = $matches[0];
		}
		
		$openfuego_items_filtered[$i]['domain'] = $domain;

		$openfuego_items_filtered[$i]['rank'] = $i+1;
			
		$status = openfuego_get_tweet($link_id);

		$tw_id_str = $status['id_str'];
		$tw_screen_name = $status['screen_name'];
		$tw_text = $status['text'];
		$tw_profile_image_url = $status['profile_image_url'];
		$tw_profile_image_url_bigger = null;
		$tw_tweet_url = null;
		
		if ($tw_profile_image_url && $tw_screen_name && $tw_id_str) {
			$tw_profile_image_url_bigger = str_replace('_normal.', '_bigger.', $tw_profile_image_url);
			$tw_tweet_url = 'https://twitter.com/' . $tw_screen_name . '/status/' . $tw_id_str;
		}

		$openfuego_items_filtered[$i]['tw_id_str'] = $tw_id_str;
 		$openfuego_items_filtered[$i]['tw_screen_name'] = $tw_screen_name;
		$openfuego_items_filtered[$i]['tw_text'] = $tw_text;
		$openfuego_items_filtered[$i]['tw_profile_image_url'] = $tw_profile_image_url;
		$openfuego_items_filtered[$i]['tw_profile_image_url_bigger'] = $tw_profile_image_url_bigger;
		$openfuego_items_filtered[$i]['tw_tweet_url'] = $tw_tweet_url;

		if (isset($link_meta)) {
			$openfuego_items_filtered[$i]['metadata'] = $link_meta[$i];
		}
		
		unset($openfuego_items_filtered[$i]['html']);
	}

 return $openfuego_items_filtered;
}


function openfuego_get_tweet($link_id) {

	$dbh = openfuego_get_dbh();

	try {
		$sth = $dbh->prepare("SELECT id_str, screen_name, text, profile_image_url FROM openfuego_tweets_cache WHERE link_id = :link_id LIMIT 1;");
		$sth->bindParam('link_id', $link_id);
		$sth->execute();

	} catch (PDOException $e) {
		openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $e);
		return FALSE;
	}
	
	$tweets_cache_row = $sth->fetch();

	if ($tweets_cache_row) {  // if tweet CACHED

		$id_str = $tweets_cache_row[0];
		$screen_name = $tweets_cache_row[1];
		$text = $tweets_cache_row[2];
		$profile_image_url = $tweets_cache_row[3];

	} else { // if associated tweet is NOT cached
	
		try {
			$query = $dbh->prepare("SELECT first_tweet FROM openfuego_links WHERE link_id = :link_id LIMIT 1");
			$query->bindParam('link_id', $link_id);
			$query->execute();

			$id_str = $query->fetchColumn(0);

		} catch (PDOException $e) {
			openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $e);
			return FALSE;
		}
		
		if (empty($id_str) || $id_str == NULL) {
			$status = openfuego_update_tweet($link_id);
			$id_str = $status['id_str'];
			$screen_name = $status['screen_name'];
			$text = $status['text'];
			$profile_image_url = $status['profile_image_url'];

		} else {

			$twitter = openfuego_twitter_connect();
			$status = $twitter->get("statuses/show/$id_str", array('include_entities' => false));

			if (preg_match("/2../", $twitter->http_code)) {
				$id_str = $status['id_str'];
				$screen_name = $status['user']['screen_name'];
				$text = $status['text'];
				$profile_image_url = $status['user']['profile_image_url'];

				try {
					$sth = $dbh->prepare("INSERT IGNORE INTO openfuego_tweets_cache (link_id, id_str, screen_name, text, profile_image_url) VALUES (:link_id, :id_str, :screen_name, :text, :profile_image_url);");
					$sth->bindParam('link_id', $link_id);
					$sth->bindParam('id_str', $id_str);
					$sth->bindParam('screen_name', $screen_name);
					$sth->bindParam('text', $text);
					$sth->bindParam('profile_image_url', $profile_image_url);
					$sth->execute();
		
				} catch (PDOException $e) {
					openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $e);
					return FALSE;
				}
			}

			elseif (preg_match("/4../", $twitter->http_code)) {
				$status = openfuego_update_tweet($link_id);
				$id_str = $status['id_str'];
				$screen_name = $status['screen_name'];
				$text = $status['text'];
				$profile_image_url = $status['profile_image_url'];
			}
						
			else {
				openfuego_notify('OpenFuego exception in ' . __FUNCTION__, $twitter->http_code . "\n\n" . $twitter->url . "\n\n" . openfuego_curl($twitter->url));
				return FALSE;
			}
		}
	}

	$tweet = array('id_str' => $id_str, 'screen_name' => $screen_name, 'text' => $text, 'profile_image_url' => $profile_image_url);
		
	return $tweet;
}


function openfuego_update_tweet($link_id) {
	
	$dbh = openfuego_get_dbh();

	$sth = $dbh->query("SELECT sl.input_url, l.url, l.first_user_id FROM openfuego_links AS l LEFT JOIN (openfuego_short_links AS sl) ON (sl.long_url = l.url) WHERE l.link_id = $link_id;");
	
	$row = $sth->fetch(PDO::FETCH_ASSOC);

	$short_url = $row['input_url'];	
	$long_url = $row['url'];	
	$first_user_id = $row['first_user_id'];
	
	$query = $short_url ? $short_url . ' OR ' . $long_url : $long_url;

	$twitter = openfuego_twitter_connect();

	$search = $twitter->get("search/tweets", array('q' => $query, 'count' => 100, 'result_type' => 'mixed'));
	
	if ($search['statuses']) {
		$search_results = $search['statuses'];

		foreach ($search_results as $search_result) {
			if ($search_result['user']['id_str'] == $first_user_id) {
				break;
			}
		}
	}
	else {
		openfuego_notify('No Twitter search results on openfuego_update_tweet()', 'Query: ' . $twitter->url);
		return false; // no results. not sure what else to do, really.
	}
	
	$id_str = $search_result['user']['id_str'];
	$screen_name = $search_result['user']['screen_name'];
	$profile_image_url = $search_result['user']['profile_image_url'];
	$text = $search_result['text'];

	try {
		$sth = $dbh->prepare("INSERT INTO openfuego_tweets_cache (link_id, id_str, screen_name, text, profile_image_url) VALUES (:link_id, :id_str, :screen_name, :text, :profile_image_url) ON DUPLICATE KEY UPDATE id_str=VALUES(id_str), screen_name=VALUES(screen_name), text=VALUES(text), profile_image_url=VALUES(profile_image_url);");
		$sth->bindParam('link_id', $link_id);
		$sth->bindParam('id_str', $id_str);
		$sth->bindParam('screen_name', $screen_name);
		$sth->bindParam('text', $text);
		$sth->bindParam('profile_image_url', $profile_image_url);
		$sth->execute();

	} catch (PDOException $e) {
		openfuego_notify('PDO exception in ' . __FILE__ . ', ' . __LINE__, $e . "\n\n link_id: $link_id \n\n id_str: $id_str \n\n screen_name: $screen_name \n\n text: $text \n\n profile_image_url: $profile_image_url");

		return FALSE;
	}

	$tweet = array('id_str' => $id_str, 'screen_name' => $screen_name, 'text' => $text, 'profile_image_url' => $profile_image_url);
	
 return $tweet;
}


function openfuego_last_updated() {

	$dbh = openfuego_get_dbh();

	try {
		$sth = $dbh->prepare('SELECT last_seen FROM openfuego_links ORDER BY last_seen DESC LIMIT 1;');
		$sth->execute();
		$updated = $sth->fetchColumn(0);	
		$updated = strtotime($updated);
		return $updated;

	} catch (PDOException $e) {
		openfuego_notify('Could not get last_updated', $e);
		return FALSE;
	}
}

function openfuego_populate_universe($authorities, $min_influence = 1) {

	$owner_screen_name = strtolower(OPENFUEGO_TW_SCREEN_NAME);

	$twitter = openfuego_twitter_connect();
	
	$authorities = implode(',', $authorities);
	$authorities = str_replace('@', '', $authorities);
	$authorities = $twitter->get('users/lookup', array('screen_name' => $authorities));

{'fraction_non_alphanumeric': 0.17654280569651334, 'fraction_numerical': 0.004992633818955639, 'mean_word_length': 5.011562115621156, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 161, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1515621', 'n_tokens_mistral': 10332, 'n_tokens_neox': 9285, 'n_words': 1640}