Compare commits
23 Commits
feature/re
...
feature/no
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8f58fce1b0 | ||
![]() |
3420e053fc | ||
![]() |
a01bc6989e | ||
![]() |
a71aa0c3b6 | ||
![]() |
26be8a086e | ||
![]() |
af5de3ee14 | ||
![]() |
c8cee80144 | ||
![]() |
d8e170ff85 | ||
![]() |
9c101dfb7b | ||
![]() |
12fd228e75 | ||
![]() |
dc0eb0a548 | ||
![]() |
16ed4482f4 | ||
![]() |
57a847baf5 | ||
![]() |
332b6d7dd0 | ||
![]() |
99a92c6106 | ||
![]() |
4ca6f00c1b | ||
![]() |
7b8811b894 | ||
![]() |
900e4c94a7 | ||
![]() |
a434a45e4a | ||
![]() |
d5ee59825f | ||
![]() |
dd07940aea | ||
![]() |
78bb7dae28 | ||
![]() |
5642e73391 |
@@ -65,6 +65,10 @@ class EjaculationController extends Controller
|
||||
if (!empty($inputs['tags'])) {
|
||||
$tags = explode(' ', $inputs['tags']);
|
||||
foreach ($tags as $tag) {
|
||||
if ($tag === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tag = Tag::firstOrCreate(['name' => $tag]);
|
||||
$tagIds[] = $tag->id;
|
||||
}
|
||||
@@ -106,6 +110,8 @@ class EjaculationController extends Controller
|
||||
{
|
||||
$ejaculation = Ejaculation::findOrFail($id);
|
||||
|
||||
$this->authorize('edit', $ejaculation);
|
||||
|
||||
return view('ejaculation.edit')->with(compact('ejaculation'));
|
||||
}
|
||||
|
||||
@@ -113,6 +119,8 @@ class EjaculationController extends Controller
|
||||
{
|
||||
$ejaculation = Ejaculation::findOrFail($id);
|
||||
|
||||
$this->authorize('edit', $ejaculation);
|
||||
|
||||
$inputs = $request->all();
|
||||
|
||||
$validator = Validator::make($inputs, [
|
||||
@@ -147,6 +155,10 @@ class EjaculationController extends Controller
|
||||
if (!empty($inputs['tags'])) {
|
||||
$tags = explode(' ', $inputs['tags']);
|
||||
foreach ($tags as $tag) {
|
||||
if ($tag === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tag = Tag::firstOrCreate(['name' => $tag]);
|
||||
$tagIds[] = $tag->id;
|
||||
}
|
||||
@@ -163,6 +175,9 @@ class EjaculationController extends Controller
|
||||
public function destroy($id)
|
||||
{
|
||||
$ejaculation = Ejaculation::findOrFail($id);
|
||||
|
||||
$this->authorize('edit', $ejaculation);
|
||||
|
||||
$user = User::findOrFail($ejaculation->user_id);
|
||||
$ejaculation->tags()->detach();
|
||||
$ejaculation->delete();
|
||||
|
37
app/Http/Controllers/TagController.php
Normal file
37
app/Http/Controllers/TagController.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Tag;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$tags = Tag::select(DB::raw(
|
||||
<<<'SQL'
|
||||
tags.name,
|
||||
count(*) AS "checkins_count"
|
||||
SQL
|
||||
))
|
||||
->join('ejaculation_tag', 'tags.id', '=', 'ejaculation_tag.tag_id')
|
||||
->join('ejaculations', 'ejaculations.id', '=', 'ejaculation_tag.ejaculation_id')
|
||||
->join('users', 'users.id', '=', 'ejaculations.user_id')
|
||||
->where('ejaculations.is_private', false)
|
||||
->where(function ($query) {
|
||||
$query->where('users.is_protected', false);
|
||||
if (Auth::check()) {
|
||||
$query->orWhere('users.id', Auth::id());
|
||||
}
|
||||
})
|
||||
->groupBy('tags.name')
|
||||
->orderByDesc('checkins_count')
|
||||
->orderBy('tags.name')
|
||||
->paginate(100);
|
||||
|
||||
return view('tag.index', compact('tags'));
|
||||
}
|
||||
}
|
@@ -53,17 +53,19 @@ class DLsiteResolver implements Resolver
|
||||
public function resolve(string $url): Metadata
|
||||
{
|
||||
//アフィリエイトの場合は普通のURLに変換
|
||||
if (strpos($url, '/dlaf/=/link/') !== false) {
|
||||
preg_match('~www\.dlsite\.com/(?P<genre>.+)/dlaf/=/link/work/aid/.+/id/(?P<titleId>..\d+)(\.html)?~', $url, $matches);
|
||||
// ID型
|
||||
if (preg_match('~/dlaf/=(/.+/.+)?/link/~', $url)) {
|
||||
preg_match('~www\.dlsite\.com/(?P<genre>.+)/dlaf/=(/.+/.+)?/link/work/aid/(?P<AffiliateId>.+)/id/(?P<titleId>..\d+)(\.html)?~', $url, $matches);
|
||||
$url = "https://www.dlsite.com/{$matches['genre']}/work/=/product_id/{$matches['titleId']}.html";
|
||||
}
|
||||
// URL型
|
||||
if (strpos($url, '/dlaf/=/aid/') !== false) {
|
||||
preg_match('~www\.dlsite\.com/.+/dlaf/=/aid/.+/url/(?P<url>.+)~', $url, $matches);
|
||||
$affiliate_url = urldecode($matches['url']);
|
||||
if (preg_match('~www\.dlsite\.com/.+/(work|announce)/=/product_id/..\d+(\.html)?~', $affiliate_url, $matches)) {
|
||||
$url = $affiliate_url;
|
||||
$affiliateUrl = urldecode($matches['url']);
|
||||
if (preg_match('~www\.dlsite\.com/.+/(work|announce)/=/product_id/..\d+(\.html)?~', $affiliateUrl, $matches)) {
|
||||
$url = $affiliateUrl;
|
||||
} else {
|
||||
throw new \RuntimeException("アフィリエイト先のリンクがDLsiteのタイトルではありません: $affiliate_url");
|
||||
throw new \RuntimeException("アフィリエイト先のリンクがDLsiteのタイトルではありません: $affiliateUrl");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,7 @@ class MetadataResolver implements Resolver
|
||||
'~ec\.toranoana\.(jp|shop)/(tora|joshi)(_[rd]+)?/(ec|digi)/item/~' => ToranoanaResolver::class,
|
||||
'~iwara\.tv/(videos|images)/.*~' => IwaraResolver::class,
|
||||
'~www\.dlsite\.com/.*/(work|announce)/=/product_id/..\d+(\.html)?~' => DLsiteResolver::class,
|
||||
'~www\.dlsite\.com/.*/dlaf/=/link/(work|announce)/aid/.+/..\d+(\.html)?~' => DLsiteResolver::class,
|
||||
'~www\.dlsite\.com/.*/dlaf/=(/.+/.+)?/link/work/aid/.+(/id)?/..\d+(\.html)?~' => DLsiteResolver::class,
|
||||
'~www\.dlsite\.com/.*/dlaf/=/aid/.+/url/.+~' => DLsiteResolver::class,
|
||||
'~dlsite\.jp/...tw/..\d+~' => DLsiteResolver::class,
|
||||
'~www\.pixiv\.net/member_illust\.php\?illust_id=\d+~' => PixivResolver::class,
|
||||
@@ -33,7 +33,6 @@ class MetadataResolver implements Resolver
|
||||
'~store\.steampowered\.com/app/\d+~' => SteamResolver::class,
|
||||
'~www\.xtube\.com/video-watch/.*-\d+$~'=> XtubeResolver::class,
|
||||
'~ss\.kb10uy\.org/posts/\d+$~' => Kb10uyShortStoryServerResolver::class,
|
||||
'~(..|www)\.pornhub\.com/view_video\.php\?viewkey=.+$~'=> PornHubResolver::class,
|
||||
];
|
||||
|
||||
public $mimeTypes = [
|
||||
|
@@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\MetadataResolver;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
class PornHubResolver 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
|
||||
{
|
||||
// if (preg_match('~www\.xtube\.com/video-watch/.*-(\d+)$~', $url, $matches) !== 1) {
|
||||
// throw new \RuntimeException("Unmatched URL Pattern: $url");
|
||||
// }
|
||||
// $videoid = $matches[1];
|
||||
|
||||
$res = $this->client->get($url);
|
||||
if ($res->getStatusCode() === 200) {
|
||||
$html = (string) $res->getBody();
|
||||
$metadata = $this->ogpResolver->parse($html);
|
||||
$crawler = new Crawler($html);
|
||||
|
||||
$js = $crawler->filter('#player script')->text();
|
||||
if (preg_match('~({.+});~', $js, $matches)) {
|
||||
$json = $matches[1];
|
||||
$data = json_decode($json, true);
|
||||
|
||||
$metadata->title = $data['video_title'];
|
||||
$metadata->image = $data['image_url'];
|
||||
}
|
||||
|
||||
$metadata->tags = $crawler->filter('.video-detailed-info a:not(.add-btn-small)')->extract('_text');
|
||||
|
||||
|
||||
return $metadata;
|
||||
} else {
|
||||
throw new \RuntimeException("{$res->getStatusCode()}: $url");
|
||||
}
|
||||
}
|
||||
}
|
@@ -11,10 +11,15 @@ class XtubeResolver implements Resolver
|
||||
* @var Client
|
||||
*/
|
||||
private $client;
|
||||
/**
|
||||
* @var OGPResolver
|
||||
*/
|
||||
private $ogpResolver;
|
||||
|
||||
public function __construct(Client $client)
|
||||
public function __construct(Client $client, OGPResolver $ogpResolver)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->ogpResolver = $ogpResolver;
|
||||
}
|
||||
|
||||
public function resolve(string $url): Metadata
|
||||
@@ -25,17 +30,14 @@ class XtubeResolver implements Resolver
|
||||
|
||||
$res = $this->client->get($url);
|
||||
$html = (string) $res->getBody();
|
||||
$metadata = new Metadata();
|
||||
$metadata = $this->ogpResolver->parse($html);
|
||||
$crawler = new Crawler($html);
|
||||
|
||||
// poster URL抽出
|
||||
$playerConfig = explode("\n", trim($crawler->filter('#playerWrapper script')->last()->text()));
|
||||
preg_match('~https:\\\/\\\/cdn\d+-s-hw-e5\.xtube\.com\\\/m=(?P<size>.{8})\\\/videos\\\/\d{6}\\\/\d{2}\\\/.{5}-.{4}-\\\/original\\\/\d+\.jpg~', $playerConfig[0], $matches);
|
||||
$metadata->image = str_replace('\/', '/', $matches[0]);
|
||||
|
||||
$metadata->title = trim($crawler->filter('.underPlayerRateForm h1')->text(''));
|
||||
$metadata->description = trim($crawler->filter('.fullDescription ')->text(''));
|
||||
$metadata->tags = $crawler->filter('.tagsCategories a')->extract('_text');
|
||||
$metadata->image = str_replace('m=eSuQ8f', 'm=eaAaaEFb', $metadata->image);
|
||||
$metadata->image = str_replace('240X180', 'original', $metadata->image);
|
||||
$metadata->tags = array_map('trim', $crawler->filter('.tagsCategories a')->extract('_text'));
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
27
app/Policies/EjaculationPolicy.php
Normal file
27
app/Policies/EjaculationPolicy.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Ejaculation;
|
||||
use App\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class EjaculationPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Create a new policy instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function edit(User $user, Ejaculation $ejaculation): bool
|
||||
{
|
||||
return $user->id === $ejaculation->user_id;
|
||||
}
|
||||
}
|
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Ejaculation;
|
||||
use App\Policies\EjaculationPolicy;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
@@ -14,6 +16,7 @@ class AuthServiceProvider extends ServiceProvider
|
||||
*/
|
||||
protected $policies = [
|
||||
'App\Model' => 'App\Policies\ModelPolicy',
|
||||
Ejaculation::class => EjaculationPolicy::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
@@ -17,6 +17,7 @@
|
||||
"chart.js": "^2.7.1",
|
||||
"cross-env": "^5.2.0",
|
||||
"date-fns": "^1.30.1",
|
||||
"grapheme-splitter": "^1.0.4",
|
||||
"husky": "^1.3.1",
|
||||
"jquery": "^3.2.1",
|
||||
"js-cookie": "^2.2.0",
|
||||
|
5
resources/assets/js/app.js
vendored
5
resources/assets/js/app.js
vendored
@@ -85,6 +85,9 @@ $(() => {
|
||||
if (xhr.status === 409) {
|
||||
callback(JSON.parse(xhr.responseText));
|
||||
return;
|
||||
} else if (xhr.status === 401) {
|
||||
alert('いいねするためにはログインしてください。');
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(xhr);
|
||||
@@ -98,4 +101,4 @@ $(() => {
|
||||
$this.siblings(".card-link").removeClass("card-spoiler");
|
||||
$this.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import Vue from 'vue';
|
||||
import TagInput from "./components/TagInput.vue";
|
||||
import MetadataPreview from './components/MetadataPreview.vue';
|
||||
import GraphemeSplitter from "grapheme-splitter";
|
||||
|
||||
export const bus = new Vue({name: "EventBus"});
|
||||
|
||||
@@ -16,6 +17,7 @@ new Vue({
|
||||
data: {
|
||||
metadata: null,
|
||||
metadataLoadState: MetadataLoadState.Inactive,
|
||||
noteLength: 0
|
||||
},
|
||||
components: {
|
||||
TagInput,
|
||||
@@ -28,6 +30,16 @@ new Vue({
|
||||
this.fetchMetadata(linkInput.value);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
noteLength: (length: number) => {
|
||||
const counter = document.querySelector<HTMLElement>(
|
||||
"#note-character-counter"
|
||||
);
|
||||
if (counter) {
|
||||
counter.innerText = `残り ${500 - length} 文字`;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// オカズリンクの変更時
|
||||
onChangeLink(event: Event) {
|
||||
@@ -43,6 +55,14 @@ new Vue({
|
||||
this.fetchMetadata(url);
|
||||
}
|
||||
},
|
||||
onChangeNote(event: Event) {
|
||||
if (event.target instanceof HTMLTextAreaElement) {
|
||||
const splitter = new GraphemeSplitter();
|
||||
this.noteLength = splitter.splitGraphemes(
|
||||
event.target.value
|
||||
).length;
|
||||
}
|
||||
},
|
||||
// メタデータの取得
|
||||
fetchMetadata(url: string) {
|
||||
this.metadataLoadState = MetadataLoadState.Loading;
|
||||
|
3
resources/assets/sass/app.scss
vendored
3
resources/assets/sass/app.scss
vendored
@@ -13,3 +13,6 @@ $primary: #e53fb1;
|
||||
// Components
|
||||
@import "components/ejaculation";
|
||||
@import "components/link-card";
|
||||
|
||||
// Tag
|
||||
@import "tag/index";
|
||||
|
22
resources/assets/sass/tag/_index.scss
vendored
Normal file
22
resources/assets/sass/tag/_index.scss
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
.tags {
|
||||
& > .btn-tag {
|
||||
width: 100%;
|
||||
|
||||
.tag-name {
|
||||
display: inline-block;
|
||||
max-width: 80%;
|
||||
overflow: hidden;
|
||||
line-height: 40px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.checkins-count {
|
||||
display: inline-block;
|
||||
line-height: 40px;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
@@ -67,8 +67,8 @@
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>
|
||||
<textarea id="note" name="note" class="form-control {{ $errors->has('note') ? ' is-invalid' : '' }}" rows="4">{{ old('note') ?? $defaults['note'] }}</textarea>
|
||||
<small class="form-text text-muted">
|
||||
<textarea id="note" name="note" class="form-control {{ $errors->has('note') ? ' is-invalid' : '' }}" rows="4" v-on:input="onChangeNote">{{ old('note') ?? $defaults['note'] }}</textarea>
|
||||
<small id="note-character-counter" class="form-text text-muted">
|
||||
最大 500 文字
|
||||
</small>
|
||||
@if ($errors->has('note'))
|
||||
|
@@ -68,8 +68,8 @@
|
||||
<div class="form-row">
|
||||
<div class="form-group col-sm-12">
|
||||
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>
|
||||
<textarea id="note" name="note" class="form-control {{ $errors->has('note') ? ' is-invalid' : '' }}" rows="4">{{ old('note') ?? $ejaculation->note }}</textarea>
|
||||
<small class="form-text text-muted">
|
||||
<textarea id="note" name="note" class="form-control {{ $errors->has('note') ? ' is-invalid' : '' }}" rows="4" v-on:input="onChangeNote">{{ old('note') ?? $ejaculation->note }}</textarea>
|
||||
<small id="note-character-counter" class="form-text text-muted">
|
||||
最大 500 文字
|
||||
</small>
|
||||
@if ($errors->has('note'))
|
||||
|
@@ -54,6 +54,9 @@
|
||||
<a href="{{ route('user.likes', ['name' => Auth::user()->name]) }}" class="dropdown-item">いいね</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="{{ route('setting') }}" class="dropdown-item">設定</a>
|
||||
@can ('admin')
|
||||
<a href="{{ route('admin.dashboard') }}" class="dropdown-item">管理</a>
|
||||
@endcan
|
||||
<a href="{{ route('logout') }}" class="dropdown-item" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">ログアウト</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -79,6 +82,9 @@
|
||||
<li class="nav-item {{ stripos(Route::currentRouteName(), 'user.okazu') === 0 ? 'active' : ''}}">
|
||||
<a class="nav-link" href="{{ route('user.okazu', ['name' => Auth::user()->name]) }}">オカズ</a>
|
||||
</li>
|
||||
<li class="nav-item {{ stripos(Route::currentRouteName(), 'tag') === 0 ? 'active' : ''}}">
|
||||
<a class="nav-link" href="{{ route('tag') }}">タグ一覧</a>
|
||||
</li>
|
||||
{{--<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('ranking') }}">ランキング</a>
|
||||
</li>--}}
|
||||
@@ -137,6 +143,13 @@
|
||||
<a class="btn btn-{{ stripos(Route::currentRouteName(), 'user.okazu') === 0 ? 'primary' : 'outline-secondary'}}" href="{{ route('user.okazu', ['name' => Auth::user()->name]) }}" role="button">オカズ</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col">
|
||||
<a class="btn btn-{{ stripos(Route::currentRouteName(), 'tag') === 0 ? 'primary' : 'outline-secondary'}}" href="{{ route('tag') }}" role="button">タグ一覧</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
{{-- <div class="row mt-2">
|
||||
<div class="col">
|
||||
<a class="btn btn-outline-secondary" href="{{ route('ranking') }}">ランキング</a>
|
||||
|
20
resources/views/tag/index.blade.php
Normal file
20
resources/views/tag/index.blade.php
Normal file
@@ -0,0 +1,20 @@
|
||||
@extends('layouts.base')
|
||||
|
||||
@section('title', 'タグ一覧')
|
||||
|
||||
@section('content')
|
||||
<div class="container pb-1">
|
||||
<h2 class="mb-3">タグ一覧</h2>
|
||||
<p class="text-secondary">公開チェックインに付けられているタグを、チェックイン数の多い順で表示しています。</p>
|
||||
<div class="container-fluid">
|
||||
<div class="row mx-1">
|
||||
@foreach($tags as $tag)
|
||||
<div class="col-12 col-lg-6 col-xl-3 py-3 text-break tags">
|
||||
<a href="{{ route('search', ['q' => $tag->name]) }}" class="btn btn-outline-primary btn-tag" title="{{ $tag->name }}"><span class="tag-name">{{ $tag->name }}</span> <span class="checkins-count">({{ $tag->checkins_count }})</span></a>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
{{ $tags->links(null, ['className' => 'mt-4 justify-content-center']) }}
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
@@ -46,6 +46,8 @@ Route::redirect('/search', '/search/checkin', 301);
|
||||
Route::get('/search/checkin', 'SearchController@index')->name('search');
|
||||
Route::get('/search/related-tag', 'SearchController@relatedTag')->name('search.related-tag');
|
||||
|
||||
Route::get('/tag', 'TagController@index')->name('tag');
|
||||
|
||||
Route::middleware('can:admin')
|
||||
->namespace('Admin')
|
||||
->prefix('admin')
|
||||
|
@@ -227,7 +227,7 @@ class DLsiteResolverTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testAffiliateLink()
|
||||
public function testOldAffiliateLink()
|
||||
{
|
||||
$responseText = file_get_contents(__DIR__ . '/../../fixture/DLsite/testHome.html');
|
||||
|
||||
@@ -243,6 +243,38 @@ class DLsiteResolverTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testSnsAffiliateLink()
|
||||
{
|
||||
$responseText = file_get_contents(__DIR__ . '/../../fixture/DLsite/testHome.html');
|
||||
|
||||
$this->createResolver(DLsiteResolver::class, $responseText);
|
||||
|
||||
$metadata = $this->resolver->resolve('https://www.dlsite.com/home/dlaf/=/t/s/link/work/aid/eai04191/id/RJ221761.html');
|
||||
$this->assertEquals('ひつじ、数えてあげるっ', $metadata->title);
|
||||
$this->assertEquals('サークル名: Butterfly Dream' . PHP_EOL . '眠れないあなたに彼女が羊を数えてくれる音声です。', $metadata->description);
|
||||
$this->assertEquals('https://img.dlsite.jp/modpub/images2/work/doujin/RJ222000/RJ221761_img_main.jpg', $metadata->image);
|
||||
$this->assertEquals(['癒し', 'バイノーラル/ダミヘ', '日常/生活', 'ほのぼの', '恋人同士'], $metadata->tags);
|
||||
if ($this->shouldUseMock()) {
|
||||
$this->assertSame('https://www.dlsite.com/home/work/=/product_id/RJ221761.html', (string) $this->handler->getLastRequest()->getUri());
|
||||
}
|
||||
}
|
||||
|
||||
public function testAffiliateLink()
|
||||
{
|
||||
$responseText = file_get_contents(__DIR__ . '/../../fixture/DLsite/testHome.html');
|
||||
|
||||
$this->createResolver(DLsiteResolver::class, $responseText);
|
||||
|
||||
$metadata = $this->resolver->resolve('https://www.dlsite.com/home/dlaf/=/t/t/link/work/aid/eai04191/id/RJ221761.html');
|
||||
$this->assertEquals('ひつじ、数えてあげるっ', $metadata->title);
|
||||
$this->assertEquals('サークル名: Butterfly Dream' . PHP_EOL . '眠れないあなたに彼女が羊を数えてくれる音声です。', $metadata->description);
|
||||
$this->assertEquals('https://img.dlsite.jp/modpub/images2/work/doujin/RJ222000/RJ221761_img_main.jpg', $metadata->image);
|
||||
$this->assertEquals(['癒し', 'バイノーラル/ダミヘ', '日常/生活', 'ほのぼの', '恋人同士'], $metadata->tags);
|
||||
if ($this->shouldUseMock()) {
|
||||
$this->assertSame('https://www.dlsite.com/home/work/=/product_id/RJ221761.html', (string) $this->handler->getLastRequest()->getUri());
|
||||
}
|
||||
}
|
||||
|
||||
public function testAffiliateUrl()
|
||||
{
|
||||
$responseText = file_get_contents(__DIR__ . '/../../fixture/DLsite/testHome.html');
|
||||
|
1041
tests/fixture/Xtube/video.html
vendored
1041
tests/fixture/Xtube/video.html
vendored
File diff suppressed because one or more lines are too long
@@ -5,9 +5,8 @@
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"experimentalDecorators": true
|
||||
"experimentalDecorators": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": [
|
||||
"resources/assets/js/**/*"
|
||||
]
|
||||
}
|
||||
"include": ["resources/assets/js/**/*"]
|
||||
}
|
||||
|
@@ -3357,6 +3357,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
|
||||
integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
|
||||
|
||||
grapheme-splitter@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
|
||||
integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
|
||||
|
||||
growly@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||
|
Reference in New Issue
Block a user