瀏覽代碼

Merge pull request #3006 from pixelfed/staging

Staging
daniel 3 年之前
父節點
當前提交
36b7a63d14
共有 5 個文件被更改,包括 295 次插入180 次删除
  1. 54 0
      app/Services/AutolinkService.php
  2. 46 1
      app/Util/Lexer/Autolink.php
  3. 21 3
      app/Util/Lexer/Extractor.php
  4. 2 2
      composer.json
  5. 172 174
      composer.lock

+ 54 - 0
app/Services/AutolinkService.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace App\Services;
+
+use Cache;
+use App\Profile;
+use Illuminate\Support\Str;
+use Illuminate\Support\Facades\Http;
+use App\Util\Webfinger\WebfingerUrl;
+
+class AutolinkService
+{
+	const CACHE_KEY = 'pf:services:autolink:';
+
+	public static function mentionedUsernameExists($username)
+	{
+		$key = 'pf:services:autolink:userexists:' . hash('sha256', $username);
+
+		return Cache::remember($key, 3600, function() use($username) {
+			$remote = Str::of($username)->contains('@');
+			$profile = Profile::whereUsername($username)->first();
+			if($profile) {
+				if($profile->domain != null) {
+					$instance = InstanceService::getByDomain($profile->domain);
+					if($instance && $instance->banned == true) {
+						return false;
+					}
+				}
+				return true;
+			} else {
+				if($remote) {
+					$parts = explode('@', $username);
+					$domain = last($parts);
+					$instance = InstanceService::getByDomain($domain);
+
+					if($instance) {
+						if($instance->banned == true) {
+							return false;
+						} else {
+							$wf = WebfingerUrl::generateWebfingerUrl($username);
+							$res = Http::head($wf);
+							return $res->ok();
+						}
+					} else {
+						$wf = WebfingerUrl::generateWebfingerUrl($username);
+						$res = Http::head($wf);
+						return $res->ok();
+					}
+				}
+			}
+			return false;
+		});
+	}
+}

+ 46 - 1
app/Util/Lexer/Autolink.php

@@ -10,6 +10,7 @@
 namespace App\Util\Lexer;
 
 use Illuminate\Support\Str;
+use App\Services\AutolinkService;
 
 /**
  * Twitter Autolink Class.
@@ -140,6 +141,12 @@ class Autolink extends Regex
      */
     protected $extractor = null;
 
+    /**
+     * @var autolinkActiveUsersOnly
+     */
+    protected $autolinkActiveUsersOnly = false;
+
+
     /**
      * Provides fluent method chaining.
      *
@@ -185,6 +192,30 @@ class Autolink extends Regex
         $this->url_base_cash = config('app.url').'/search?q=%24';
     }
 
+    public function setBaseUserPath($path = '/')
+    {
+        $this->url_base_user = config('app.url') . $path;
+        $this->target = null;
+        $this->external = null;
+        return $this;
+    }
+
+    public function setBaseHashPath($path = '/discover/tags/')
+    {
+        $this->url_base_hash = config('app.url') . $path;
+        $this->target = null;
+        $this->external = null;
+        return $this;
+    }
+
+    public function setAutolinkActiveUsersOnly($active)
+    {
+    	$this->autolinkActiveUsersOnly = $active;
+    	$this->target = null;
+        $this->external = null;
+    	return $this;
+    }
+
     /**
      * CSS class for auto-linked URLs.
      *
@@ -529,6 +560,14 @@ class Autolink extends Regex
         }
         $entities = $this->extractor->extractMentionsOrListsWithIndices($tweet);
 
+        if($this->autolinkActiveUsersOnly == true) {
+        	$entities = collect($entities)
+        		->filter(function($entity) {
+        			return AutolinkService::mentionedUsernameExists($entity['screen_name']);
+        		})
+        		->toArray();
+        }
+
         return $this->autoLinkEntities($tweet, $entities);
     }
 
@@ -707,8 +746,14 @@ class Autolink extends Regex
     public function linkToMentionAndList($entity)
     {
         $attributes = [];
-
         $screen_name = $entity['screen_name'];
+
+        if($this->autolinkActiveUsersOnly == true) {
+        	if(!AutolinkService::mentionedUsernameExists($screen_name)) {
+        		return Str::of($screen_name)->startsWith('@') ? $screen_name : "@{$screen_name}";
+        	}
+        }
+
         if (!empty($entity['list_slug'])) {
             // Replace the list and username
             $linkText = Str::startsWith($screen_name, '@') ? $screen_name : '@'.$screen_name;

+ 21 - 3
app/Util/Lexer/Extractor.php

@@ -11,6 +11,7 @@ namespace App\Util\Lexer;
 
 use Illuminate\Support\Str;
 use App\Status;
+use App\Services\AutolinkService;
 
 /**
  * Twitter Extractor Class.
@@ -33,6 +34,7 @@ class Extractor extends Regex
      * @var bool
      */
     protected $extractURLWithoutProtocol = true;
+    protected $activeUsersOnly = false;
 
     /**
      * Provides fluent method chaining.
@@ -48,6 +50,12 @@ class Extractor extends Regex
         return new self($tweet);
     }
 
+    public function setActiveUsersOnly($active)
+    {
+    	$this->activeUsersOnly = $active;
+    	return $this;
+    }
+
     /**
      * Reads in a tweet to be parsed and extracts elements from it.
      *
@@ -172,6 +180,12 @@ class Extractor extends Regex
         $mentionsWithIndices = $this->extractMentionsOrListsWithIndices($tweet);
 
         foreach ($mentionsWithIndices as $mentionWithIndex) {
+        	if($this->activeUsersOnly == true) {
+        		if(!AutolinkService::mentionedUsernameExists($mentionWithIndex['screen_name'])) {
+        			continue;
+        		}
+        	}
+
             $screen_name = mb_strtolower($mentionWithIndex['screen_name']);
             if (empty($screen_name) or in_array($screen_name, $usernamesOnly)) {
                 continue;
@@ -452,9 +466,13 @@ class Extractor extends Regex
             $start_position = $at[1] > 0 ? StringUtils::strlen(substr($tweet, 0, $at[1])) : $at[1];
             $end_position = $start_position + StringUtils::strlen($at[0]) + StringUtils::strlen($username[0]);
             $screenname = trim($all[0]) == '@'.$username[0] ? $username[0] : trim($all[0]);
-            if(config('app.env') == 'production' && \App\Profile::whereUsername($screenname)->exists() == false) {
-                continue;
-            }
+
+            if($this->activeUsersOnly == true) {
+        		if(!AutolinkService::mentionedUsernameExists($screenname)) {
+        			continue;
+        		}
+        	}
+
             $entity = [
                 'screen_name' => $screenname,
                 'list_slug'   => $list_slug[0],

+ 2 - 2
composer.json

@@ -5,7 +5,7 @@
 	"license": "AGPL-3.0-only",
 	"type": "project",
 	"require": {
-		"php": "^7.3",
+		"php": "^7.3|^7.4|^8.0",
 		"ext-bcmath": "*",
 		"ext-ctype": "*",
 		"ext-curl": "*",
@@ -13,7 +13,7 @@
 		"ext-json": "*",
 		"ext-mbstring": "*",
 		"ext-openssl": "*",
-		"beyondcode/laravel-self-diagnosis": "^1.0.2",
+		"beyondcode/laravel-self-diagnosis": "^1.0",
 		"brick/math": "^0.8",
 		"buzz/laravel-h-captcha": "1.0.2",
 		"doctrine/dbal": "^2.7",

文件差異過大導致無法顯示
+ 172 - 174
composer.lock


部分文件因文件數量過多而無法顯示