Merge pull request #268 from shikorism/develop

Release 20190906.0000
This commit is contained in:
shibafu 2019-09-06 00:06:31 +09:00 committed by GitHub
commit ff6de777d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 22838 additions and 2536 deletions

View File

@ -1,9 +1,9 @@
version: 2
version: 2.1
jobs:
executors:
build:
docker:
- image: circleci/php:7.1-node-browsers
- image: circleci/php:7.3-node-browsers
environment:
APP_DEBUG: true
APP_ENV: testing
@ -17,38 +17,75 @@ jobs:
POSTGRES_DB: tissue
POSTGRES_USER: tissue
POSTGRES_PASSWORD: tissue
commands:
initialize:
steps:
- checkout
- run: sudo apt update
- run: sudo apt install -y libpq-dev
- run: sudo docker-php-ext-install zip
- run: sudo docker-php-ext-install pdo_pgsql
restore_composer:
steps:
- restore_cache:
keys:
- v1-dependencies-{{ checksum "composer.json" }}
- v1-dependencies-
- run: composer install -n --prefer-dist
save_composer:
steps:
- save_cache:
key: v1-dependencies-{{ checksum "composer.json" }}
paths:
- ./vendor
restore_npm:
steps:
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
- v1-dependencies-
- run: yarn install
save_npm:
steps:
- save_cache:
key: v1-dependencies-{{ checksum "package.json" }}
paths:
- ./node_modules
- ~/.yarn
- run: php artisan migrate
jobs:
build:
executor: build
steps:
- initialize
- restore_composer
- run: composer install -n --prefer-dist
- save_composer
- restore_npm
- run: yarn install
- save_npm
- run: yarn run prod
- persist_to_workspace:
root: .
paths:
- public
test:
executor: build
steps:
- initialize
- restore_composer
- restore_npm
- attach_workspace:
at: .
- run: php artisan migrate
# Run linter
- run:
command: |
@ -79,3 +116,51 @@ jobs:
- run:
command: bash <(curl -s https://codecov.io/bash) -f /tmp/phpunit/coverage.xml
when: always
test_resolver:
executor: build
environment:
TEST_USE_HTTP_MOCK: false
steps:
- initialize
- restore_composer
- attach_workspace:
at: .
- run: php artisan migrate
# Run unit test
- run:
command: |
mkdir -p /tmp/phpunit
./vendor/bin/phpunit --testsuite MetadataResolver --log-junit /tmp/phpunit/phpunit.xml --coverage-clover=/tmp/phpunit/coverage.xml
when: always
- store_test_results:
path: /tmp/phpunit
- store_artifacts:
path: /tmp/phpunit/coverage.xml
workflows:
version: 2.1
test:
jobs:
- build
- test:
requires:
- build
scheduled_resolver_test:
triggers:
- schedule:
cron: "4 0 * * 1"
filters:
branches:
only:
- develop
jobs:
- build
- test_resolver:
requires:
- build

View File

@ -1,6 +1,6 @@
FROM node:10-jessie as node
FROM php:7.1-apache
FROM php:7.3-apache
ENV APACHE_DOCUMENT_ROOT /var/www/html/public
@ -10,6 +10,7 @@ RUN apt-get update \
&& pecl install xdebug \
&& curl -sS https://getcomposer.org/installer | php \
&& mv composer.phar /usr/local/bin/composer \
&& composer global require hirak/prestissimo \
&& sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf \
&& sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf \
&& a2enmod rewrite

View File

@ -12,7 +12,7 @@ a.k.a. shikorism.net
## 実行環境
- PHP 7.1
- PHP 7.3
- PostgreSQL 9.6
## 開発環境の構築
@ -36,7 +36,6 @@ docker-compose up -d
4. Composer と yarn を使い必要なライブラリをインストールします。
```
docker-compose exec web composer global require hirak/prestissimo
docker-compose exec web composer install
docker-compose exec web yarn install
```

View File

@ -5,6 +5,7 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
class SettingController extends Controller
{
@ -18,10 +19,18 @@ class SettingController extends Controller
$inputs = $request->all();
$validator = Validator::make($inputs, [
'display_name' => 'required|string|max:20',
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique('users')->ignore(Auth::user()->email, 'email')
],
'bio' => 'nullable|string|max:160',
'url' => 'nullable|url|max:2000'
], [], [
'display_name' => '名前',
'email' => 'メールアドレス',
'bio' => '自己紹介',
'url' => 'URL'
]);
@ -32,6 +41,7 @@ class SettingController extends Controller
$user = Auth::user();
$user->display_name = $inputs['display_name'];
$user->email = $inputs['email'];
$user->bio = $inputs['bio'] ?? '';
$user->url = $inputs['url'] ?? '';
$user->save();

View File

@ -109,13 +109,6 @@ SQL
}
}
// 月間グラフ用の配列初期化
$month = Carbon::now()->firstOfMonth()->subMonth(11); // 直近12ヶ月
for ($i = 0; $i < 12; $i++) {
$monthlySum[$month->format('Y/m')] = 0;
$month->addMonth();
}
foreach ($groupByDay as $data) {
$date = Carbon::createFromFormat('Y/m/d', $data->date);
$yearAndMonth = $date->format('Y/m');
@ -123,21 +116,18 @@ SQL
$dailySum[$date->timestamp] = $data->count;
$yearlySum[$date->year] += $data->count;
$dowSum[$date->dayOfWeek] += $data->count;
if (isset($monthlySum[$yearAndMonth])) {
$monthlySum[$yearAndMonth] += $data->count;
}
$monthlySum[$yearAndMonth] = ($monthlySum[$yearAndMonth] ?? 0) + $data->count;
}
foreach ($groupByHour as $data) {
$hour = (int)$data->hour;
$hourlySum[$hour] += $data->count;
}
$graphData = [
'dailySum' => $dailySum,
'dowSum' => $dowSum,
'monthlyKey' => array_keys($monthlySum),
'monthlySum' => array_values($monthlySum),
'monthlySum' => $monthlySum,
'yearlyKey' => array_keys($yearlySum),
'yearlySum' => array_values($yearlySum),
'hourlyKey' => array_keys($hourlySum),

View File

@ -52,6 +52,20 @@ 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);
$url = "https://www.dlsite.com/{$matches['genre']}/work/=/product_id/{$matches['titleId']}.html";
}
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;
} else {
throw new \RuntimeException("アフィリエイト先のリンクがDLsiteのタイトルではありません: $affiliate_url");
}
}
//スマホページの場合はPCページに正規化
if (strpos($url, '-touch') !== false) {
@ -82,7 +96,8 @@ class DLsiteResolver implements Resolver
// #work_makerから「makerを含むテキスト」を持つ要素を持つtdを探す
// 作者名単体の場合もあるし、"作者A / 作者B"のようになることもある
$makersNode = $xpath->query('//*[@id="work_maker"]//*[contains(text(), "' . $makers[0] . '")]/ancestor::td')->item(0);
$makers = trim($makersNode->textContent);
// nbspをspaceに置換
$makers = trim(str_replace("\xc2\xa0", ' ', $makersNode->textContent));
// makersHaed
// $makerNode(td)に対するthを探す
@ -97,10 +112,11 @@ class DLsiteResolver implements Resolver
// OGP説明文から定型文を消す
if (strpos($url, 'dlsite.com/eng/') || strpos($url, 'dlsite.com/ecchi-eng/')) {
$metadata->description = trim(preg_replace('~DLsite.+ is a download shop for .+With a huge selection of products, we\'re sure you\'ll find whatever tickles your fancy\. DLsite is one of the greatest indie contents download shops in Japan\.$~', '', $metadata->description));
$metadata->description = preg_replace('~DLsite.+ is a download shop for .+With a huge selection of products, we\'re sure you\'ll find whatever tickles your fancy\. DLsite is one of the greatest indie contents download shops in Japan\.$~', '', $metadata->description);
} else {
$metadata->description = trim(preg_replace('~「DLsite.+」は.+のダウンロードショップ。お気に入りの作品をすぐダウンロードできてすぐ楽しめる毎日更新しているのであなたが探している作品にきっと出会えます。国内最大級の二次元総合ダウンロードショップ「DLsite」$~', '', $metadata->description));
$metadata->description = preg_replace('~「DLsite.+」は.+のダウンロードショップ。お気に入りの作品をすぐダウンロードできてすぐ楽しめる毎日更新しているのであなたが探している作品にきっと出会えます。国内最大級の二次元総合ダウンロードショップ「DLsite」$~', '', $metadata->description);
}
$metadata->description = trim(strip_tags($metadata->description));
// 整形
$metadata->description = $makersHead . ': ' . $makers . PHP_EOL . $metadata->description;

View File

@ -23,31 +23,27 @@ class DeviantArtResolver implements Resolver
public function resolve(string $url): Metadata
{
$res = $this->client->get($url);
$res = $this->client->get('https://backend.deviantart.com/oembed?url=' . $url);
if ($res->getStatusCode() === 200) {
$metadata = $this->ogpResolver->parse($res->getBody());
$data = json_decode($res->getBody()->getContents(), true);
$metadata = new Metadata();
$dom = new \DOMDocument();
@$dom->loadHTML(mb_convert_encoding($res->getBody(), 'HTML-ENTITIES', 'UTF-8'));
$xpath = new \DOMXPath($dom);
$node = $xpath->query('//*[@id="pimp-preload"]/following-sibling::div//img')->item(0);
$srcset = $node->getAttribute('srcset');
$srcset_array = explode('w,', $srcset);
$src = end($srcset_array);
$src = preg_replace('~ \d+w$~', '', $src);
if (preg_match('~\.wixmp\.com$~', parse_url($src)['host'])) {
// アスペクト比を保ったまま、縦か横が最大700pxになるように変換する。
if (preg_match('~\.wixmp\.com$~', parse_url($data['url'])['host'])) {
// アスペクト比を保ったまま、縦か横が最大1024pxになる画像を取得する。
// Ref: https://support.wixmp.com/en/article/image-service-3835799
if (strpos($src, '/v1/fill/')) {
$src = preg_replace('~/v1/fill/w_\d+,h_\d+,q_\d+,strp~', '/v1/fit/w_700,h_700,q_70,strp', $src);
// 作成されていない画像が参照されると403を返すようなので、サイト内で使用されている1024pxにした。
if (strpos($data['url'], '/v1/fill/')) {
$metadata->image = preg_replace('~/v1/fill/w_\d+,h_\d+(?:,q_\d+),strp/.+\.(jpg|png|webp|gif)~', '/v1/fit/w_1024,h_1024,strp/image.jpg', $data['url']);
} else {
$src = $src . '/v1/fit/w_700,h_700,q_70,strp/image.jpg';
$queryStartPos = strpos($data['url'], '?');
$metadata->image = substr_replace($data['url'], '/v1/fit/w_1024,h_1024,strp/image.jpg', $queryStartPos, 0);
}
} else {
$metadata->image = $data['url'];
}
$metadata->image = $src;
$metadata->title = $data['title'] ?? '';
$metadata->description = 'By ' . $data['author_name'];
return $metadata;
} else {

View File

@ -3,6 +3,7 @@
namespace App\MetadataResolver;
use GuzzleHttp\Client;
use Symfony\Component\DomCrawler\Crawler;
class IwaraResolver implements Resolver
{
@ -19,46 +20,40 @@ class IwaraResolver implements Resolver
public function resolve(string $url): Metadata
{
$res = $this->client->get($url);
if ($res->getStatusCode() === 200) {
$dom = new \DOMDocument();
@$dom->loadHTML(mb_convert_encoding($res->getBody(), 'HTML-ENTITIES', 'UTF-8'));
$xpath = new \DOMXPath($dom);
$metadata = new Metadata();
$html = (string) $res->getBody();
$crawler = new Crawler($html);
// find title
foreach ($xpath->query('//title') as $node) {
$content = $node->textContent;
if (!empty($content)) {
$metadata->title = $content;
break;
$infoElements = $crawler->filter('#video-player + div, .field-name-field-video-url + div, .field-name-field-images + div');
$title = $infoElements->filter('h1.title')->text();
$author = $infoElements->filter('.username')->text();
$description = $infoElements->filter('.field-type-text-with-summary')->text('');
$tags = $infoElements->filter('a[href^="/videos"], a[href^="/images"]')->extract('_text');
// 役に立たないタグを削除する
$tags = array_values(array_diff($tags, ['Uncategorized', 'Other']));
array_push($tags, $author);
$metadata->title = $title;
$metadata->description = '投稿者: ' . $author . PHP_EOL . $description;
$metadata->tags = $tags;
// iwara video
if ($crawler->filter('#video-player')->count()) {
$metadata->image = 'https:' . $crawler->filter('#video-player')->attr('poster');
}
// youtube
if ($crawler->filter('iframe[src^="//www.youtube.com"]')->count()) {
if (preg_match('~youtube\.com/embed/(\S+)\?~', $crawler->filter('iframe[src^="//www.youtube.com"]')->attr('src'), $matches) === 1) {
$youtubeId = $matches[1];
$metadata->image = 'https://img.youtube.com/vi/' . $youtubeId . '/maxresdefault.jpg';
}
}
// find thumbnail
foreach ($xpath->query('//*[@id="video-player"]') as $node) {
$poster = $node->getAttribute('poster');
if (!empty($poster)) {
if (strpos($poster, '//') === 0) {
$poster = 'https:' . $poster;
}
$metadata->image = $poster;
break;
}
}
if (empty($metadata->image)) {
// YouTube embedded?
foreach ($xpath->query('//div[@class="embedded-video"]//iframe') as $node) {
$src = $node->getAttribute('src');
if (preg_match('~youtube\.com/embed/(\S+)\?~', $src, $matches) !== -1) {
$youtubeId = $matches[1];
$iwaraThumbUrl = 'https://i.iwara.tv/sites/default/files/styles/thumbnail/public/video_embed_field_thumbnails/youtube/' . $youtubeId . '.jpg';
$metadata->image = $iwaraThumbUrl;
break;
}
}
// images
if ($crawler->filter('.field-name-field-images')->count()) {
$metadata->image = 'https:' . $crawler->filter('.field-name-field-images a')->first()->attr('href');
}
return $metadata;

View File

@ -14,8 +14,10 @@ class MetadataResolver implements Resolver
'~komiflo\.com(/#!)?/comics/(\\d+)~' => KomifloResolver::class,
'~www\.melonbooks\.co\.jp/detail/detail\.php~' => MelonbooksResolver::class,
'~ec\.toranoana\.(jp|shop)/(tora|joshi)(_[rd]+)?/(ec|digi)/item/~' => ToranoanaResolver::class,
'~iwara\.tv/videos/.*~' => IwaraResolver::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/=/aid/.+/url/.+~' => DLsiteResolver::class,
'~dlsite\.jp/...tw/..\d+~' => DLsiteResolver::class,
'~www\.pixiv\.net/member_illust\.php\?illust_id=\d+~' => PixivResolver::class,
'~www\.pixiv\.net/user/\d+/series/\d+~' => PixivResolver::class,
@ -28,6 +30,7 @@ class MetadataResolver implements Resolver
'~www\.plurk\.com\/p\/.*~' => PlurkResolver::class,
'~(adult\.)?contents\.fc2\.com\/article_search\.php\?id=\d+~' => FC2ContentsResolver::class,
'~store\.steampowered\.com/app/\d+~' => SteamResolver::class,
'~www\.xtube\.com/video-watch/.*-\d+$~'=> XtubeResolver::class,
];
public $mimeTypes = [

View File

@ -3,6 +3,7 @@
namespace App\MetadataResolver;
use GuzzleHttp\Client;
use Symfony\Component\DomCrawler\Crawler;
class NijieResolver implements Resolver
{
@ -30,23 +31,29 @@ class NijieResolver implements Resolver
$url = preg_replace('~view_popup\.php~', 'view.php', $url);
}
$client = $this->client;
$res = $client->get($url);
$res = $this->client->get($url);
if ($res->getStatusCode() === 200) {
$metadata = $this->ogpResolver->parse($res->getBody());
$html = (string) $res->getBody();
$metadata = $this->ogpResolver->parse($html);
$crawler = new Crawler($html);
$dom = new \DOMDocument();
@$dom->loadHTML(mb_convert_encoding($res->getBody(), 'HTML-ENTITIES', 'UTF-8'));
$xpath = new \DOMXPath($dom);
$dataNode = $xpath->query('//script[substring(@type, string-length(@type) - 3, 4) = "json"]');
foreach ($dataNode as $node) {
// 改行がそのまま入っていることがあるのでデコード前にエスケープが必要
$imageData = json_decode(preg_replace('/\r?\n/', '\n', $node->nodeValue), true);
if (isset($imageData['thumbnailUrl']) && !ends_with($imageData['thumbnailUrl'], '.gif') && !ends_with($imageData['thumbnailUrl'], '.mp4')) {
$metadata->image = preg_replace('~nijie\\.info/.*/nijie_picture/~', 'nijie.info/nijie_picture/', $imageData['thumbnailUrl']);
break;
}
// DomCrawler内でjson内の日本語がHTMLエンティティに変換されるのでhtml_entity_decode
$json = html_entity_decode($crawler->filter('script[type="application/ld+json"]')->first()->text());
// 改行がそのまま入っていることがあるのでデコード前にエスケープが必要
$data = json_decode(preg_replace('/\r?\n/', '\n', $json), true);
$metadata->title = $data['name'];
$metadata->description = '投稿者: ' . $data['author']['name'] . PHP_EOL . $data['description'];
if (
isset($data['thumbnailUrl']) &&
!ends_with($data['thumbnailUrl'], '.gif') &&
!ends_with($data['thumbnailUrl'], '.mp4')
) {
// サムネイルからメイン画像に
$metadata->image = str_replace('__rs_l160x160/', '', $data['thumbnailUrl']);
}
$metadata->tags = $crawler->filter('#view-tag span.tag_name')->extract('_text');
return $metadata;
} else {

View File

@ -24,11 +24,19 @@ class ToranoanaResolver implements Resolver
public function resolve(string $url): Metadata
{
$cookieJar = CookieJar::fromArray(['adflg' => '0'], 'ec.toranoana.jp');
$res = $this->client->get($url, ['cookies' => $cookieJar]);
$res = $this->client->get($url);
if ($res->getStatusCode() === 200) {
return $this->ogpResolver->parse($res->getBody());
$metadata = $this->ogpResolver->parse($res->getBody());
$dom = new \DOMDocument();
@$dom->loadHTML(mb_convert_encoding($res->getBody(), 'HTML-ENTITIES', 'UTF-8'));
$xpath = new \DOMXPath($dom);
$imgNode = $xpath->query('//*[@id="preview"]//img')->item(0);
if ($imgNode !== null) {
$metadata->image = $imgNode->getAttribute('src');
}
return $metadata;
} else {
throw new \RuntimeException("{$res->getStatusCode()}: $url");
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\MetadataResolver;
use GuzzleHttp\Client;
class XtubeResolver implements Resolver
{
/**
* @var Client
*/
private $client;
public function __construct(Client $client)
{
$this->client = $client;
}
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('https://www.xtube.com/webmaster/api/getvideobyid?video_id=' . $videoid);
if ($res->getStatusCode() === 200) {
$data = json_decode($res->getBody()->getContents(), true);
$metadata = new Metadata();
$metadata->title = $data['title'] ?? '';
$metadata->description = strip_tags(str_replace('\n', PHP_EOL, html_entity_decode($data['description'] ?? '')));
$metadata->image = str_replace('eSuQ8f', 'eSK08f', $data['thumb'] ?? ''); // 300x169 to 300x210
$metadata->tags = array_values(array_unique($data['tags']));
return $metadata;
} else {
throw new \RuntimeException("{$res->getStatusCode()}: $url");
}
}
}

View File

@ -13,7 +13,9 @@
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0",
"misd/linkify": "^1.1",
"staudenmeir/eloquent-eager-limit": "^1.0"
"staudenmeir/eloquent-eager-limit": "^1.0",
"symfony/css-selector": "^4.3",
"symfony/dom-crawler": "^4.3"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.1",

1298
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@
"cal-heatmap": "^3.3.10",
"chart.js": "^2.7.1",
"cross-env": "^5.2.0",
"date-fns": "^1.30.1",
"husky": "^1.3.1",
"jquery": "^3.2.1",
"js-cookie": "^2.2.0",

View File

@ -16,6 +16,10 @@
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="MetadataResolver">
<directory suffix="Test.php">./tests/Unit/MetadataResolver</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">

View File

@ -46,6 +46,14 @@
}
event.preventDefault();
break;
case 'Unidentified':
// ()
if (event.srcElement && (event.srcElement as HTMLInputElement).value.slice(-1) == ' ') {
this.tags.push(this.buffer);
this.buffer = "";
event.preventDefault();
}
break;
}
} else if (event.key === "Enter") {
//

View File

@ -1,9 +1,12 @@
import CalHeatMap from 'cal-heatmap';
import Chart from 'chart.js';
import {addMonths, format, startOfMonth, subMonths} from 'date-fns';
const graphData = JSON.parse(document.getElementById('graph-data').textContent);
function createLineGraph(id, labels, data) {
const context = document.getElementById(id).getContext('2d');
new Chart(context, {
return new Chart(context, {
type: 'line',
data: {
labels: labels,
@ -62,7 +65,22 @@ function createBarGraph(id, labels, data) {
});
}
const graphData = JSON.parse(document.getElementById('graph-data').textContent);
/**
* @param {Date} from
*/
function createMonthlyGraphData(from) {
const keys = [];
const values = [];
for (let i = 0; i < 12; i++) {
const current = addMonths(from, i);
const yearAndMonth = format(current, 'YYYY/MM');
keys.push(yearAndMonth);
values.push(graphData.monthlySum[yearAndMonth] || 0);
}
return {keys, values};
}
new CalHeatMap().init({
itemSelector: '#cal-heatmap',
@ -76,7 +94,40 @@ new CalHeatMap().init({
legend: [1, 2, 3, 4]
});
createLineGraph('monthly-graph', graphData.monthlyKey, graphData.monthlySum);
// 直近1年の月間グラフのデータを準備
const monthlyTermFrom = subMonths(startOfMonth(new Date()), 11);
const {keys: monthlyKey, values: monthlySum} = createMonthlyGraphData(monthlyTermFrom);
const monthlyGraph = createLineGraph('monthly-graph', monthlyKey, monthlySum);
createLineGraph('yearly-graph', graphData.yearlyKey, graphData.yearlySum);
createBarGraph('hourly-graph', graphData.hourlyKey, graphData.hourlySum);
createBarGraph('dow-graph', ['日', '月', '火', '水', '木', '金', '土'], graphData.dowSum);
createBarGraph('dow-graph', ['日', '月', '火', '水', '木', '金', '土'], graphData.dowSum);
// 月間グラフの期間セレクターを準備
const monthlyTermSelector = document.getElementById('monthly-term');
for (let year = monthlyTermFrom.getFullYear(); year <= new Date().getFullYear(); year++) {
const opt = document.createElement('option');
opt.setAttribute('value', year);
opt.textContent = `${year}`;
monthlyTermSelector.insertBefore(opt, monthlyTermSelector.firstChild);
}
if (monthlyTermSelector.children.length) {
monthlyTermSelector.selectedIndex = 0;
}
monthlyTermSelector.addEventListener('change', function (e) {
let monthlyTermFrom;
if (e.target.selectedIndex === 0) {
// 今年のデータを表示する時は、直近12ヶ月を表示
monthlyTermFrom = subMonths(startOfMonth(new Date()), 11);
} else {
// 過去のデータを表示する時は、選択年の1〜12月を表示
monthlyTermFrom = new Date(e.target.value, 0, 1);
}
const {keys, values} = createMonthlyGraphData(monthlyTermFrom);
monthlyGraph.data.labels = keys;
monthlyGraph.data.datasets[0].data = values;
monthlyGraph.update();
});

View File

@ -32,9 +32,12 @@
<small class="form-text text-muted">現在は変更できません。</small>
</div>
<div class="from-group mt-3">
<label for="name">メールアドレス</label>
<input id="name" name="name" type="text" class="form-control" value="{{ Auth::user()->email }}" disabled>
<small class="form-text text-muted">現在は変更できません。</small>
<label for="email">メールアドレス</label>
<input id="email" name="email" type="email" class="form-control {{ $errors->has('email') ? ' is-invalid' : '' }}" value="{{ old('email') ?? Auth::user()->email }}">
@if ($errors->has('email'))
<div class="invalid-feedback">{{ $errors->first('email') }}</div>
@endif
</div>
<div class="form-group mt-3">
<label for="bio">自己紹介</label>

View File

@ -15,7 +15,14 @@
<h5 class="my-4">Shikontribution graph</h5>
<div id="cal-heatmap" class="tis-contribution-graph"></div>
<hr class="my-4">
<h5 class="my-4">月間チェックイン回数</h5>
<div class="row my-4">
<div class="col-12 col-lg-6 d-flex align-items-center">
<h5 class="my-0">月間チェックイン回数</h5>
</div>
<div class="col-12 col-lg-6 mt-2 mt-lg-0">
<select id="monthly-term" class="form-control"></select>
</div>
</div>
<canvas id="monthly-graph" class="w-100"></canvas>
<hr class="my-4">
<h5 class="my-4">年間チェックイン回数</h5>

View File

@ -106,7 +106,7 @@ class DLsiteResolverTest extends TestCase
$metadata = $this->resolver->resolve('https://www.dlsite.com/books/work/=/product_id/BJ191317.html');
$this->assertEquals('永遠娘 vol.6', $metadata->title);
$this->assertEquals('著者: あまがえる / 玉之けだま / びんせん / 甘露アメ / 源五郎 / すみやお / 宇宙烏賊 / 毒茸人 / あやね / ガロウド / ハードボイルドよし子 / 夜歌 / 黒青郎君' . PHP_EOL . '君の命はどんな味なのだろうな?', $metadata->description);
$this->assertEquals('著者: あまがえる / 玉之けだま / びんせん / 甘露アメ / 源五郎 / すみやお / 宇宙烏賊 / 毒茸人 / あやね / ガロウド / ハードボイルドよし子 / 夜歌 / 黒青郎君' . PHP_EOL . '君の命はどんな味なのだろうな?', $metadata->description);
$this->assertEquals('https://img.dlsite.jp/modpub/images2/work/books/BJ192000/BJ191317_img_main.jpg', $metadata->image);
$this->assertEquals(['ツンデレ', 'ロリ', '妖怪', '人外娘/モンスター娘', 'セーラー服', 'メイド', 'ストッキング', 'ファンタジー', 'ぶっかけ', '中出し', '近親相姦', 'アヘ顔', '口内射精'], $metadata->tags);
if ($this->shouldUseMock()) {
@ -226,4 +226,62 @@ class DLsiteResolverTest extends TestCase
$this->assertSame('https://dlsite.jp/howtw/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/=/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');
$this->createResolver(DLsiteResolver::class, $responseText);
$metadata = $this->resolver->resolve('http://www.dlsite.com/home/dlaf/=/aid/eai04191/url/https%3A%2F%2Fwww.dlsite.com%2Fhome%2Fwork%2F=%2Fproduct_id%2FRJ221761.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 testAffiliateBadUrl()
{
$this->createResolver(DLsiteResolver::class, '');
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('アフィリエイト先のリンクがDLsiteのタイトルではありません: https://www.dlsite.com/home/');
$this->resolver->resolve('http://www.dlsite.com/home/dlaf/=/aid/eai04191/url/https%3A%2F%2Fwww.dlsite.com%2Fhome%2F');
}
public function testHTMLdescription()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/DLsite/testHTMLdescription.html');
$this->createResolver(DLsiteResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://www.dlsite.com/books/work/=/product_id/BJ123822.html');
$this->assertEquals('獣○彼女カタログ', $metadata->title);
$this->assertEquals('著者: チキコ / MUJIN編集部' . PHP_EOL . '【DLsite.com独占販売】 エロ漫画界騒然、1冊まるごと獣○オンリー単行本! 人間チ×ポは出てきませんっ!!', $metadata->description);
$this->assertEquals('https://img.dlsite.jp/modpub/images2/work/books/BJ124000/BJ123822_img_main.jpg', $metadata->image);
$this->assertEquals(['断面図', '制服', '水着', 'メイド', '巫女', '軍服', '中出し', 'フェラチオ', '複数プレイ/乱交', '異種姦', '巨乳/爆乳', '処女', '褐色/日焼け'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://www.dlsite.com/books/work/=/product_id/BJ123822.html', (string) $this->handler->getLastRequest()->getUri());
}
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace Tests\Unit\MetadataResolver;
use App\MetadataResolver\DeviantArtResolver;
use Tests\TestCase;
class DeviantArtResolverTest extends TestCase
{
use CreateMockedResolver;
public function setUp()
{
parent::setUp();
if (!$this->shouldUseMock()) {
sleep(1);
}
}
public function testWixmp()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/DeviantArt/wixmp.json');
$this->createResolver(DeviantArtResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://www.deviantart.com/bonchilo/art/Sally-Nox-743562408');
$this->assertSame('Sally Nox', $metadata->title);
$this->assertSame('By Bonchilo', $metadata->description);
$this->assertStringStartsWith('https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/f6b84a8f-053e-4ab6-bd6c-71276a4a9282/dcap4fc-6fd6359c-770b-4515-9e29-e99311d58d57.png/v1/fit/w_1024,h_1024,strp/image.jpg?token=', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://backend.deviantart.com/oembed?url=https://www.deviantart.com/bonchilo/art/Sally-Nox-743562408', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testWixmpNoImageOptions()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/DeviantArt/wixmpNoImageOptions.json');
$this->createResolver(DeviantArtResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://www.deviantart.com/messenger-lame/art/rem-639676105');
$this->assertSame('rem', $metadata->title);
$this->assertSame('By messenger-lame', $metadata->description);
$this->assertStringStartsWith('https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/9afa7937-381f-47f0-a8bc-40b9db1faad1/dakuh8p-aea3fc1c-c06e-466b-88ba-d27be8e164e9.png/v1/fit/w_1024,h_1024,strp/image.jpg?token=', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://backend.deviantart.com/oembed?url=https://www.deviantart.com/messenger-lame/art/rem-639676105', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testMature()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/DeviantArt/mature.json');
$this->createResolver(DeviantArtResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://www.deviantart.com/rasbii/art/backstage-620617246');
$this->assertSame('backstage', $metadata->title);
$this->assertSame('By Rasbii', $metadata->description);
$this->assertSame('https://orig00.deviantart.net/eb50/f/2016/191/a/b/preview_by_rasbii-da9hzby.png', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://backend.deviantart.com/oembed?url=https://www.deviantart.com/rasbii/art/backstage-620617246', (string) $this->handler->getLastRequest()->getUri());
}
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace Tests\Unit\MetadataResolver;
use App\MetadataResolver\IwaraResolver;
use Tests\TestCase;
class IwaraResolverTest extends TestCase
{
use CreateMockedResolver;
public function setUp()
{
parent::setUp();
if (!$this->shouldUseMock()) {
sleep(1);
}
}
public function testVideo()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Iwara/video.html');
$this->createResolver(IwaraResolver::class, $responseText);
$url = 'https://ecchi.iwara.tv/videos/wqlwatgmvhqg40kg';
$metadata = $this->resolver->resolve($url);
$this->assertEquals('Cakeface【鈴谷、プリンツ】', $metadata->title);
$this->assertEquals('投稿者: kuro@vov' . PHP_EOL . 'Thank you for watching!いつもありがとうございます' . PHP_EOL . 'こっそり微修正…' . PHP_EOL . 'Model鈴谷&プリンツ つみだんご様 罪袋BCD様' . PHP_EOL . '(いずれも改変)クレジット漏れゴメンナサイ。。。' . PHP_EOL, $metadata->description);
$this->assertEquals(['KanColle', 'kuro@vov'], $metadata->tags);
$this->assertEquals('https://i.iwara.tv/sites/default/files/videos/thumbnails/238591/thumbnail-238591_0004.jpg', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame($url, (string) $this->handler->getLastRequest()->getUri());
}
}
public function testYouTube()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Iwara/youtube.html');
$this->createResolver(IwaraResolver::class, $responseText);
$url = 'https://iwara.tv/videos/z4dn6fag4iko08o0';
$metadata = $this->resolver->resolve($url);
$this->assertEquals('むちむち天龍ちゃんで君色に染まる', $metadata->title);
$this->assertEquals('投稿者: kochira' . PHP_EOL . 'Ray-cast test. Still trying to figure out how Ray-cast works so I\'m sorry if anything looks off.' . PHP_EOL . 'Unauthorized reproduction prohibited (無断転載は禁止です/未經授權禁止複製)' . PHP_EOL, $metadata->description);
$this->assertEquals(['KanColle', 'kochira'], $metadata->tags);
$this->assertEquals('https://img.youtube.com/vi/pvA5Db082yo/maxresdefault.jpg', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame($url, (string) $this->handler->getLastRequest()->getUri());
}
}
public function testImages()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Iwara/images.html');
$this->createResolver(IwaraResolver::class, $responseText);
$url = 'https://iwara.tv/images/%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3';
$metadata = $this->resolver->resolve($url);
$this->assertEquals('鏡音りん18歳', $metadata->title);
$this->assertEquals('投稿者: Tonjiru Lion' . PHP_EOL . '今回はあんまエロくないです。' . PHP_EOL, $metadata->description);
$this->assertEquals(['Vocaloid', 'Tonjiru Lion'], $metadata->tags);
$this->assertEquals('https://i.iwara.tv/sites/default/files/photos/jing_yin_rin18sui_a.png', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame($url, (string) $this->handler->getLastRequest()->getUri());
}
}
}

View File

@ -25,10 +25,10 @@ class NijieResolverTest extends TestCase
$this->createResolver(NijieResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://nijie.info/view.php?id=66384');
$this->assertEquals('チンポップくんの日常ep.1「チンポップくんと釣り」 | ニジエ運営', $metadata->title);
$this->assertEquals("メールマガジン漫画のバックナンバー第一話です!\r\n最新話はメールマガジンより配信中です。", $metadata->description);
$this->assertRegExp('/pic\d+\.nijie\.info/', $metadata->image);
$this->assertNotRegExp('~/diff/main/~', $metadata->image);
$this->assertSame('チンポップくんの日常ep.1「チンポップくんと釣り」', $metadata->title);
$this->assertSame('投稿者: ニジエ運営' . PHP_EOL . 'メールマガジン漫画のバックナンバー第一話です!' . PHP_EOL . '最新話はメールマガジンより配信中です。', $metadata->description);
$this->assertSame('https://pic.nijie.net/04/nijie_picture/38_20131130155623.png', $metadata->image);
$this->assertSame(['ニジエたん', '釣り', 'チンポップ君の日常', '公式漫画'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://nijie.info/view.php?id=66384', (string) $this->handler->getLastRequest()->getUri());
}
@ -41,10 +41,10 @@ class NijieResolverTest extends TestCase
$this->createResolver(NijieResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://nijie.info/view.php?id=202707');
$this->assertEquals('ニジエ壁紙 | ニジエ運営', $metadata->title);
$this->assertEquals("ニジエのPCとiphone用(4.7inch推奨)の壁紙です。\r\n保存してご自由にお使いくださいませ。", $metadata->description);
$this->assertRegExp('/pic\d+\.nijie\.info/', $metadata->image);
$this->assertNotRegExp('~/diff/main/~', $metadata->image);
$this->assertSame('ニジエ壁紙', $metadata->title);
$this->assertSame('投稿者: ニジエ運営' . PHP_EOL . 'ニジエのPCとiphone用(4.7inch推奨)の壁紙です。' . PHP_EOL . '保存してご自由にお使いくださいませ。', $metadata->description);
$this->assertSame('https://pic.nijie.net/03/nijie_picture/38_20170209185801_0.png', $metadata->image);
$this->assertSame(['ニジエたん', '壁紙'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://nijie.info/view.php?id=202707', (string) $this->handler->getLastRequest()->getUri());
}
@ -57,9 +57,10 @@ class NijieResolverTest extends TestCase
$this->createResolver(NijieResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://nijie.info/view.php?id=9537');
$this->assertEquals('ニジエがgifに対応したんだってね 奥さん | 黒末アプコ', $metadata->title);
$this->assertEquals('アニメgifとか専門外なのでよくわかりませんでした', $metadata->description);
$this->assertRegExp('~/nijie\.info/pic/logo~', $metadata->image);
$this->assertSame('ニジエがgifに対応したんだってね 奥さん', $metadata->title);
$this->assertSame('投稿者: 黒末アプコ' . PHP_EOL . 'アニメgifとか専門外なのでよくわかりませんでした', $metadata->description);
$this->assertStringStartsWith('https://nijie.info/pic/logo/nijie_logo_og.png', $metadata->image);
$this->assertSame(['おっぱい', '陥没乳首', '眼鏡', 'GIFアニメ', 'ぶるんぶるん', 'アニメgif'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://nijie.info/view.php?id=9537', (string) $this->handler->getLastRequest()->getUri());
}
@ -72,74 +73,60 @@ class NijieResolverTest extends TestCase
$this->createResolver(NijieResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://nijie.info/view.php?id=256283');
$this->assertEquals('てすと | ニジエ運営', $metadata->title);
$this->assertEquals("H264動画てすと あとで消します\r\n\r\n今の所、H264コーデックのみ、出力時に音声なしにしないと投稿できません\r\n動画は勝手にループします", $metadata->description);
$this->assertRegExp('~/nijie\.info/pic/logo~', $metadata->image);
$this->assertSame('てすと', $metadata->title);
$this->assertSame('投稿者: ニジエ運営' . PHP_EOL . 'H264動画てすと あとで消します' . PHP_EOL . PHP_EOL . '今の所、H264コーデックのみ、出力時に音声なしにしないと投稿できません' . PHP_EOL . '動画は勝手にループします', $metadata->description);
$this->assertStringStartsWith('https://nijie.info/pic/logo/nijie_logo_og.png', $metadata->image);
$this->assertSame([], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://nijie.info/view.php?id=256283', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testStandardPictureSp()
public function testViewPopup()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Nijie/testStandardPictureResponse.html');
$this->createResolver(NijieResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://nijie.info/view_popup.php?id=66384');
$this->assertSame('チンポップくんの日常ep.1「チンポップくんと釣り」', $metadata->title);
$this->assertSame('投稿者: ニジエ運営' . PHP_EOL . 'メールマガジン漫画のバックナンバー第一話です!' . PHP_EOL . '最新話はメールマガジンより配信中です。', $metadata->description);
$this->assertSame('https://pic.nijie.net/04/nijie_picture/38_20131130155623.png', $metadata->image);
$this->assertSame(['ニジエたん', '釣り', 'チンポップ君の日常', '公式漫画'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://nijie.info/view.php?id=66384', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testSp()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Nijie/testStandardPictureResponse.html');
$this->createResolver(NijieResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://sp.nijie.info/view.php?id=66384');
$this->assertEquals('チンポップくんの日常ep.1「チンポップくんと釣り」 | ニジエ運営', $metadata->title);
$this->assertEquals("メールマガジン漫画のバックナンバー第一話です!\r\n最新話はメールマガジンより配信中です。", $metadata->description);
$this->assertRegExp('/pic\d+\.nijie\.info/', $metadata->image);
$this->assertNotRegExp('~/diff/main/~', $metadata->image);
$this->assertSame('チンポップくんの日常ep.1「チンポップくんと釣り」', $metadata->title);
$this->assertSame('投稿者: ニジエ運営' . PHP_EOL . 'メールマガジン漫画のバックナンバー第一話です!' . PHP_EOL . '最新話はメールマガジンより配信中です。', $metadata->description);
$this->assertSame('https://pic.nijie.net/04/nijie_picture/38_20131130155623.png', $metadata->image);
$this->assertSame(['ニジエたん', '釣り', 'チンポップ君の日常', '公式漫画'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://nijie.info/view.php?id=66384', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testMultiplePictureSp()
public function testSpViewPopup()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Nijie/testMultiplePictureResponse.html');
$responseText = file_get_contents(__DIR__ . '/../../fixture/Nijie/testStandardPictureResponse.html');
$this->createResolver(NijieResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://sp.nijie.info/view.php?id=202707');
$this->assertEquals('ニジエ壁紙 | ニジエ運営', $metadata->title);
$this->assertEquals("ニジエのPCとiphone用(4.7inch推奨)の壁紙です。\r\n保存してご自由にお使いくださいませ。", $metadata->description);
$this->assertRegExp('/pic\d+\.nijie\.info/', $metadata->image);
$this->assertNotRegExp('~/diff/main/~', $metadata->image);
$metadata = $this->resolver->resolve('https://sp.nijie.info/view_popup.php?id=66384');
$this->assertSame('チンポップくんの日常ep.1「チンポップくんと釣り」', $metadata->title);
$this->assertSame('投稿者: ニジエ運営' . PHP_EOL . 'メールマガジン漫画のバックナンバー第一話です!' . PHP_EOL . '最新話はメールマガジンより配信中です。', $metadata->description);
$this->assertSame('https://pic.nijie.net/04/nijie_picture/38_20131130155623.png', $metadata->image);
$this->assertSame(['ニジエたん', '釣り', 'チンポップ君の日常', '公式漫画'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://nijie.info/view.php?id=202707', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testAnimationGifSp()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Nijie/testAnimationGifResponse.html');
$this->createResolver(NijieResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://nijie.info/view.php?id=9537');
$this->assertEquals('ニジエがgifに対応したんだってね 奥さん | 黒末アプコ', $metadata->title);
$this->assertEquals('アニメgifとか専門外なのでよくわかりませんでした', $metadata->description);
$this->assertRegExp('~/nijie\.info/pic/logo~', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://nijie.info/view.php?id=9537', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testMp4MovieSp()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Nijie/testMp4MovieResponse.html');
$this->createResolver(NijieResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://sp.nijie.info/view.php?id=256283');
$this->assertEquals('てすと | ニジエ運営', $metadata->title);
$this->assertEquals("H264動画てすと あとで消します\r\n\r\n今の所、H264コーデックのみ、出力時に音声なしにしないと投稿できません\r\n動画は勝手にループします", $metadata->description);
$this->assertRegExp('~/nijie\.info/pic/logo~', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://nijie.info/view.php?id=256283', (string) $this->handler->getLastRequest()->getUri());
$this->assertSame('https://nijie.info/view.php?id=66384', (string) $this->handler->getLastRequest()->getUri());
}
}
}

View File

@ -40,13 +40,13 @@ class PixivResolverTest extends TestCase
$this->createResolver(PixivResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://www.pixiv.net/member_illust.php?mode=medium&illust_id=74939802');
$this->assertEquals('T-20S', $metadata->title);
$this->assertEquals('投稿者: amssc' . PHP_EOL . 'JUST FOR FUN' . PHP_EOL . '现在可以做到游戏内立绘修改拉!立绘动态皮肤都可以支持,想要资助获得新技术请站内信联系我。', $metadata->description);
$this->assertEquals('https://i.pixiv.cat/img-master/img/2019/05/28/01/16/24/74939802_p0_master1200.jpg', $metadata->image);
$this->assertEquals(['巨乳', '母乳', 'lastorigin', 'Last_Origin', 'T-20S', 'おっぱい', '라스트오리진', '노움'], $metadata->tags);
$metadata = $this->resolver->resolve('https://www.pixiv.net/member_illust.php?mode=medium&illust_id=75899985');
$this->assertEquals('コミッション絵33', $metadata->title);
$this->assertEquals('投稿者: ナゼ(NAZE)' . PHP_EOL . 'Leak' . PHP_EOL . PHP_EOL . 'Character:アリッサさん(依頼主のオリキャラ)', $metadata->description);
$this->assertEquals('https://i.pixiv.cat/img-master/img/2019/07/25/13/02/59/75899985_p0_master1200.jpg', $metadata->image);
$this->assertEquals(['巨乳輪', '超乳', '巨乳首', '母乳'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://www.pixiv.net/ajax/illust/74939802', (string) $this->handler->getLastRequest()->getUri());
$this->assertSame('https://www.pixiv.net/ajax/illust/75899985', (string) $this->handler->getLastRequest()->getUri());
}
}

View File

@ -0,0 +1,140 @@
<?php
namespace Tests\Unit\MetadataResolver;
use App\MetadataResolver\ToranoanaResolver;
use Tests\TestCase;
class ToranoanaResolverTest extends TestCase
{
use CreateMockedResolver;
public function setUp()
{
parent::setUp();
if (!$this->shouldUseMock()) {
sleep(1);
}
}
public function testTora()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Toranoana/testTora.html');
$this->createResolver(ToranoanaResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://ec.toranoana.shop/tora/ec/item/040030720152');
$this->assertEquals('新・古明地喫茶~そしてまた扉は開く~', $metadata->title);
$this->assertEquals('サークル【ツキギのとこ】(槻木こうすけ)発行の「新・古明地喫茶~そしてまた扉は開く~」を買うなら、とらのあな全年齢向け通信販売!', $metadata->description);
$this->assertRegExp('~ecdnimg\.toranoana\.jp/ec/img/.*\.jpg~', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://ec.toranoana.shop/tora/ec/item/040030720152', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testToraR()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Toranoana/testToraR.html');
$this->createResolver(ToranoanaResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://ec.toranoana.jp/tora_r/ec/item/040030720174');
$this->assertEquals('お姉ちゃんが妹のぱんつでひとりえっちしてました。', $metadata->title);
$this->assertEquals('サークル【没後】RYO発行の「お姉ちゃんが妹のぱんつでひとりえっちしてました。」を買うなら、とらのあな成年向け通信販売', $metadata->description);
$this->assertRegExp('~ecdnimg\.toranoana\.jp/ec/img/.*\.jpg~', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://ec.toranoana.jp/tora_r/ec/item/040030720174', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testToraD()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Toranoana/testToraD.html');
$this->createResolver(ToranoanaResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://ec.toranoana.shop/tora_d/digi/item/042000013358');
$this->assertEquals('虎の穴ラボの薄い本。vol 1.5', $metadata->title);
$this->assertEquals('サークル【虎の穴ラボ】虎の穴ラボエンジニアチーム発行の「虎の穴ラボの薄い本。vol 1.5」を買うなら、とらのあな全年齢向け電子書籍!', $metadata->description);
$this->assertRegExp('~ecdnimg\.toranoana\.jp/ec/img/.*\.jpg~', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://ec.toranoana.shop/tora_d/digi/item/042000013358', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testToraRD()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Toranoana/testToraRD.html');
$this->createResolver(ToranoanaResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://ec.toranoana.jp/tora_rd/digi/item/042000013181');
$this->assertEquals('放課後のお花摘み', $metadata->title);
$this->assertEquals('サークル【給食泥棒】(村雲)発行の「放課後のお花摘み」を買うなら、とらのあな成年向け電子書籍!', $metadata->description);
$this->assertRegExp('~ecdnimg\.toranoana\.jp/ec/img/.*\.jpg~', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://ec.toranoana.jp/tora_rd/digi/item/042000013181', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testJoshi()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Toranoana/testJoshi.html');
$this->createResolver(ToranoanaResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://ec.toranoana.shop/joshi/ec/item/040030702729');
$this->assertEquals('円卓のクソ漫画', $metadata->title);
$this->assertEquals('サークル【地獄のすなぎもカーニバル】槌田発行の「円卓のクソ漫画」を買うなら、とらのあなJOSHIBU全年齢向け通信販売', $metadata->description);
$this->assertRegExp('~ecdnimg\.toranoana\.jp/ec/img/.*\.jpg~', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://ec.toranoana.shop/joshi/ec/item/040030702729', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testJoshiR()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Toranoana/testJoshiR.html');
$this->createResolver(ToranoanaResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://ec.toranoana.jp/joshi_r/ec/item/040030730126');
$this->assertEquals('リバースナイトリバース', $metadata->title);
$this->assertEquals('サークル【雨傘サイクル】チャリリズム発行の「リバースナイトリバース」を買うなら、とらのあなJOSHIBU成年向け通信販売', $metadata->description);
$this->assertRegExp('~ecdnimg\.toranoana\.jp/ec/img/.*\.jpg~', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://ec.toranoana.jp/joshi_r/ec/item/040030730126', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testJoshiD()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Toranoana/testJoshiD.html');
$this->createResolver(ToranoanaResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://ec.toranoana.shop/joshi_d/digi/item/042000012192');
$this->assertEquals('超幸運ガール審神者GOLDEN', $metadata->title);
$this->assertEquals('サークル【Day Of The Dead】ほんちゅ発行の「超幸運ガール審神者GOLDEN」を買うなら、とらのあなJOSHIBU全年齢向け電子書籍', $metadata->description);
$this->assertRegExp('~ecdnimg\.toranoana\.jp/ec/img/.*\.jpg~', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://ec.toranoana.shop/joshi_d/digi/item/042000012192', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testJoshiRD()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Toranoana/testJoshiRD.html');
$this->createResolver(ToranoanaResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://ec.toranoana.jp/joshi_rd/digi/item/042000013472');
$this->assertEquals('UBWの裏側で非公式に遠坂凛をナデナデする本', $metadata->title);
$this->assertEquals('サークル【阿仁谷組】阿仁谷ユイジ発行の「UBWの裏側で非公式に遠坂凛をナデナデする本」を買うなら、とらのあなJOSHIBU成年向け電子書籍', $metadata->description);
$this->assertRegExp('~ecdnimg\.toranoana\.jp/ec/img/.*\.jpg~', $metadata->image);
if ($this->shouldUseMock()) {
$this->assertSame('https://ec.toranoana.jp/joshi_rd/digi/item/042000013472', (string) $this->handler->getLastRequest()->getUri());
}
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace Tests\Unit\MetadataResolver;
use App\MetadataResolver\XtubeResolver;
use Tests\TestCase;
class XtubeResolverTest extends TestCase
{
use CreateMockedResolver;
public function setUp()
{
parent::setUp();
if (!$this->shouldUseMock()) {
sleep(1);
}
}
public function test()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Xtube/test.json');
$this->createResolver(XtubeResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://www.xtube.com/video-watch/homegrown-big-tits-18634762');
$this->assertEquals('Homegrown Big Tits', $metadata->title);
$this->assertEquals('Dedicated to the fans of the beautiful amateur women with big natural tits. All user submitted - you can see big boob amateur hotties fucking and sucking as their tits bounce and sway.', $metadata->description);
$this->assertRegExp('~https://cdn\d-s-hw-e5\.xtube\.com/m=eSK08f/videos/201302/07/RF4Nk-S774-/240X180/1\.jpg~', $metadata->image);
$this->assertEquals(['bigtits', 'homeg'], $metadata->tags);
}
public function testNotMatch()
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Unmatched URL Pattern: https://www.xtube.com/gallery/black-celebs-free-7686657');
$this->createResolver(XtubeResolver::class, '');
$this->resolver->resolve('https://www.xtube.com/gallery/black-celebs-free-7686657');
}
public function testNotOK()
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('404: https://www.xtube.com/video-watch/notfound-404');
$this->createResolver(XtubeResolver::class, '', [], 404);
$this->resolver->resolve('https://www.xtube.com/video-watch/notfound-404');
}
}

File diff suppressed because it is too large Load Diff

1
tests/fixture/DeviantArt/mature.json vendored Normal file
View File

@ -0,0 +1 @@
{"version":"1.0","type":"photo","title":"backstage","category":"Anthro > Digital Media > Drawings > Animals","url":"https:\/\/orig00.deviantart.net\/eb50\/f\/2016\/191\/a\/b\/preview_by_rasbii-da9hzby.png","author_name":"Rasbii","author_url":"https:\/\/www.deviantart.com\/rasbii","provider_name":"DeviantArt","provider_url":"https:\/\/www.deviantart.com","safety":"adult","pubdate":"2016-07-09T13:12:42-07:00","community":{"statistics":{"_attributes":{"views":6678,"favorites":127,"comments":39,"downloads":0}}},"rating":"adult","license":{"_attributes":{"type":"text\/html","href":"http:\/\/creativecommons.org\/licenses\/by-nc-nd\/3.0\/"},"0":"Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 License"},"width":"689","height":"619","imagetype":"png","thumbnail_url":"https:\/\/t00.deviantart.net\/eJ1IFDUqQxCrbw2pGNP2ZYtyqk4=\/fit-in\/300x900\/filters:no_upscale():origin()\/pre00\/e504\/th\/pre\/f\/2016\/191\/a\/b\/preview_by_rasbii-da9hzby.png","thumbnail_width":300,"thumbnail_height":270,"thumbnail_url_150":"https:\/\/t00.deviantart.net\/EUshcQ7hG73H6zzfsrnH8xJl5dQ=\/fit-in\/150x150\/filters:no_upscale():origin()\/pre00\/e504\/th\/pre\/f\/2016\/191\/a\/b\/preview_by_rasbii-da9hzby.png","thumbnail_url_200h":"https:\/\/t00.deviantart.net\/ijA0nHI6NA42Ocm0Bfd1rhrDHh0=\/300x200\/filters:fixed_height(100,100):origin()\/pre00\/e504\/th\/pre\/f\/2016\/191\/a\/b\/preview_by_rasbii-da9hzby.png","thumbnail_width_200h":223,"thumbnail_height_200h":200}

1
tests/fixture/DeviantArt/wixmp.json vendored Normal file
View File

@ -0,0 +1 @@
{"version":"1.0","type":"photo","title":"Sally Nox","category":"Manga & Anime > Digital Media > Drawings","url":"https:\/\/images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com\/f\/f6b84a8f-053e-4ab6-bd6c-71276a4a9282\/dcap4fc-6fd6359c-770b-4515-9e29-e99311d58d57.png\/v1\/fill\/w_947,h_844,q_70,strp\/sally__nox_by_bonchilo_dcap4fc-pre.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9MTE0MCIsInBhdGgiOiJcL2ZcL2Y2Yjg0YThmLTA1M2UtNGFiNi1iZDZjLTcxMjc2YTRhOTI4MlwvZGNhcDRmYy02ZmQ2MzU5Yy03NzBiLTQ1MTUtOWUyOS1lOTkzMTFkNThkNTcucG5nIiwid2lkdGgiOiI8PTEyODAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.zbw4e5eH0NafyMmhM15DKN1NjawSZBUwr2RWQWB7O3o","author_name":"Bonchilo","author_url":"https:\/\/www.deviantart.com\/bonchilo","provider_name":"DeviantArt","provider_url":"https:\/\/www.deviantart.com","safety":"nonadult","pubdate":"2018-05-05T07:18:54-07:00","community":{"statistics":{"_attributes":{"views":243,"favorites":73,"comments":7,"downloads":7}}},"copyright":{"_attributes":{"url":"https:\/\/www.deviantart.com\/bonchilo","year":"2018","entity":"Bonchilo"}},"width":947,"height":844,"imagetype":"","thumbnail_url":"https:\/\/images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com\/f\/f6b84a8f-053e-4ab6-bd6c-71276a4a9282\/dcap4fc-6fd6359c-770b-4515-9e29-e99311d58d57.png\/v1\/fit\/w_300,h_900,q_70,strp\/sally__nox_by_bonchilo_dcap4fc-300w.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9MTE0MCIsInBhdGgiOiJcL2ZcL2Y2Yjg0YThmLTA1M2UtNGFiNi1iZDZjLTcxMjc2YTRhOTI4MlwvZGNhcDRmYy02ZmQ2MzU5Yy03NzBiLTQ1MTUtOWUyOS1lOTkzMTFkNThkNTcucG5nIiwid2lkdGgiOiI8PTEyODAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.zbw4e5eH0NafyMmhM15DKN1NjawSZBUwr2RWQWB7O3o","thumbnail_width":300,"thumbnail_height":267,"thumbnail_url_150":"https:\/\/images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com\/f\/f6b84a8f-053e-4ab6-bd6c-71276a4a9282\/dcap4fc-6fd6359c-770b-4515-9e29-e99311d58d57.png\/v1\/fit\/w_150,h_150,q_70,strp\/sally__nox_by_bonchilo_dcap4fc-150.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9MTE0MCIsInBhdGgiOiJcL2ZcL2Y2Yjg0YThmLTA1M2UtNGFiNi1iZDZjLTcxMjc2YTRhOTI4MlwvZGNhcDRmYy02ZmQ2MzU5Yy03NzBiLTQ1MTUtOWUyOS1lOTkzMTFkNThkNTcucG5nIiwid2lkdGgiOiI8PTEyODAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.zbw4e5eH0NafyMmhM15DKN1NjawSZBUwr2RWQWB7O3o","thumbnail_url_200h":"https:\/\/images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com\/f\/f6b84a8f-053e-4ab6-bd6c-71276a4a9282\/dcap4fc-6fd6359c-770b-4515-9e29-e99311d58d57.png\/v1\/fill\/w_225,h_200,q_70,strp\/sally__nox_by_bonchilo_dcap4fc-200h.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9MTE0MCIsInBhdGgiOiJcL2ZcL2Y2Yjg0YThmLTA1M2UtNGFiNi1iZDZjLTcxMjc2YTRhOTI4MlwvZGNhcDRmYy02ZmQ2MzU5Yy03NzBiLTQ1MTUtOWUyOS1lOTkzMTFkNThkNTcucG5nIiwid2lkdGgiOiI8PTEyODAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.zbw4e5eH0NafyMmhM15DKN1NjawSZBUwr2RWQWB7O3o","thumbnail_width_200h":225,"thumbnail_height_200h":200}

View File

@ -0,0 +1 @@
{"version":"1.0","type":"photo","title":"rem","category":"Manga & Anime > Digital Media > Drawings","url":"https:\/\/images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com\/f\/9afa7937-381f-47f0-a8bc-40b9db1faad1\/dakuh8p-aea3fc1c-c06e-466b-88ba-d27be8e164e9.png?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcLzlhZmE3OTM3LTM4MWYtNDdmMC1hOGJjLTQwYjlkYjFmYWFkMVwvZGFrdWg4cC1hZWEzZmMxYy1jMDZlLTQ2NmItODhiYS1kMjdiZThlMTY0ZTkucG5nIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmZpbGUuZG93bmxvYWQiXX0.QX4iUJ00rh1B0PXwyBedqQVbEHR6C72Yp0a9DpM5UIg","author_name":"messenger-lame","author_url":"https:\/\/www.deviantart.com\/messenger-lame","provider_name":"DeviantArt","provider_url":"https:\/\/www.deviantart.com","safety":"nonadult","pubdate":"2016-10-12T05:03:58-07:00","community":{"statistics":{"_attributes":{"views":1612,"favorites":313,"comments":9,"downloads":71}}},"tags":"rem, re_zero_kara_hajimeru_isekai_seikatsu","copyright":{"_attributes":{"url":"https:\/\/www.deviantart.com\/messenger-lame","year":"2016","entity":"messenger-lame"}},"width":"750","height":"1000","imagetype":"png","thumbnail_url":"https:\/\/images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com\/f\/9afa7937-381f-47f0-a8bc-40b9db1faad1\/dakuh8p-aea3fc1c-c06e-466b-88ba-d27be8e164e9.png\/v1\/fit\/w_300,h_900,strp\/rem_by_messenger_lame_dakuh8p-300w.png?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9MTAwMCIsInBhdGgiOiJcL2ZcLzlhZmE3OTM3LTM4MWYtNDdmMC1hOGJjLTQwYjlkYjFmYWFkMVwvZGFrdWg4cC1hZWEzZmMxYy1jMDZlLTQ2NmItODhiYS1kMjdiZThlMTY0ZTkucG5nIiwid2lkdGgiOiI8PTc1MCJ9XV0sImF1ZCI6WyJ1cm46c2VydmljZTppbWFnZS5vcGVyYXRpb25zIl19._gC85PXUst0iqKJCZZSUVonW0YRr5GHj2Qen_Q_95Og","thumbnail_width":300,"thumbnail_height":400,"thumbnail_url_150":"https:\/\/images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com\/f\/9afa7937-381f-47f0-a8bc-40b9db1faad1\/dakuh8p-aea3fc1c-c06e-466b-88ba-d27be8e164e9.png\/v1\/fit\/w_150,h_150,strp\/rem_by_messenger_lame_dakuh8p-150.png?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9MTAwMCIsInBhdGgiOiJcL2ZcLzlhZmE3OTM3LTM4MWYtNDdmMC1hOGJjLTQwYjlkYjFmYWFkMVwvZGFrdWg4cC1hZWEzZmMxYy1jMDZlLTQ2NmItODhiYS1kMjdiZThlMTY0ZTkucG5nIiwid2lkdGgiOiI8PTc1MCJ9XV0sImF1ZCI6WyJ1cm46c2VydmljZTppbWFnZS5vcGVyYXRpb25zIl19._gC85PXUst0iqKJCZZSUVonW0YRr5GHj2Qen_Q_95Og","thumbnail_url_200h":"https:\/\/images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com\/f\/9afa7937-381f-47f0-a8bc-40b9db1faad1\/dakuh8p-aea3fc1c-c06e-466b-88ba-d27be8e164e9.png\/v1\/fill\/w_150,h_200,strp\/rem_by_messenger_lame_dakuh8p-200h.png?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9MTAwMCIsInBhdGgiOiJcL2ZcLzlhZmE3OTM3LTM4MWYtNDdmMC1hOGJjLTQwYjlkYjFmYWFkMVwvZGFrdWg4cC1hZWEzZmMxYy1jMDZlLTQ2NmItODhiYS1kMjdiZThlMTY0ZTkucG5nIiwid2lkdGgiOiI8PTc1MCJ9XV0sImF1ZCI6WyJ1cm46c2VydmljZTppbWFnZS5vcGVyYXRpb25zIl19._gC85PXUst0iqKJCZZSUVonW0YRr5GHj2Qen_Q_95Og","thumbnail_width_200h":150,"thumbnail_height_200h":200}

644
tests/fixture/Iwara/images.html vendored Normal file
View File

@ -0,0 +1,644 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<title>鏡音りん18歳 | Iwara</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="x-dns-prefetch-control" content="on" />
<link rel="dns-prefetch" href="//i.iwara.tv" />
<!--[if IE 9]>
<link rel="prefetch" href="//i.iwara.tv" />
<![endif]-->
<meta name="Generator" content="Drupal 7 (http://drupal.org)" />
<link rel="canonical" href="https://iwara.tv/images/%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3" />
<link rel="canonical" href="/images/%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3" />
<link rel="shortlink" href="/node/67589" />
<link rel="shortcut icon" href="https://iwara.tv/misc/favicon.ico" type="image/vnd.microsoft.icon" />
<style type="text/css" media="all">
@import url("https://iwara.tv/modules/system/system.base.css?pv5bfq");
@import url("https://iwara.tv/modules/system/system.menus.css?pv5bfq");
@import url("https://iwara.tv/modules/system/system.messages.css?pv5bfq");
@import url("https://iwara.tv/modules/system/system.theme.css?pv5bfq");
</style>
<style type="text/css" media="all">
@import url("https://iwara.tv/modules/comment/comment.css?pv5bfq");
@import url("https://iwara.tv/modules/field/theme/field.css?pv5bfq");
@import url("https://iwara.tv/modules/node/node.css?pv5bfq");
@import url("https://iwara.tv/modules/user/user.css?pv5bfq");
@import url("https://iwara.tv/modules/forum/forum.css?pv5bfq");
@import url("https://iwara.tv/sites/all/modules/contrib/views/css/views.css?pv5bfq");
</style>
<style type="text/css" media="all">
@import url("https://iwara.tv/sites/all/modules/contrib/ctools/css/ctools.css?pv5bfq");
@import url("https://iwara.tv/sites/all/modules/contrib/video/css/video.css?pv5bfq");
@import url("https://iwara.tv/modules/locale/locale.css?pv5bfq");
</style>
<style type="text/css" media="all">
@import url("https://iwara.tv/sites/all/themes/main/css/main.css?pv5bfq");
@import url("https://iwara.tv/sites/all/themes/main/lib/video-js/video-js.min.css?pv5bfq");
@import url("https://iwara.tv/sites/all/themes/main/lib/videojs-loopbutton/videojs.loopbutton.css?pv5bfq");
@import url("https://iwara.tv/sites/all/themes/main/lib/videojs-resolution-switcher/videojs-resolution-switcher.css?pv5bfq");
@import url("https://iwara.tv/sites/all/themes/main/lib/slick/slick.css?pv5bfq");
@import url("https://iwara.tv/sites/all/themes/main/lib/slick/slick-theme.css?pv5bfq");
</style>
<script type="text/javascript">
<!--//--><![CDATA[//><!--
window.google_analytics_domain_name = ".iwara.tv";window.google_analytics_uacct = "UA-37410039-11";
//--><!]]>
</script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
<!--//--><![CDATA[//><!--
window.jQuery || document.write("<script src='/sites/all/modules/contrib/jquery_update/replace/jquery/1.10/jquery.min.js'>\x3C/script>")
//--><!]]>
</script>
<script type="text/javascript" src="https://iwara.tv/misc/jquery.once.js?v=1.2"></script>
<script type="text/javascript" src="https://iwara.tv/misc/drupal.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/modules/contrib/jquery_update/replace/ui/external/jquery.cookie.js?v=67fb34f6a866c40d0570"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/modules/contrib/jquery_update/replace/misc/jquery.form.min.js?v=2.69"></script>
<script type="text/javascript" src="https://iwara.tv/misc/ajax.js?v=7.64"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/modules/contrib/jquery_update/js/jquery_update.js?v=0.0.1"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/modules/custom/user_management/user_management.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/default/files/languages/ja_InHMwhlJnpgeRQNauiTX5Z8i27Ho8-JuYjQwQykOyag.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/modules/contrib/video/js/video.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/modules/contrib/views/js/base.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/misc/progress.js?v=7.64"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/modules/contrib/google_analytics/googleanalytics.js?pv5bfq"></script>
<script type="text/javascript">
<!--//--><![CDATA[//><!--
(function(i,s,o,g,r,a,m){i["GoogleAnalyticsObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,"script","https://www.google-analytics.com/analytics.js","ga");ga("create", "UA-37410039-11", {"cookieDomain":".iwara.tv"});ga("set", "anonymizeIp", true);ga("send", "pageview");
//--><!]]>
</script>
<script type="text/javascript" src="https://iwara.tv/sites/all/modules/contrib/views_load_more/views_load_more.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/modules/contrib/views/js/ajax_view.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/js/bootstrap.min.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/js/flat-ui.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/js/js.cookie.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/js/jquery.truncate.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/lib/video-js/video.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/lib/videojs.hotkeys.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/lib/videojs.persistvolume.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/lib/videojs-loopbutton/videojs.loopbutton.min.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/lib/videojs-resolution-switcher/videojs-resolution-switcher.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/lib/slick/slick.min.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/lib/writeCapture.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/lib/jquery.writeCapture.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/sites/all/themes/main/js/main.js?pv5bfq"></script>
<script type="text/javascript">
<!--//--><![CDATA[//><!--
jQuery.extend(Drupal.settings, {"basePath":"\/","pathPrefix":"","ajaxPageState":{"theme":"main","theme_token":"rbkG9UcbZ-jrWv01QHFcevqE_zrYWCoZ0Y7672kB-zk","jquery_version":"1.10","js":{"sites\/all\/modules\/custom\/extra_content\/extra_content.js":1,"modules\/statistics\/statistics.js":1,"0":1,"\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/1.10.2\/jquery.min.js":1,"1":1,"misc\/jquery.once.js":1,"misc\/drupal.js":1,"sites\/all\/modules\/contrib\/jquery_update\/replace\/ui\/external\/jquery.cookie.js":1,"sites\/all\/modules\/contrib\/jquery_update\/replace\/misc\/jquery.form.min.js":1,"misc\/ajax.js":1,"sites\/all\/modules\/contrib\/jquery_update\/js\/jquery_update.js":1,"sites\/all\/modules\/custom\/user_management\/user_management.js":1,"public:\/\/languages\/ja_InHMwhlJnpgeRQNauiTX5Z8i27Ho8-JuYjQwQykOyag.js":1,"sites\/all\/modules\/contrib\/video\/js\/video.js":1,"sites\/all\/modules\/contrib\/views\/js\/base.js":1,"misc\/progress.js":1,"sites\/all\/modules\/contrib\/google_analytics\/googleanalytics.js":1,"2":1,"sites\/all\/modules\/contrib\/views_load_more\/views_load_more.js":1,"sites\/all\/modules\/contrib\/views\/js\/ajax_view.js":1,"sites\/all\/themes\/main\/js\/bootstrap.min.js":1,"sites\/all\/themes\/main\/js\/flat-ui.js":1,"sites\/all\/themes\/main\/js\/js.cookie.js":1,"sites\/all\/themes\/main\/js\/jquery.truncate.js":1,"sites\/all\/themes\/main\/lib\/video-js\/video.js":1,"sites\/all\/themes\/main\/lib\/videojs.hotkeys.js":1,"sites\/all\/themes\/main\/lib\/videojs.persistvolume.js":1,"sites\/all\/themes\/main\/lib\/videojs-loopbutton\/videojs.loopbutton.min.js":1,"sites\/all\/themes\/main\/lib\/videojs-resolution-switcher\/videojs-resolution-switcher.js":1,"sites\/all\/themes\/main\/lib\/slick\/slick.min.js":1,"sites\/all\/themes\/main\/lib\/writeCapture.js":1,"sites\/all\/themes\/main\/lib\/jquery.writeCapture.js":1,"sites\/all\/themes\/main\/js\/main.js":1},"css":{"modules\/system\/system.base.css":1,"modules\/system\/system.menus.css":1,"modules\/system\/system.messages.css":1,"modules\/system\/system.theme.css":1,"modules\/comment\/comment.css":1,"modules\/field\/theme\/field.css":1,"modules\/node\/node.css":1,"modules\/user\/user.css":1,"modules\/forum\/forum.css":1,"sites\/all\/modules\/contrib\/views\/css\/views.css":1,"sites\/all\/modules\/contrib\/ctools\/css\/ctools.css":1,"sites\/all\/modules\/contrib\/video\/css\/video.css":1,"modules\/locale\/locale.css":1,"sites\/all\/themes\/main\/css\/main.css":1,"sites\/all\/themes\/main\/lib\/video-js\/video-js.min.css":1,"sites\/all\/themes\/main\/lib\/videojs-loopbutton\/videojs.loopbutton.css":1,"sites\/all\/themes\/main\/lib\/videojs-resolution-switcher\/videojs-resolution-switcher.css":1,"sites\/all\/themes\/main\/lib\/slick\/slick.css":1,"sites\/all\/themes\/main\/lib\/slick\/slick-theme.css":1}},"views":{"ajax_path":"\/views\/ajax","ajaxViews":{"views_dom_id:3db0f7819590f4cdd92bcf970946e86c":{"view_name":"likes","view_display_id":"block","view_args":"67589","view_path":"node\/67589","view_base_path":null,"view_dom_id":"3db0f7819590f4cdd92bcf970946e86c","pager_element":"1"},"views_dom_id:299ba1e6aebe291ab75faaba85866eb4":{"view_name":"likes","view_display_id":"block","view_args":"67589","view_path":"node\/67589","view_base_path":null,"view_dom_id":"299ba1e6aebe291ab75faaba85866eb4","pager_element":"1"}}},"urlIsAjaxTrusted":{"\/views\/ajax":true},"googleanalytics":{"trackOutbound":1,"trackMailto":1,"trackDomainMode":1},"theme":{"nid":67589},"statistics":{"data":{"nid":"67589"},"url":"\/modules\/statistics\/statistics.php"}});
//--><!]]>
</script>
<style>
.extra-content-block {
position: relative;
}
.extra-content-block img {
top: 0 !important;
left: 0 !important;
}
body.page-node-254112 {
background-image: url('/sites/all/themes/main/img/great-thread.gif');
}
</style>
</head>
<body class="html not-front not-logged-in no-sidebars page-node page-node- page-node-67589 node-type-image i18n-ja" >
<div id="wrapper">
<header>
<div class="menu-bar">
<div class="container">
<div>
<a href="/" class="pull-left logo">
<img src="/sites/all/themes/main/img/logo.png" />
<span class="site-name visible-xs">Iwara</span>
</a>
<a href="#" id="hamburger-toggle" class="pull-right visible-xs"><i class="glyphicon glyphicon-list"></i></a>
</div>
<div class="top-menu hidden-xs">
<div class="region region-header">
<div id="block-system-main-menu" class="block block-system block-menu">
<div class="content">
<ul class="menu nav nav-pills pull-left"><li title=""><a href="/" title="">Home</a></li>
<li class="leaf"><a href="/videos">動画</a></li>
<li class="active active"><a href="/images" class="active-trail active">画像</a></li>
<li title=""><a href="/forum" title="">フォーラム</a></li>
</ul> </div>
</div>
</div>
<!-- User -->
<div id="user-links" class="pull-right">
<a href="/search" class="search-link"><span class="fui-search"></span></a>
<a href="/user/login?destination=node/67589" class="btn btn-sm btn-primary" title="Log in to your account">ログイン</a>
<a href="/user/register" class="btn btn-sm btn-success" title="Create a new account">Join</a>
<a href="/section/ecchi?destination=node/67589" class="btn btn-sm btn-danger section-btn"><span class="glyphicon glyphicon-heart"></span> Ecchi</a>
</div>
</div>
</div>
</div>
</header>
<section id="content">
<div class="container" style="position: relative">
<div class="region region-before-content">
<div id="block-extra-content-extra-content-block-1" class="block block-extra-content">
<div class="content">
<div class="extra-content-block" data-type="wide" data-bid="1"></div> </div>
</div>
</div>
<div class="region region-content">
<div id="block-system-main" class="block block-system">
<div class="content">
<div id="node-67589" class="node node-image node-full clearfix col-sm-9">
<div class="content">
<div class="field field-name-field-images field-type-file field-label-hidden"><div class="field-items"><div class="field-item even"><a href="//i.iwara.tv/sites/default/files/photos/jing_yin_rin18sui_a.png" target="_blank"><img src="//i.iwara.tv/sites/default/files/styles/large/public/photos/jing_yin_rin18sui_a.png?itok=seN2Lu5g" width="940" height="480" alt="" /></a></div><div class="field-item odd"><a href="//i.iwara.tv/sites/default/files/photos/jing_yin_rin18sui_b.png" target="_blank"><img src="//i.iwara.tv/sites/default/files/styles/large/public/photos/jing_yin_rin18sui_b.png?itok=5a29f-Vr" width="940" height="480" alt="" /></a></div><div class="field-item even"><a href="//i.iwara.tv/sites/default/files/photos/jing_yin_rin18sui_c.png" target="_blank"><img src="//i.iwara.tv/sites/default/files/styles/large/public/photos/jing_yin_rin18sui_c.png?itok=9WCbVgGu" width="940" height="480" alt="" /></a></div><div class="field-item odd"><a href="//i.iwara.tv/sites/default/files/photos/jing_yin_rin18sui_d.png" target="_blank"><img src="//i.iwara.tv/sites/default/files/styles/large/public/photos/jing_yin_rin18sui_d.png?itok=03bH-wAL" width="940" height="480" alt="" /></a></div><div class="field-item even"><a href="//i.iwara.tv/sites/default/files/photos/jing_yin_rin18sui_e.png" target="_blank"><img src="//i.iwara.tv/sites/default/files/styles/large/public/photos/jing_yin_rin18sui_e.png?itok=2tbuVk1X" width="940" height="480" alt="" /></a></div><div class="field-item odd"><a href="//i.iwara.tv/sites/default/files/photos/jing_yin_rin18sui_f.png" target="_blank"><img src="//i.iwara.tv/sites/default/files/styles/large/public/photos/jing_yin_rin18sui_f.png?itok=4XwfTgFV" width="940" height="480" alt="" /></a></div><div class="field-item even"><a href="//i.iwara.tv/sites/default/files/photos/jing_yin_rin18sui_g.png" target="_blank"><img src="//i.iwara.tv/sites/default/files/styles/large/public/photos/jing_yin_rin18sui_g.png?itok=CXsigpLq" width="940" height="480" alt="" /></a></div><div class="field-item odd"><a href="//i.iwara.tv/sites/default/files/photos/jing_yin_rin18sui_h.png" target="_blank"><img src="//i.iwara.tv/sites/default/files/styles/large/public/photos/jing_yin_rin18sui_h.png?itok=h14hWTK6" width="940" height="480" alt="" /></a></div></div></div>
<div class="node-info">
<div class="submitted">
<span class="hidden-xs">
<div class="user-picture">
<a href="/users/tonjiru-lion" title="ユーザープロフィールの表示"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/avatars/7177.jpg?itok=M_gYMGc0" width="70" height="70" alt="ユーザー Tonjiru Lion の写真" title="ユーザー Tonjiru Lion の写真" /></a> </div>
</span>
<h1 class="title">鏡音りん18歳</h1>
作成者:<a href="/users/tonjiru-lion" title="ユーザープロフィールの表示" class="username">Tonjiru Lion</a> 作成日:2016-05-28 21:04 </div>
<div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><p>今回はあんまエロくないです。</p>
</div></div></div> <div class="field field-name-field-image-categories field-type-taxonomy-term-reference field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/images?f%5B0%5D=field_image_categories%3A5">Vocaloid</a></div></div></div> <div class="node-views"><i class="glyphicon glyphicon-eye-open"></i> 12,542</div>
<div class="share-icons">
<a class="symbol" target="_blank" href="http://twitter.com/home?status=%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3+https%3A%2F%2Fiwara.tv%2Fimages%2F%25E9%258F%25A1%25E9%259F%25B3%25E3%2582%258A%25E3%2582%259318%25E6%25AD%25B3" title="Share on Twitter">&#xe086;</a>
<a class="symbol" target="_blank" href="http://www.facebook.com/share.php?u=https%3A%2F%2Fiwara.tv%2Fimages%2F%25E9%258F%25A1%25E9%259F%25B3%25E3%2582%258A%25E3%2582%259318%25E6%25AD%25B3&amp;title=%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3" title="Share on Facebook">&#xe027;</a>
<a class="symbol" target="_blank" href="https://plus.google.com/share?url=https%3A%2F%2Fiwara.tv%2Fimages%2F%25E9%258F%25A1%25E9%259F%25B3%25E3%2582%258A%25E3%2582%259318%25E6%25AD%25B3" title="Share on Google+">&#xe039;</a>
<a class="symbol" target="_blank" href="http://www.reddit.com/submit?url=https%3A%2F%2Fiwara.tv%2Fimages%2F%25E9%258F%25A1%25E9%259F%25B3%25E3%2582%258A%25E3%2582%259318%25E6%25AD%25B3&amp;title=%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3" title="Share on Reddit">&#xe069;</a>
<a class="symbol" target="_blank" href="http://www.stumbleupon.com/submit?url=https%3A%2F%2Fiwara.tv%2Fimages%2F%25E9%258F%25A1%25E9%259F%25B3%25E3%2582%258A%25E3%2582%259318%25E6%25AD%25B3&amp;title=%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3" title="Share on StumbleUpon">&#xe083;</a>
</div> </div>
<div class="node-buttons">
</div>
</div>
<div class="col-sm-12">
<div id="comments" class="comment-wrapper has-comments">
<h2 class="title">
コメント数 6 </h2>
<a id="comment-37719"></a>
<div class="comment clearfix">
<div class="col-sm-2 user-avatar hidden-xs">
<div class="user-picture">
<a href="/users/makimaki" title="ユーザープロフィールの表示"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/pictures/picture-10965-1518366600.png?itok=ZMDNhxs8" width="70" height="70" alt="ユーザー MakiMaki の写真" title="ユーザー MakiMaki の写真" /></a> </div>
</div>
<div class="col-sm-10">
<div class="submitted">
作成者:<a href="/users/makimaki" title="ユーザープロフィールの表示" class="username">MakiMaki</a> 作成日:2016-05-29 19:40 </div>
<div class="content">
<div class="field field-name-comment-body field-type-text-long field-label-hidden"><div class="field-items"><div class="field-item even"><p>良いカスタムモデルですね<br />
ぶっちゃけ裸よりエロいです(*´ω`)</p>
</div></div></div> </div>
<ul class="links inline"><li class="comment_forbidden first last"><span>コメントを投稿するには<a href="/user/login?destination=node/67589%23comment-form">ログイン</a>または<a href="/user/register?destination=node/67589%23comment-form">ユーザー登録</a>を行ってください</span></li>
</ul> </div>
</div>
<a id="comment-42253"></a>
<div class="comment clearfix">
<div class="col-sm-2 user-avatar hidden-xs">
<div class="user-picture">
<a href="/users/%E3%83%A0%E3%83%AA%E3%83%A0%E3%83%AA%E3%83%A0%E3%83%AA" title="ユーザープロフィールの表示"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/pictures/picture-42946-1471620521.jpg?itok=jh7viI8A" width="70" height="70" alt="ユーザー ムリムリムリ の写真" title="ユーザー ムリムリムリ の写真" /></a> </div>
</div>
<div class="col-sm-10">
<div class="submitted">
作成者:<a href="/users/%E3%83%A0%E3%83%AA%E3%83%A0%E3%83%AA%E3%83%A0%E3%83%AA" title="ユーザープロフィールの表示" class="username">ムリムリムリ</a> 作成日:2016-06-13 01:42 </div>
<div class="content">
<div class="field field-name-comment-body field-type-text-long field-label-hidden"><div class="field-items"><div class="field-item even"><p>可愛いと思います!</p>
</div></div></div> </div>
<ul class="links inline"><li class="comment_forbidden first last"><span>コメントを投稿するには<a href="/user/login?destination=node/67589%23comment-form">ログイン</a>または<a href="/user/register?destination=node/67589%23comment-form">ユーザー登録</a>を行ってください</span></li>
</ul> </div>
</div>
<a id="comment-56348"></a>
<div class="comment clearfix">
<div class="col-sm-2 user-avatar hidden-xs">
<div class="user-picture">
<a href="/users/g3-3p" title="ユーザープロフィールの表示"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/default-avatar.png?itok=ZB6hu7xh" width="70" height="70" alt="ユーザー g3-3p の写真" title="ユーザー g3-3p の写真" /></a> </div>
</div>
<div class="col-sm-10">
<div class="submitted">
作成者:<a href="/users/g3-3p" title="ユーザープロフィールの表示" class="username">g3-3p</a> 作成日:2016-07-16 19:32 </div>
<div class="content">
<div class="field field-name-comment-body field-type-text-long field-label-hidden"><div class="field-items"><div class="field-item even"><p>これくらいの微エロも捗りますね</p>
</div></div></div> </div>
<ul class="links inline"><li class="comment_forbidden first last"><span>コメントを投稿するには<a href="/user/login?destination=node/67589%23comment-form">ログイン</a>または<a href="/user/register?destination=node/67589%23comment-form">ユーザー登録</a>を行ってください</span></li>
</ul> </div>
</div>
<a id="comment-73682"></a>
<div class="comment clearfix">
<div class="col-sm-2 user-avatar hidden-xs">
<div class="user-picture">
<a href="/users/%E5%A4%8F%E7%82%89%E5%86%AC%E6%89%87" title="ユーザープロフィールの表示"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/default-avatar.png?itok=ZB6hu7xh" width="70" height="70" alt="ユーザー 夏炉冬扇 の写真" title="ユーザー 夏炉冬扇 の写真" /></a> </div>
</div>
<div class="col-sm-10">
<div class="submitted">
作成者:<a href="/users/%E5%A4%8F%E7%82%89%E5%86%AC%E6%89%87" title="ユーザープロフィールの表示" class="username">夏炉冬扇</a> 作成日:2016-08-23 13:58 </div>
<div class="content">
<div class="field field-name-comment-body field-type-text-long field-label-hidden"><div class="field-items"><div class="field-item even"><p>これはけしからん18歳</p>
</div></div></div> </div>
<ul class="links inline"><li class="comment_forbidden first last"><span>コメントを投稿するには<a href="/user/login?destination=node/67589%23comment-form">ログイン</a>または<a href="/user/register?destination=node/67589%23comment-form">ユーザー登録</a>を行ってください</span></li>
</ul> </div>
</div>
<a id="comment-112401"></a>
<div class="comment clearfix">
<div class="col-sm-2 user-avatar hidden-xs">
<div class="user-picture">
<a href="/users/calinanon" title="ユーザープロフィールの表示"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/default-avatar.png?itok=ZB6hu7xh" width="70" height="70" alt="ユーザー UnknownAnon の写真" title="ユーザー UnknownAnon の写真" /></a> </div>
</div>
<div class="col-sm-10">
<div class="submitted">
作成者:<a href="/users/calinanon" title="ユーザープロフィールの表示" class="username">UnknownAnon</a> 作成日:2016-11-19 23:38 </div>
<div class="content">
<div class="field field-name-comment-body field-type-text-long field-label-hidden"><div class="field-items"><div class="field-item even"><p>That is Nice!</p>
</div></div></div> </div>
<ul class="links inline"><li class="comment_forbidden first last"><span>コメントを投稿するには<a href="/user/login?destination=node/67589%23comment-form">ログイン</a>または<a href="/user/register?destination=node/67589%23comment-form">ユーザー登録</a>を行ってください</span></li>
</ul> </div>
</div>
<a id="comment-469660"></a>
<div class="comment clearfix">
<div class="col-sm-2 user-avatar hidden-xs">
<div class="user-picture">
<a href="/users/velveltia" title="ユーザープロフィールの表示"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/pictures/picture-284975-1526661952.jpg?itok=r07_SvI2" width="70" height="70" alt="ユーザー velveltia の写真" title="ユーザー velveltia の写真" /></a> </div>
</div>
<div class="col-sm-10">
<div class="submitted">
作成者:<a href="/users/velveltia" title="ユーザープロフィールの表示" class="username">velveltia</a> 作成日:2018-10-13 11:35 </div>
<div class="content">
<div class="field field-name-comment-body field-type-text-long field-label-hidden"><div class="field-items"><div class="field-item even"><p>Lovely! I wanna make her videos!! plz</p>
</div></div></div> </div>
<ul class="links inline"><li class="comment_forbidden first last"><span>コメントを投稿するには<a href="/user/login?destination=node/67589%23comment-form">ログイン</a>または<a href="/user/register?destination=node/67589%23comment-form">ユーザー登録</a>を行ってください</span></li>
</ul> </div>
</div>
</div> </div>
</div>
<div class="col-sm-3 sidebar">
<div id="block-extra-content-extra-content-block-3" class="block block-extra-content">
<div class="content">
<div class="extra-content-block" data-type="tall" data-bid="3"></div> </div>
</div>
<div id="block-views-likes-block" class="block block-views">
<h2>Liked by</h2>
<div class="content">
<div class="view view-likes view-id-likes view-display-id-block view-dom-id-299ba1e6aebe291ab75faaba85866eb4">
<div class="view-content">
<div class="views-row views-row-1 views-row-odd views-row-first">
<div class="views-field views-field-picture"> <div class="field-content"><a href="/users/icarus3901"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/pictures/picture-99167-1479188321_0.jpg?itok=5jMmxEGl" width="70" height="70" alt="ユーザー icarus3901 の写真" /></a></div> </div>
<div class="views-field views-field-name"> <span class="field-content"><a href="/users/icarus3901" title="ユーザープロフィールの表示" class="username">icarus3901</a></span> </div>
<div class="views-field views-field-timestamp"> <span class="field-content"><em class="placeholder">4日</em></span> </div> </div>
<div class="views-row views-row-2 views-row-even">
<div class="views-field views-field-picture"> <div class="field-content"><a href="/users/13921944947"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/default-avatar.png?itok=ZB6hu7xh" width="70" height="70" alt="ユーザー 13921944947 の写真" /></a></div> </div>
<div class="views-field views-field-name"> <span class="field-content"><a href="/users/13921944947" title="ユーザープロフィールの表示" class="username">13921944947</a></span> </div>
<div class="views-field views-field-timestamp"> <span class="field-content"><em class="placeholder">3週</em></span> </div> </div>
<div class="views-row views-row-3 views-row-odd">
<div class="views-field views-field-picture"> <div class="field-content"><a href="/users/%E6%B0%B8%E8%BF%9C%E7%9A%84yc"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/default-avatar.png?itok=ZB6hu7xh" width="70" height="70" alt="ユーザー 永远的YC の写真" /></a></div> </div>
<div class="views-field views-field-name"> <span class="field-content"><a href="/users/%E6%B0%B8%E8%BF%9C%E7%9A%84yc" title="ユーザープロフィールの表示" class="username">永远的YC</a></span> </div>
<div class="views-field views-field-timestamp"> <span class="field-content"><em class="placeholder">1ヶ月</em></span> </div> </div>
<div class="views-row views-row-4 views-row-even">
<div class="views-field views-field-picture"> <div class="field-content"><a href="/users/misakasang"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/default-avatar.png?itok=ZB6hu7xh" width="70" height="70" alt="ユーザー MisakaSang の写真" /></a></div> </div>
<div class="views-field views-field-name"> <span class="field-content"><a href="/users/misakasang" title="ユーザープロフィールの表示" class="username">MisakaSang</a></span> </div>
<div class="views-field views-field-timestamp"> <span class="field-content"><em class="placeholder">1ヶ月</em></span> </div> </div>
<div class="views-row views-row-5 views-row-odd">
<div class="views-field views-field-picture"> <div class="field-content"><a href="/users/tsk-ij04n"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/default-avatar.png?itok=ZB6hu7xh" width="70" height="70" alt="ユーザー TSK-ij04n の写真" /></a></div> </div>
<div class="views-field views-field-name"> <span class="field-content"><a href="/users/tsk-ij04n" title="ユーザープロフィールの表示" class="username">TSK-ij04n</a></span> </div>
<div class="views-field views-field-timestamp"> <span class="field-content"><em class="placeholder">7ヶ月</em></span> </div> </div>
<div class="views-row views-row-6 views-row-even views-row-last">
<div class="views-field views-field-picture"> <div class="field-content"><a href="/users/ramaro"><img src="//i.iwara.tv/sites/default/files/styles/avatar_small/public/pictures/picture-8092-1531758452.png?itok=7CW_KraP" width="70" height="70" alt="ユーザー ramaro の写真" /></a></div> </div>
<div class="views-field views-field-name"> <span class="field-content"><a href="/users/ramaro" title="ユーザープロフィールの表示" class="username">ramaro</a></span> </div>
<div class="views-field views-field-timestamp"> <span class="field-content"><em class="placeholder">9ヶ月</em></span> </div> </div>
</div>
<div class="item-list"><ul class="pager pager-load-more"><li class="pager-next first last"><a href="/images/%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3?page=0%2C1">Show more</a></li>
</ul></div>
</div> </div>
</div>
<div id="block-views-search-block-1" class="block block-views">
<h2>More like this</h2>
<div class="content">
<div class="view view-search view-id-search view-display-id-block_1 view-dom-id-bb0dec2f11c5548a0e00114d44c58673">
<div class="view-content">
<div class="views-responsive-grid views-responsive-grid-horizontal views-columns-2">
<div class="views-row row views-row-1 views-row-first">
<div class="views-column col-sm-6 views-column-1 views-column-first">
<div id="node-26903" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="阿武隈">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 35</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26903"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/144000862061222f.png?itok=9a8JSlmy" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
<div class="views-column col-sm-6 views-column-2 views-column-last">
<div id="node-26913" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="大鳥居">
<div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26913"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/1440844307f07d19.jpg?itok=9IqFIae0" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
</div>
<div class="views-row row views-row-2">
<div class="views-column col-sm-6 views-column-1 views-column-first">
<div id="node-26914" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="てつのくじら館">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 4</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26914"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/14408444339cf8ce.jpg?itok=w_ACmY4t" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
<div class="views-column col-sm-6 views-column-2 views-column-last">
<div id="node-26915" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="潜水艦あきしおの発令所">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 1</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26915"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/1440844725c1f47b.jpg?itok=GAV4jF-U" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
</div>
<div class="views-row row views-row-3">
<div class="views-column col-sm-6 views-column-1 views-column-first">
<div id="node-26916" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="潜水艦あきしおの魚雷発射所">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 2</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26916"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/14408449874d49d7.jpg?itok=j-9Jygsi" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
<div class="views-column col-sm-6 views-column-2 views-column-last">
<div id="node-26917" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="潜水艦あきしおの潜望鏡">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 1</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26917"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/14408450891e04bf.jpg?itok=VJ79mzh_" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
</div>
<div class="views-row row views-row-4">
<div class="views-column col-sm-6 views-column-1 views-column-first">
<div id="node-26918" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="戦艦 陸奥の主錨">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 2</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26918"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/1440845323998c3f.jpg?itok=sGyJF6jt" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
<div class="views-column col-sm-6 views-column-2 views-column-last">
<div id="node-26919" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="戦艦 陸奥の主砲">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 2</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26919"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/144084542421cdc9.jpg?itok=eTVTfKA_" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
</div>
<div class="views-row row views-row-5">
<div class="views-column col-sm-6 views-column-1 views-column-first">
<div id="node-26920" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="戦艦 陸奥のスクリュー">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 3</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26920"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/1440845506461ad3.jpg?itok=Gl3zL796" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
<div class="views-column col-sm-6 views-column-2 views-column-last">
<div id="node-26921" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="戦艦 大和の巨大模型">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 3</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26921"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/1440845867beed12.jpg?itok=TLjrsw5W" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
</div>
<div class="views-row row views-row-6">
<div class="views-column col-sm-6 views-column-1 views-column-first">
<div id="node-26922" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="戦艦 長門の軍艦旗">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 7</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26922"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/144084593641bb06.jpg?itok=_vd6homo" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
<div class="views-column col-sm-6 views-column-2 views-column-last">
<div id="node-26923" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="零式艦上戦闘機">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 4</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26923"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/14408461449d9411.jpg?itok=xdyThTxi" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
</div>
<div class="views-row row views-row-7">
<div class="views-column col-sm-6 views-column-1 views-column-first">
<div id="node-26924" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="砲弾">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 4</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26924"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/14408463334e7eb6.jpg?itok=j9lzqoeN" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
<div class="views-column col-sm-6 views-column-2 views-column-last">
<div id="node-26925" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="戦艦 大和の巨大模型2">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 3</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/26925"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/1440846468344aa6.jpg?itok=EcogP7eH" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
</div>
<div class="views-row row views-row-8 views-row-last">
<div class="views-column col-sm-6 views-column-1 views-column-first">
<div id="node-27079" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="護衛艦 いせ">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 1</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/27079"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/144283604013e383.jpg?itok=IoWmSlTe" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
<div class="views-column col-sm-6 views-column-2 views-column-last">
<div id="node-27080" class="node node-image node-sidebar_teaser clearfix" data-toggle="tooltip" data-placement="top" title="護衛艦 せんだい">
<div>
<div class="icon-bg">
<div class="right-icon likes-icon"><i class="glyphicon glyphicon-heart"></i> 3</div>
</div>
<div class="field field-name-field-thumbnail field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><a href="/node/27080"><img src="//i.iwara.tv/sites/default/files/styles/sidebar_preview/public/photos/imported/1442836502a92b44.jpg?itok=Zm9MUseh" width="141" height="84" /></a></div></div></div> </div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
<footer>
<div class="container">
<div class="region region-footer">
<div id="block-locale-language" class="block block-locale">
<h2>言語</h2>
<div class="content">
<ul class="language-switcher-locale-session"><li class="en first active"><a href="/images/%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3?language=en" class="language-link active" xml:lang="en">English</a></li>
<li class="ja active"><a href="/images/%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3" class="language-link session-active active" xml:lang="ja">日本語</a></li>
<li class="zh-hans active"><a href="/images/%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3?language=zh-hans" class="language-link active" xml:lang="zh-hans">简体中文</a></li>
<li class="de last active"><a href="/images/%E9%8F%A1%E9%9F%B3%E3%82%8A%E3%82%9318%E6%AD%B3?language=de" class="language-link active" xml:lang="de">Deutsch</a></li>
</ul> </div>
</div>
<div id="block-menu-menu-footer" class="block block-menu">
<h2>リンク</h2>
<div class="content">
<ul class="menu nav nav-pills pull-left"><li title="For contacting us"><a href="//www.iwara.tv/contact" title="For contacting us">Contact Us</a></li>
<li title=""><a href="https://discord.gg/V62x3tm" title="">Discord</a></li>
<li class="leaf"><a href="/playlists">Playlists</a></li>
<li title=""><a href="//ecchi.iwara.tv/forums/important-website-rules-and-conduct" title="">Rules</a></li>
<li title=""><a href="/users" title="">Users</a></li>
</ul> </div>
</div>
<div id="block-forum-new" class="block block-forum">
<h2>新しいフォーラムトピック</h2>
<div class="content">
<div class="item-list"><ul><li class="first"><a href="/forums/help-please-where-can-i-find-video">help please. where can I find this video?</a></li>
<li><a href="/forums/looking-mmd-r18-discord">looking for mmd r18 discord </a></li>
<li><a href="/forums/looking-male-chastity-model">Looking for a male chastity model</a></li>
<li><a href="/forums/spanish-forum-link-or-help" title="コメント数 2">spanish forum link or help</a></li>
<li class="last"><a href="/forums/how-fix-problem-motion" title="コメント数 2">How to fix this problem with a motion?</a></li>
</ul></div><div class="more-link"><a href="/forum" title="最新のフォーラムトピックを読む">続き</a></div> </div>
</div>
</div>
<div class="copyright">&copy; Iwara 2019</div>
</div>
</footer> <script type="text/javascript" src="https://iwara.tv/sites/all/modules/custom/extra_content/extra_content.js?pv5bfq"></script>
<script type="text/javascript" src="https://iwara.tv/modules/statistics/statistics.js?pv5bfq"></script>
</body>
</html>

1711
tests/fixture/Iwara/video.html vendored Normal file

File diff suppressed because it is too large Load Diff

1013
tests/fixture/Iwara/youtube.html vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1675
tests/fixture/Toranoana/testJoshi.html vendored Normal file

File diff suppressed because it is too large Load Diff

1588
tests/fixture/Toranoana/testJoshiD.html vendored Normal file

File diff suppressed because it is too large Load Diff

1738
tests/fixture/Toranoana/testJoshiR.html vendored Normal file

File diff suppressed because it is too large Load Diff

1696
tests/fixture/Toranoana/testJoshiRD.html vendored Normal file

File diff suppressed because it is too large Load Diff

1794
tests/fixture/Toranoana/testTora.html vendored Normal file

File diff suppressed because it is too large Load Diff

1674
tests/fixture/Toranoana/testToraD.html vendored Normal file

File diff suppressed because it is too large Load Diff

1744
tests/fixture/Toranoana/testToraR.html vendored Normal file

File diff suppressed because it is too large Load Diff

1626
tests/fixture/Toranoana/testToraRD.html vendored Normal file

File diff suppressed because it is too large Load Diff

1
tests/fixture/Xtube/test.json vendored Normal file
View File

@ -0,0 +1 @@
{"duration":"180","views":3146,"video_id":"RF4Nk-S774-","rating":"4.000","ratings":"1","title":"Homegrown Big Tits","description":"Dedicated to the fans of the beautiful amateur women with big natural tits. All user submitted - you can see big boob amateur hotties fucking and sucking as their tits bounce and sway.","url":"https:\/\/www.xtube.com\/video-watch\/homegrown-big-tits-18634762","embedCode":"https:\/\/www.xtube.com\/video-watch\/embedded\/homegrown-big-tits-18634762","default_thumb":"https:\/\/cdn5-s-hw-e5.xtube.com\/m=eSuQ8f\/videos\/201302\/07\/RF4Nk-S774-\/240X180\/1.jpg","thumb":"https:\/\/cdn5-s-hw-e5.xtube.com\/m=eSuQ8f\/videos\/201302\/07\/RF4Nk-S774-\/240X180\/1.jpg","publish_date":"2013-02-07 17:41:10","tags":{"1396":"bigtits","472012":"homeg"},"thumbs":[{"width":300,"height":210,"src":"https:\/\/cdn4-s-hw-e5.xtube.com\/m=eSK08f\/videos\/201302\/07\/RF4Nk-S774-\/240X180\/1.jpg"},{"width":300,"height":210,"src":"https:\/\/cdn4-s-hw-e5.xtube.com\/m=eSK08f\/videos\/201302\/07\/RF4Nk-S774-\/240X180\/2.jpg"},{"width":300,"height":210,"src":"https:\/\/cdn10-s-hw-e5.xtube.com\/m=eSK08f\/videos\/201302\/07\/RF4Nk-S774-\/240X180\/3.jpg"}]}

3270
yarn.lock

File diff suppressed because it is too large Load Diff