web/search_tweets.php
changeset 1558 761ba7426984
parent 1557 7c67caaafdeb
equal deleted inserted replaced
1557:7c67caaafdeb 1558:761ba7426984
     1 <?php
     1 <?php
       
     2 use Abraham\TwitterOAuth\TwitterOAuth;
       
     3 use GuzzleHttp\Client;
     2 
     4 
     3 if (isset ($_GET['callback'])) {
     5 if (isset ($_GET['callback'])) {
     4 	header("Content-type: text/javascript");
     6 	header("Content-type: text/javascript");
     5 } else {
     7 } else {
     6 	header("Content-type: application/json");
     8 	header("Content-type: application/json");
     7 }
     9 }
     8 
    10 
       
    11 include_once 'common.php';
     9 
    12 
    10 include_once 'common.php';
    13 function searchTwitter($token, $request_vars) {
    11 use Abraham\TwitterOAuth\TwitterOAuth;
    14     $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $token['oauth_token'], $token['oauth_token_secret']);
    12 use Stash\Pool;
    15     $statuses = $connection->get("search/tweets", $request_vars);
    13 use Stash\Driver\Sqlite;
    16 
       
    17     return array_map(function($tweet) { 
       
    18         $res = $tweet;
       
    19         $res['type'] = "Twitter";
       
    20         return $res;
       
    21     }, $statuses);
       
    22 }
       
    23 
       
    24 function searchMastodon($token, $request_vars, $domain) {
       
    25 
       
    26     $mapTootDomain = function($toot) use ($domain) {
       
    27         return mapToot($toot, $domain);
       
    28     };
       
    29 
       
    30     $tag = $request_vars['q'] ?? false;
       
    31 
       
    32     $rv = [
       
    33         'limit' => min(intval($request_vars['count'] ?? 40), 40),
       
    34     ];
       
    35 
       
    36     if ($request_vars['since_id'] ?? false) {
       
    37         $rv['since_id'] = $request_vars['since_id']; 
       
    38     }
       
    39 
       
    40     if(!$tag) {
       
    41         return ["statuses" => []];
       
    42     }
       
    43 
       
    44     $client = new Client([
       
    45         'base_uri' => "https://$domain",
       
    46         'timeout'  => 2.0,
       
    47     ]);
       
    48     $resp = $client->get("/api/v1/timelines/tag/".ltrim($tag, '#'),[
       
    49         "headers" => [
       
    50             'Authorization' => 'Bearer ' . $token,        
       
    51             'Accept'        => 'application/json',
       
    52         ],
       
    53         "query" => $rv
       
    54     ]);
       
    55     $body = (string)($resp->getBody());
       
    56     $statuses = json_decode($body, true);
       
    57     return ["statuses" => array_map($mapTootDomain, $statuses)];
       
    58 }
       
    59 
       
    60 function buildUsernameWithDomain($acct, $domain) {
       
    61     return str_contains($acct, '@')?$acct:"$acct@$domain";
       
    62 }
       
    63 
       
    64 function getFullText($toot) {
       
    65     if ($toot['reblog']) {
       
    66         return $toot['reblog']['content'];
       
    67     }
       
    68     return $toot['content'];
       
    69 }
       
    70 
       
    71 function getRetweetedStatus($toot) {
       
    72     $reblog = $toot["reblog"]; 
       
    73     if (!$reblog) {
       
    74         return null;
       
    75     }
       
    76     return ['id_str' => strval($reblog['id'])];
       
    77 }
       
    78 
       
    79 function buildUser($account, $domain) {
       
    80     return [
       
    81         "id" => strval($account['id']),
       
    82         "screen_name" => buildUsernameWithDomain($account['acct'], $domain),
       
    83         "name" => $account['display_name'],
       
    84         "profile_image_url_https" => $account['avatar'],
       
    85         "url" => $account['url']
       
    86     ];
       
    87 }
       
    88 
       
    89 function mapToot($toot, $domain) {
       
    90     $new_obj = [
       
    91         'type' => 'Mastodon',
       
    92         'id' => strval($toot['id']),
       
    93         'from_user' => buildUsernameWithDomain($toot["account"]["acct"],$domain),
       
    94         'user' => buildUser($toot["account"], $domain),
       
    95         'from_user_id' => strval($toot["account"]["id"]),
       
    96         'in_reply_to_status_id' => $toot["in_reply_to_id"]?strval($toot["in_reply_to_id"]):null,
       
    97         'created_at' => $toot['created_at'],
       
    98         'full_text' => getFullText($toot),
       
    99         'retweeted_status' => getRetweetedStatus($toot),
       
   100         'url' => $toot['url'],
       
   101         'uri' => $toot['uri'],
       
   102     ];
       
   103 
       
   104     return $new_obj;
       
   105 }
    14 
   106 
    15 $cacheDriver = new Stash\Driver\Sqlite(array('path' => sys_get_temp_dir()."/polemictweet_cache.db"));
   107 $cacheDriver = new Stash\Driver\Sqlite(array('path' => sys_get_temp_dir()."/polemictweet_cache.db"));
    16 $cachePool = new Stash\Pool($cacheDriver);
   108 $cachePool = new Stash\Pool($cacheDriver);
    17 
   109 
    18 /**
   110 /**
    19  * Check for a POSTed status message to send to Twitter
   111  * Check for a POSTed status message to send to Twitter
    20  */
   112  */
    21 if (!empty($_GET)
   113 if (!empty($_GET)
    22 && isset($_SESSION['SOCIAL_ACCESS_TOKEN'])) {
   114 && isset($_SESSION['SOCIAL_ACCESS_TOKEN'])) {
    23 
   115 
    24     $itemCachePath="search/tweets?" . http_build_query($_GET);
   116     $socialNetwork = isset($_GET['social_network'])?$_GET['social_network']:"Twitter";
       
   117     $request_vars = array_filter($_GET,fn ($key) => $key != 'social_network', ARRAY_FILTER_USE_KEY); 
       
   118 
       
   119     $itemCachePath="search/tweets?" . http_build_query($request_vars) . "_" . $_SESSION['SOCIAL_ACCESS_TOKEN'];
    25 
   120 
    26     $cachedStatusesResp = $cachePool->getItem($itemCachePath);
   121     $cachedStatusesResp = $cachePool->getItem($itemCachePath);
    27 
   122 
    28     $statusesStr = $cachedStatusesResp->get();
   123     $statusesStr = $cachedStatusesResp->get();
    29 
   124 
    30     if ($cachedStatusesResp->isMiss()) {
   125     if ($cachedStatusesResp->isMiss()) {
    31         $cachedStatusesResp->lock();
   126         $cachedStatusesResp->lock();
       
   127     
    32         
   128         
    33         $token = unserialize($_SESSION['SOCIAL_ACCESS_TOKEN']);
   129         $token = unserialize($_SESSION['SOCIAL_ACCESS_TOKEN']);
    34         $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $token['oauth_token'], $token['oauth_token_secret']);
   130         $statuses = [];
       
   131 
       
   132         if ($socialNetwork == "Twitter") {
       
   133             $statuses = searchTwitter($token, $request_vars);    
       
   134 
       
   135         } else if ($socialNetwork == "Mastodon") {
       
   136             $statuses = searchMastodon($token, $request_vars, $_SESSION['SOCIAL_LOGIN_DOMAIN']);
       
   137         }
    35     
   138     
    36     
       
    37         $statuses = $connection->get("search/tweets", $_GET);
       
    38         $statusesStr = json_encode($statuses);
   139         $statusesStr = json_encode($statuses);
    39 
   140 
    40         $cachedStatusesResp->set($statusesStr)->expiresAfter(3);
   141         $cachedStatusesResp->set($statusesStr)->expiresAfter(3);
    41         $cachePool->save($cachedStatusesResp);
   142         $cachePool->save($cachedStatusesResp);
    42     }
   143     }