web/search_tweets.php
changeset 1558 761ba7426984
parent 1557 7c67caaafdeb
--- a/web/search_tweets.php	Mon Nov 20 18:10:58 2023 +0100
+++ b/web/search_tweets.php	Tue Sep 03 11:09:40 2024 +0200
@@ -1,4 +1,6 @@
 <?php
+use Abraham\TwitterOAuth\TwitterOAuth;
+use GuzzleHttp\Client;
 
 if (isset ($_GET['callback'])) {
 	header("Content-type: text/javascript");
@@ -6,11 +8,101 @@
 	header("Content-type: application/json");
 }
 
+include_once 'common.php';
 
-include_once 'common.php';
-use Abraham\TwitterOAuth\TwitterOAuth;
-use Stash\Pool;
-use Stash\Driver\Sqlite;
+function searchTwitter($token, $request_vars) {
+    $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $token['oauth_token'], $token['oauth_token_secret']);
+    $statuses = $connection->get("search/tweets", $request_vars);
+
+    return array_map(function($tweet) { 
+        $res = $tweet;
+        $res['type'] = "Twitter";
+        return $res;
+    }, $statuses);
+}
+
+function searchMastodon($token, $request_vars, $domain) {
+
+    $mapTootDomain = function($toot) use ($domain) {
+        return mapToot($toot, $domain);
+    };
+
+    $tag = $request_vars['q'] ?? false;
+
+    $rv = [
+        'limit' => min(intval($request_vars['count'] ?? 40), 40),
+    ];
+
+    if ($request_vars['since_id'] ?? false) {
+        $rv['since_id'] = $request_vars['since_id']; 
+    }
+
+    if(!$tag) {
+        return ["statuses" => []];
+    }
+
+    $client = new Client([
+        'base_uri' => "https://$domain",
+        'timeout'  => 2.0,
+    ]);
+    $resp = $client->get("/api/v1/timelines/tag/".ltrim($tag, '#'),[
+        "headers" => [
+            'Authorization' => 'Bearer ' . $token,        
+            'Accept'        => 'application/json',
+        ],
+        "query" => $rv
+    ]);
+    $body = (string)($resp->getBody());
+    $statuses = json_decode($body, true);
+    return ["statuses" => array_map($mapTootDomain, $statuses)];
+}
+
+function buildUsernameWithDomain($acct, $domain) {
+    return str_contains($acct, '@')?$acct:"$acct@$domain";
+}
+
+function getFullText($toot) {
+    if ($toot['reblog']) {
+        return $toot['reblog']['content'];
+    }
+    return $toot['content'];
+}
+
+function getRetweetedStatus($toot) {
+    $reblog = $toot["reblog"]; 
+    if (!$reblog) {
+        return null;
+    }
+    return ['id_str' => strval($reblog['id'])];
+}
+
+function buildUser($account, $domain) {
+    return [
+        "id" => strval($account['id']),
+        "screen_name" => buildUsernameWithDomain($account['acct'], $domain),
+        "name" => $account['display_name'],
+        "profile_image_url_https" => $account['avatar'],
+        "url" => $account['url']
+    ];
+}
+
+function mapToot($toot, $domain) {
+    $new_obj = [
+        'type' => 'Mastodon',
+        'id' => strval($toot['id']),
+        'from_user' => buildUsernameWithDomain($toot["account"]["acct"],$domain),
+        'user' => buildUser($toot["account"], $domain),
+        'from_user_id' => strval($toot["account"]["id"]),
+        'in_reply_to_status_id' => $toot["in_reply_to_id"]?strval($toot["in_reply_to_id"]):null,
+        'created_at' => $toot['created_at'],
+        'full_text' => getFullText($toot),
+        'retweeted_status' => getRetweetedStatus($toot),
+        'url' => $toot['url'],
+        'uri' => $toot['uri'],
+    ];
+
+    return $new_obj;
+}
 
 $cacheDriver = new Stash\Driver\Sqlite(array('path' => sys_get_temp_dir()."/polemictweet_cache.db"));
 $cachePool = new Stash\Pool($cacheDriver);
@@ -21,7 +113,10 @@
 if (!empty($_GET)
 && isset($_SESSION['SOCIAL_ACCESS_TOKEN'])) {
 
-    $itemCachePath="search/tweets?" . http_build_query($_GET);
+    $socialNetwork = isset($_GET['social_network'])?$_GET['social_network']:"Twitter";
+    $request_vars = array_filter($_GET,fn ($key) => $key != 'social_network', ARRAY_FILTER_USE_KEY); 
+
+    $itemCachePath="search/tweets?" . http_build_query($request_vars) . "_" . $_SESSION['SOCIAL_ACCESS_TOKEN'];
 
     $cachedStatusesResp = $cachePool->getItem($itemCachePath);
 
@@ -29,12 +124,18 @@
 
     if ($cachedStatusesResp->isMiss()) {
         $cachedStatusesResp->lock();
+    
         
         $token = unserialize($_SESSION['SOCIAL_ACCESS_TOKEN']);
-        $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $token['oauth_token'], $token['oauth_token_secret']);
+        $statuses = [];
+
+        if ($socialNetwork == "Twitter") {
+            $statuses = searchTwitter($token, $request_vars);    
+
+        } else if ($socialNetwork == "Mastodon") {
+            $statuses = searchMastodon($token, $request_vars, $_SESSION['SOCIAL_LOGIN_DOMAIN']);
+        }
     
-    
-        $statuses = $connection->get("search/tweets", $_GET);
         $statusesStr = json_encode($statuses);
 
         $cachedStatusesResp->set($statusesStr)->expiresAfter(3);