@@ -24,6 +24,7 @@ class MetadataResolver implements Resolver
 | 
			
		||||
        '~www\.deviantart\.com/.*/art/.*~' => DeviantArtResolver::class,
 | 
			
		||||
        '~\.syosetu\.com/n\d+[a-z]{2,}~' => NarouResolver::class,
 | 
			
		||||
        '~ci-en\.jp/creator/\d+/article/\d+~' => CienResolver::class,
 | 
			
		||||
        '~www\.plurk\.com\/p\/.*~' => PlurkResolver::class,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    public $mimeTypes = [
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								app/MetadataResolver/PlurkResolver.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/MetadataResolver/PlurkResolver.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\MetadataResolver;
 | 
			
		||||
 | 
			
		||||
use GuzzleHttp\Client;
 | 
			
		||||
 | 
			
		||||
class PlurkResolver implements Resolver
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var Client
 | 
			
		||||
     */
 | 
			
		||||
    private $client;
 | 
			
		||||
    /**
 | 
			
		||||
     * @var OGPResolver
 | 
			
		||||
     */
 | 
			
		||||
    private $ogpResolver;
 | 
			
		||||
 | 
			
		||||
    public function __construct(Client $client, OGPResolver $ogpResolver)
 | 
			
		||||
    {
 | 
			
		||||
        $this->client = $client;
 | 
			
		||||
        $this->ogpResolver = $ogpResolver;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function resolve(string $url): Metadata
 | 
			
		||||
    {
 | 
			
		||||
        $res = $this->client->get($url);
 | 
			
		||||
        if ($res->getStatusCode() === 200) {
 | 
			
		||||
            $metadata = $this->ogpResolver->parse($res->getBody());
 | 
			
		||||
 | 
			
		||||
            $dom = new \DOMDocument();
 | 
			
		||||
            @$dom->loadHTML(mb_convert_encoding($res->getBody(), 'HTML-ENTITIES', 'UTF-8'));
 | 
			
		||||
            $xpath = new \DOMXPath($dom);
 | 
			
		||||
            $imageNode = $xpath->query('//div[@class="text_holder"]/a[1]')->item(0);
 | 
			
		||||
 | 
			
		||||
            if ($imageNode) {
 | 
			
		||||
                $metadata->image = $imageNode->getAttribute('href');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $metadata;
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new \RuntimeException("{$res->getStatusCode()}: $url");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								tests/Unit/MetadataResolver/PlurkResolverTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								tests/Unit/MetadataResolver/PlurkResolverTest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Tests\Unit\MetadataResolver;
 | 
			
		||||
 | 
			
		||||
use App\MetadataResolver\PlurkResolver;
 | 
			
		||||
use Tests\TestCase;
 | 
			
		||||
 | 
			
		||||
class PlurkResolverTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    use CreateMockedResolver;
 | 
			
		||||
 | 
			
		||||
    public function setUp()
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUp();
 | 
			
		||||
 | 
			
		||||
        if (!$this->shouldUseMock()) {
 | 
			
		||||
            sleep(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function test()
 | 
			
		||||
    {
 | 
			
		||||
        $responseText = file_get_contents(__DIR__.'/../../fixture/Plurk/test.html');
 | 
			
		||||
 | 
			
		||||
        $this->createResolver(PlurkResolver::class, $responseText);
 | 
			
		||||
 | 
			
		||||
        $metadata = $this->resolver->resolve('https://www.plurk.com/p/n0awli/');
 | 
			
		||||
        $this->assertEquals('[R18]FC2實況中', $metadata->title);
 | 
			
		||||
        $this->assertEquals('Plurk by 小虫/ムシ@台中種 - 71 response(s)', $metadata->description);
 | 
			
		||||
        $this->assertEquals('https://images.plurk.com/5cT15Sf9OOFYk9fEQ759bZ.jpg', $metadata->image);
 | 
			
		||||
        if ($this->shouldUseMock()) {
 | 
			
		||||
            $this->assertSame('https://www.plurk.com/p/n0awli/', (string) $this->handler->getLastRequest()->getUri());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								tests/fixture/Plurk/test.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								tests/fixture/Plurk/test.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
    <head>
 | 
			
		||||
        <meta charset="utf-8">
 | 
			
		||||
        <title>小虫/ムシ@台中種 - [R18]FC2實況中 - Plurk</title>
 | 
			
		||||
        <link rel="shortcut icon" type="image/png" href="//s.plurk.com/936ddc656e104792b651240cdafeb7aa.png">
 | 
			
		||||
        <link rel="dns-prefetch" href="//avatars.plurk.com">
 | 
			
		||||
        <link rel="dns-prefetch" href="//emos.plurk.com">
 | 
			
		||||
        <link rel="dns-prefetch" href="//images.plurk.com">
 | 
			
		||||
        <link rel="dns-prefetch" href="//imgs.plurk.com">
 | 
			
		||||
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=0" />
 | 
			
		||||
        <meta name="mobile-web-app-capable" content="yes" />
 | 
			
		||||
        <meta name="apple-mobile-web-app-capable" content="yes" />
 | 
			
		||||
        <meta name="fragment" content="!">
 | 
			
		||||
        <meta property="og:type" content="article" />
 | 
			
		||||
        <meta property="og:title" content="[R18]FC2實況中" />
 | 
			
		||||
        <meta property="og:site_name" content="Plurk" />
 | 
			
		||||
        <meta property="og:url" content="https://www.plurk.com/p/n0awli" />
 | 
			
		||||
        <meta property="og:description" content="Plurk by 小虫/ムシ@台中種 - 71 response(s)" />
 | 
			
		||||
        <meta property="og:image" content="https://s.plurk.com/6c6e2fb987651802af50e5f6a3853b40.png" />
 | 
			
		||||
        <meta property="fb:app_id" content="47804741521"/>
 | 
			
		||||
        <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
 | 
			
		||||
        <meta name="verify-v1" content="iBRwaQ/3d4NoF1uaa2SAfCJ962ORry1TE8/4XxtIbHk=" />
 | 
			
		||||
        <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
 | 
			
		||||
        <meta name="application-name" content="Plurk"/>
 | 
			
		||||
        <meta name="msapplication-TileColor" content="#AA460F"/>
 | 
			
		||||
        <meta name="msapplication-TileImage" content="//s.plurk.com/0964d8f7301cc4ee38b343ed154d2369.png"/>
 | 
			
		||||
    </head>
 | 
			
		||||
 | 
			
		||||
    <body>
 | 
			
		||||
        <div class="content">
 | 
			
		||||
            <div class="text_holder">
 | 
			
		||||
                <a href="https://images.plurk.com/5cT15Sf9OOFYk9fEQ759bZ.jpg" class="ex_link pictureservices" rel="nofollow">
 | 
			
		||||
                    <img src="https://images.plurk.com/mx_5cT15Sf9OOFYk9fEQ759bZ.jpg" alt="https://images.plurk.com/5cT15Sf9OOFYk9fEQ759bZ.jpg" height="48">
 | 
			
		||||
                </a>
 | 
			
		||||
                <a href="https://images.plurk.com/2HdBlulzzXMZB7vITj4uOG.jpg" class="ex_link pictureservices" rel="nofollow">
 | 
			
		||||
                    <img src="https://images.plurk.com/mx_2HdBlulzzXMZB7vITj4uOG.jpg" alt="https://images.plurk.com/2HdBlulzzXMZB7vITj4uOG.jpg" height="48">
 | 
			
		||||
                </a> [R18]FC2實況中
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </body>
 | 
			
		||||
</html>
 | 
			
		||||
		Reference in New Issue
	
	Block a user