1 Commits

Author SHA1 Message Date
eai04191
8845eab5d9 Cypress test 2019-06-19 04:16:39 +09:00
66 changed files with 1990 additions and 16663 deletions

View File

@@ -1,9 +1,8 @@
version: 2.1
executors:
version: 2
jobs:
build:
docker:
- image: circleci/php:7.3-node-browsers
- image: circleci/php:7.1-node-browsers
environment:
APP_DEBUG: true
APP_ENV: testing
@@ -17,74 +16,37 @@ executors:
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-
save_composer:
steps:
- run: composer install -n --prefer-dist
- save_cache:
key: v1-dependencies-{{ checksum "composer.json" }}
paths:
- ./vendor
restore_npm:
steps:
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
- v1-dependencies-
save_npm:
steps:
- run: yarn install
- save_cache:
key: v1-dependencies-{{ checksum "package.json" }}
paths:
- ./node_modules
- ~/.yarn
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: yarn run prod
# Run linter
- run:
@@ -105,62 +67,7 @@ jobs:
- run:
command: |
mkdir -p /tmp/phpunit
./vendor/bin/phpunit --log-junit /tmp/phpunit/phpunit.xml --coverage-clover=/tmp/phpunit/coverage.xml
./vendor/bin/phpunit --log-junit /tmp/phpunit/phpunit.xml
when: always
- store_test_results:
path: /tmp/phpunit
- store_artifacts:
path: /tmp/phpunit/coverage.xml
# Upload coverage
- 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,21 +0,0 @@
root = true
[*]
indent_style = space
indent_size = 4
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[*.yml]
indent_size = 2
[*.json]
indent_size = 2
[composer.json]
indent_size = 4

View File

@@ -1,6 +1,6 @@
FROM node:10-jessie as node
FROM php:7.3-apache
FROM php:7.1-apache
ENV APACHE_DOCUMENT_ROOT /var/www/html/public
@@ -10,7 +10,6 @@ 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

@@ -50,7 +50,7 @@ docker-compose exec web php artisan migrate
6. ファイルに書き込めるように権限を設定します。
```
docker-compose exec web chown -R www-data /var/www/html/storage
docker-compose exec web chown -R www-data /var/www/html
```
7. アセットをビルドします。

View File

@@ -51,8 +51,6 @@ class CardController
$metadata->tags()->sync($tagIds);
}
$metadata->load('tags');
$response = response($metadata);
if (!config('app.debug')) {
$response = $response->setCache(['public' => true, 'max_age' => 86400]);

View File

@@ -109,6 +109,13 @@ 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');
@@ -116,7 +123,9 @@ SQL
$dailySum[$date->timestamp] = $data->count;
$yearlySum[$date->year] += $data->count;
$dowSum[$date->dayOfWeek] += $data->count;
$monthlySum[$yearAndMonth] = ($monthlySum[$yearAndMonth] ?? 0) + $data->count;
if (isset($monthlySum[$yearAndMonth])) {
$monthlySum[$yearAndMonth] += $data->count;
}
}
foreach ($groupByHour as $data) {
@@ -127,7 +136,8 @@ SQL
$graphData = [
'dailySum' => $dailySum,
'dowSum' => $dowSum,
'monthlySum' => $monthlySum,
'monthlyKey' => array_keys($monthlySum),
'monthlySum' => array_values($monthlySum),
'yearlyKey' => array_keys($yearlySum),
'yearlySum' => array_values($yearlySum),
'hourlyKey' => array_keys($hourlySum),

View File

@@ -35,27 +35,9 @@ class ProfileStatsComposer
}
// 概況欄のデータ取得
$average = DB::select(<<<'SQL'
SELECT
avg(span) AS average
FROM
(
SELECT
extract(epoch from ejaculated_date - lead(ejaculated_date, 1, NULL) OVER (ORDER BY ejaculated_date DESC)) AS span
FROM
ejaculations
WHERE
user_id = :user_id
ORDER BY
ejaculated_date DESC
LIMIT
30
) AS temp
SQL
, ['user_id' => $user->id]);
$summary = DB::select(<<<'SQL'
SELECT
avg(span) AS average,
max(span) AS longest,
min(span) AS shortest,
sum(span) AS total_times,
@@ -74,6 +56,6 @@ FROM
SQL
, ['user_id' => $user->id]);
$view->with(compact('latestEjaculation', 'currentSession', 'average', 'summary'));
$view->with(compact('latestEjaculation', 'currentSession', 'summary'));
}
}

View File

@@ -11,7 +11,7 @@ class Metadata extends Model
protected $keyType = 'string';
protected $fillable = ['url', 'title', 'description', 'image', 'expires_at'];
protected $visible = ['url', 'title', 'description', 'image', 'expires_at', 'tags'];
protected $visible = ['url', 'title', 'description', 'image', 'expires_at'];
protected $dates = ['created_at', 'updated_at', 'expires_at'];

View File

@@ -28,7 +28,6 @@ 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

@@ -64,7 +64,7 @@ class PixivResolver implements Resolver
$metadata->title = $json['body']['illustTitle'] ?? '';
$metadata->description = '投稿者: ' . $json['body']['userName'] . PHP_EOL . strip_tags(str_replace('<br />', PHP_EOL, $json['body']['illustComment'] ?? ''));
$metadata->image = $this->proxize($json['body']['urls']['regular'] ?? '');
$metadata->image = $this->proxize($json['body']['urls']['original'] ?? '');
// ページ数の指定がある場合は画像URLをそのページにする
if ($page != 0) {

View File

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

View File

@@ -1,41 +0,0 @@
<?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

@@ -11,9 +11,6 @@ class Tag extends Model
protected $fillable = [
'name'
];
protected $visible = [
'name'
];
public function ejaculations()
{

View File

@@ -41,7 +41,7 @@ class User extends Authenticatable
{
$hash = md5(strtolower(trim($this->email)));
return '//www.gravatar.com/avatar/' . $hash . '?s=' . $size . '&d=retro';
return '//www.gravatar.com/avatar/' . $hash . '?s=' . $size;
}
/**

View File

@@ -35,7 +35,7 @@ class Formatter
*/
public function linkify($text)
{
return $this->linkify->processUrls($text, ['attr' => ['target' => '_blank', 'rel' => 'noopener']]);
return $this->linkify->processUrls($text);
}
/**

View File

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

84
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "28abd730d4572663d10ae815393c73cd",
"content-hash": "665f6f5eb180a1295fb60303d2ea5051",
"packages": [
{
"name": "anhskohbo/no-captcha",
@@ -2113,16 +2113,16 @@
},
{
"name": "symfony/css-selector",
"version": "v4.3.3",
"version": "v4.2.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "105c98bb0c5d8635bea056135304bd8edcc42b4d"
"reference": "aa9fa526ba1b2ec087ffdfb32753803d999fcfcd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/105c98bb0c5d8635bea056135304bd8edcc42b4d",
"reference": "105c98bb0c5d8635bea056135304bd8edcc42b4d",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/aa9fa526ba1b2ec087ffdfb32753803d999fcfcd",
"reference": "aa9fa526ba1b2ec087ffdfb32753803d999fcfcd",
"shasum": ""
},
"require": {
@@ -2131,7 +2131,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
"dev-master": "4.2-dev"
}
},
"autoload": {
@@ -2147,14 +2147,14 @@
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
@@ -2162,7 +2162,7 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2019-01-16T21:53:39+00:00"
"time": "2018-11-11T19:52:12+00:00"
},
{
"name": "symfony/debug",
@@ -2220,67 +2220,6 @@
"homepage": "https://symfony.com",
"time": "2018-11-27T12:43:10+00:00"
},
{
"name": "symfony/dom-crawler",
"version": "v4.3.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "291397232a2eefb3347eaab9170409981eaad0e2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/291397232a2eefb3347eaab9170409981eaad0e2",
"reference": "291397232a2eefb3347eaab9170409981eaad0e2",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"masterminds/html5": "<2.6"
},
"require-dev": {
"masterminds/html5": "^2.6",
"symfony/css-selector": "~3.4|~4.0"
},
"suggest": {
"symfony/css-selector": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\DomCrawler\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2019-06-13T11:03:18+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v4.2.1",
@@ -4949,7 +4888,6 @@
"mock",
"xunit"
],
"abandoned": true,
"time": "2018-08-09T05:50:03+00:00"
},
{

7
e2e/.eslintrc.json Normal file
View File

@@ -0,0 +1,7 @@
{
"plugins": ["cypress"],
"env": {
"cypress/globals": true
},
"extends": ["plugin:cypress/recommended"]
}

1
e2e/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/node_modules

3
e2e/cypress.json Normal file
View File

@@ -0,0 +1,3 @@
{
"baseUrl": "http://localhost:4545"
}

View File

@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

21
e2e/cypress/integration/test.spec.js vendored Normal file
View File

@@ -0,0 +1,21 @@
describe("The Home Page", function() {
it("successfully loads", function() {
cy.visit("/"); // change URL to match your dev URL
cy.contains(".modal", "Tissue へようこそ!");
cy.focused() // command
.should("have.class", "modal")
.should("be.visible")
.contains("button", "まかせて")
.click();
cy.contains("ログイン").click();
cy.url().should("include", "/login");
cy.get("input#email").type("eai@mizle.net");
cy.get("input#password").type("111111");
cy.get("body > .container form")
.contains("ログイン")
.click();
cy.get("nav").should("contain", "ホーム");
});
});

17
e2e/cypress/plugins/index.js vendored Normal file
View File

@@ -0,0 +1,17 @@
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}

25
e2e/cypress/support/commands.js vendored Normal file
View File

@@ -0,0 +1,25 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

20
e2e/cypress/support/index.js vendored Normal file
View File

@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')

11
e2e/package.json Normal file
View File

@@ -0,0 +1,11 @@
{
"name": "e2e",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"cypress": "^3.3.1",
"eslint": "^5.16.0",
"eslint-plugin-cypress": "^2.2.1"
}
}

1751
e2e/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,6 @@
"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,10 +16,6 @@
<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

@@ -1,66 +1,9 @@
import Vue from 'vue';
import TagInput from "./components/TagInput.vue";
import MetadataPreview from './components/MetadataPreview.vue';
export const bus = new Vue({name: "EventBus"});
export enum MetadataLoadState {
Inactive,
Loading,
Success,
Failed,
}
new Vue({
el: '#app',
data: {
metadata: null,
metadataLoadState: MetadataLoadState.Inactive,
},
components: {
TagInput,
MetadataPreview
},
mounted() {
// オカズリンクにURLがセットされている場合は、すぐにメタデータを取得する
const linkInput = this.$el.querySelector<HTMLInputElement>("#link");
if (linkInput && /^https?:\/\//.test(linkInput.value)) {
this.fetchMetadata(linkInput.value);
}
},
methods: {
// オカズリンクの変更時
onChangeLink(event: Event) {
if (event.target instanceof HTMLInputElement) {
const url = event.target.value;
if (url.trim() === '' || !/^https?:\/\//.test(url)) {
this.metadata = null;
this.metadataLoadState = MetadataLoadState.Inactive;
return;
}
this.fetchMetadata(url);
}
},
// メタデータの取得
fetchMetadata(url: string) {
this.metadataLoadState = MetadataLoadState.Loading;
$.ajax({
url: '/api/checkin/card',
method: 'get',
type: 'json',
data: {
url
}
}).then(data => {
this.metadata = data;
this.metadataLoadState = MetadataLoadState.Success;
}).catch(e => {
this.metadata = null;
this.metadataLoadState = MetadataLoadState.Failed;
});
}
TagInput
}
});

View File

@@ -1,143 +0,0 @@
<template>
<div class="form-row" v-if="state !== MetadataLoadState.Inactive">
<div class="form-group col-sm-12">
<div class="card link-card-mini mb-2 px-0">
<div v-if="state === MetadataLoadState.Loading" class="row no-gutters">
<div class="col-12">
<div class="card-body">
<h6 class="card-title text-center font-weight-bold text-info" style="font-size: small;"><span class="oi oi-loop-circular"></span> オカズの情報を読み込んでいます</h6>
</div>
</div>
</div>
<div v-else-if="state === MetadataLoadState.Success" class="row no-gutters">
<div v-if="hasImage" class="col-4 justify-content-center align-items-center">
<img :src="metadata.image" alt="Thumbnail" class="w-100 bg-secondary">
</div>
<div :class="descClasses">
<div class="card-body">
<h6 class="card-title font-weight-bold" style="font-size: small;">{{ metadata.title }}</h6>
<template v-if="suggestions.length > 0">
<p class="card-text mb-2" style="font-size: small;">タグ候補<br><span class="text-secondary">(クリックするとタグ入力欄にコピーできます)</span></p>
<ul class="list-inline d-inline">
<li v-for="tag in suggestions"
:class="tagClasses(tag)"
@click="addTag(tag.name)"><span class="oi oi-tag"></span> {{ tag.name }}</li>
</ul>
</template>
</div>
</div>
</div>
<div v-else class="row no-gutters">
<div class="col-12">
<div class="card-body">
<h6 class="card-title text-center font-weight-bold text-danger" style="font-size: small;"><span class="oi oi-circle-x"></span> オカズの情報を読み込めませんでした</h6>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import {Vue, Component, Prop} from "vue-property-decorator";
import {bus, MetadataLoadState} from "../checkin";
type Metadata = {
url: string,
title: string,
description: string,
image: string,
expires_at: string | null,
tags: {
name: string
}[],
};
type Suggestion = {
name: string,
used: boolean,
}
@Component
export default class MetadataPreview extends Vue {
@Prop() readonly state!: MetadataLoadState;
@Prop() readonly metadata!: Metadata | null;
// for use in v-if
private readonly MetadataLoadState = MetadataLoadState;
tags: string[] = [];
created() {
bus.$on("change-tag", (tags: string[]) => this.tags = tags);
bus.$emit("resend-tag");
}
addTag(tag: string) {
bus.$emit("add-tag", tag);
}
tagClasses(s: Suggestion) {
return {
"list-inline-item": true,
"badge": true,
"badge-primary": !s.used,
"badge-secondary": s.used,
"metadata-tag-item": true,
};
}
get suggestions(): Suggestion[] {
if (this.metadata === null) {
return [];
}
return this.metadata.tags.map(t => {
return {
name: t.name,
used: this.tags.indexOf(t.name) !== -1
};
});
}
get hasImage() {
return this.metadata !== null && this.metadata.image !== ''
}
get descClasses() {
return {
"col-8": this.hasImage,
"col-12": !this.hasImage,
};
}
}
</script>
<style lang="scss" scoped>
.link-card-mini {
$height: 150px;
overflow: hidden;
.row > div:first-child {
display: flex;
&:not([display=none]) {
min-height: $height;
img {
position: absolute;
}
}
}
.card-text {
white-space: pre-line;
}
}
.metadata-tag-item {
cursor: pointer;
user-select: none;
}
</style>

View File

@@ -16,8 +16,7 @@
</template>
<script lang="ts">
import {Vue, Component, Prop, Watch} from "vue-property-decorator";
import {bus} from "../checkin";
import {Vue, Component, Prop} from "vue-property-decorator";
@Component
export default class TagInput extends Vue {
@@ -29,11 +28,6 @@
tags: string[] = this.value.trim() !== "" ? this.value.trim().split(" ") : [];
buffer: string = "";
created() {
bus.$on("add-tag", (tag: string) => this.tags.indexOf(tag) === -1 && this.tags.push(tag));
bus.$on("resend-tag", () => bus.$emit("change-tag", this.tags));
}
onKeyDown(event: KeyboardEvent) {
if (this.buffer.trim() !== "") {
switch (event.key) {
@@ -57,11 +51,6 @@
this.tags.splice(index, 1);
}
@Watch("tags")
onTagsChanged() {
bus.$emit("change-tag", this.tags);
}
get containerClass(): object {
return {
"form-control": true,

View File

@@ -1,12 +1,9 @@
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');
return new Chart(context, {
new Chart(context, {
type: 'line',
data: {
labels: labels,
@@ -65,22 +62,7 @@ function createBarGraph(id, labels, data) {
});
}
/**
* @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};
}
const graphData = JSON.parse(document.getElementById('graph-data').textContent);
new CalHeatMap().init({
itemSelector: '#cal-heatmap',
@@ -94,40 +76,7 @@ new CalHeatMap().init({
legend: [1, 2, 3, 4]
});
// 直近1年の月間グラフのデータを準備
const monthlyTermFrom = subMonths(startOfMonth(new Date()), 11);
const {keys: monthlyKey, values: monthlySum} = createMonthlyGraphData(monthlyTermFrom);
const monthlyGraph = createLineGraph('monthly-graph', monthlyKey, monthlySum);
createLineGraph('monthly-graph', graphData.monthlyKey, graphData.monthlySum);
createLineGraph('yearly-graph', graphData.yearlyKey, graphData.yearlySum);
createBarGraph('hourly-graph', graphData.hourlyKey, graphData.hourlySum);
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

@@ -0,0 +1,19 @@
.card-img-left {
width: 100%;
@include border-left-radius($card-inner-border-radius);
}
.card-img-right {
width: 100%;
@include border-right-radius($card-inner-border-radius);
}
.card-img-top-to-left {
width: 100%;
@include media-breakpoint-down(md) {
@include border-top-radius($card-inner-border-radius);
}
@include media-breakpoint-up(lg) {
@include border-left-radius($card-inner-border-radius);
}
}

View File

@@ -3,6 +3,7 @@ $primary: #e53fb1;
// Bootstrap
@import "~bootstrap/scss/bootstrap";
@import "bootstrap-custom";
// Open Iconic
@import "~open-iconic/font/css/open-iconic-bootstrap";

View File

@@ -1,6 +1,4 @@
.link-card {
overflow: hidden;
.row > div {
max-height: 400px;
overflow: hidden;

View File

@@ -77,4 +77,3 @@
#navbarAccountDropdownSp {
max-width: calc(100vw - 5em);
}

View File

@@ -2,7 +2,7 @@
<a class="text-dark card-link" href="{{ $link }}" target="_blank" rel="noopener">
<div class="row no-gutters">
<div class="col-12 col-md-6 justify-content-center align-items-center">
<img src="" alt="Thumbnail" class="w-100 bg-secondary">
<img src="" alt="Thumbnail" class="card-img-top-to-left bg-secondary">
</div>
<div class="col-12 col-md-6">
<div class="card-body">

View File

@@ -8,7 +8,7 @@
@endif
<h6 class="font-weight-bold"><span class="oi oi-graph"></span> 概況</h6>
<p class="card-text mb-0">平均記録: {{ Formatter::formatInterval($average[0]->average) }}</p>
<p class="card-text mb-0">平均記録: {{ Formatter::formatInterval($summary[0]->average) }}</p>
<p class="card-text mb-0">最長記録: {{ Formatter::formatInterval($summary[0]->longest) }}</p>
<p class="card-text mb-0">最短記録: {{ Formatter::formatInterval($summary[0]->shortest) }}</p>
<p class="card-text mb-0">合計時間: {{ Formatter::formatInterval($summary[0]->total_times) }}</p>

View File

@@ -52,9 +52,7 @@
<div class="form-row">
<div class="form-group col-sm-12">
<label for="link"><span class="oi oi-link-intact"></span> オカズリンク</label>
<input id="link" name="link" type="text" autocomplete="off" class="form-control {{ $errors->has('link') ? ' is-invalid' : '' }}"
placeholder="http://..." value="{{ old('link') ?? $defaults['link'] }}"
@change="onChangeLink">
<input id="link" name="link" type="text" autocomplete="off" class="form-control {{ $errors->has('link') ? ' is-invalid' : '' }}" placeholder="http://..." value="{{ old('link') ?? $defaults['link'] }}">
<small class="form-text text-muted">
オカズのURLを貼り付けて登録することができます。
</small>
@@ -63,7 +61,6 @@
@endif
</div>
</div>
<metadata-preview :metadata="metadata" :state="metadataLoadState"></metadata-preview>
<div class="form-row">
<div class="form-group col-sm-12">
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>

View File

@@ -53,9 +53,7 @@
<div class="form-row">
<div class="form-group col-sm-12">
<label for="link"><span class="oi oi-link-intact"></span> オカズリンク</label>
<input id="link" name="link" type="text" autocomplete="off" class="form-control {{ $errors->has('link') ? ' is-invalid' : '' }}"
placeholder="http://..." value="{{ old('link') ?? $ejaculation->link }}"
@change="onChangeLink">
<input id="link" name="link" type="text" autocomplete="off" class="form-control {{ $errors->has('link') ? ' is-invalid' : '' }}" placeholder="http://..." value="{{ old('link') ?? $ejaculation->link }}">
<small class="form-text text-muted">
オカズのURLを貼り付けて登録することができます。
</small>
@@ -64,7 +62,6 @@
@endif
</div>
</div>
<metadata-preview :metadata="metadata" :state="metadataLoadState"></metadata-preview>
<div class="form-row">
<div class="form-group col-sm-12">
<label for="note"><span class="oi oi-comment-square"></span> ノート</label>

View File

@@ -15,14 +15,7 @@
<h5 class="my-4">Shikontribution graph</h5>
<div id="cal-heatmap" class="tis-contribution-graph"></div>
<hr class="my-4">
<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>
<h5 class="my-4">月間チェックイン回数</h5>
<canvas id="monthly-graph" class="w-100"></canvas>
<hr class="my-4">
<h5 class="my-4">年間チェックイン回数</h5>

View File

@@ -22,12 +22,12 @@ trait CreateMockedResolver
/**
* @param string $resolverClass
* @param string|array $response
* @param string $responseText
* @param array $headers
* @param int $status
* @return Resolver
*/
protected function createResolver(string $resolverClass, $response, array $headers = [], int $status = 200)
protected function createResolver(string $resolverClass, string $responseText, array $headers = [], int $status = 200)
{
if (!$this->shouldUseMock()) {
$this->resolver = app()->make($resolverClass);
@@ -39,26 +39,8 @@ trait CreateMockedResolver
'content-type' => 'text/html',
];
if (is_array($response)) {
$responses = $response;
$mockResponses = [];
foreach ($responses as $response) {
if (is_array($response)) {
$response += [
1 => $headers,
2 => $status
];
array_push($mockResponses, new Response($response[2], $response[1], $response[0]));
} else {
array_push($mockResponses, new Response($status, $headers, $response));
}
}
$this->handler = new MockHandler($mockResponses);
} else {
$mockResponse = new Response($status, $headers, $response);
$mockResponse = new Response($status, $headers, $responseText);
$this->handler = new MockHandler([$mockResponse]);
}
$client = new Client(['handler' => $this->handler]);
$this->resolver = app()->make($resolverClass, ['client' => $client]);

View File

@@ -1,52 +0,0 @@
<?php
namespace Tests\Unit\MetadataResolver;
use App\MetadataResolver\KomifloResolver;
use Tests\TestCase;
class KomifloResolverTest extends TestCase
{
use CreateMockedResolver;
public function setUp()
{
parent::setUp();
if (!$this->shouldUseMock()) {
sleep(1);
}
}
public function testComic()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Komiflo/comic.json');
$this->createResolver(KomifloResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://komiflo.com/#!/comics/5490');
$this->assertEquals('魔法少女とえっち物語', $metadata->title);
$this->assertEquals('薙派 - メガストアα 19.07', $metadata->description);
$this->assertEquals('https://t.komiflo.com/564_mobile_large_3x/contents/23a4cd530060b8607aa434f4b299b249e71a4d5c.jpg', $metadata->image);
$this->assertEquals(['薙派', 'お姉さん', 'ショタ', 'ファンタジー', '巨乳', '野外・露出', '羞恥'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://api.komiflo.com/content/id/5490', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testComicWithNoParents()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Komiflo/comicWithNoParents.json');
$this->createResolver(KomifloResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://komiflo.com/#!/comics/3414');
$this->assertEquals('生まれなおしプログラム', $metadata->title);
$this->assertEquals('EROKI - ?', $metadata->description);
$this->assertEquals('https://t.komiflo.com/564_mobile_large_3x/contents/71cfb83640aead3cdd35e4329c4e2f427606a11d.jpg', $metadata->image);
$this->assertEquals(['EROKI', 'お姉さん', 'しつけ', 'オリジナル', 'ショートカット', '逆転', '巨乳'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://api.komiflo.com/content/id/3414', (string) $this->handler->getLastRequest()->getUri());
}
}
}

View File

@@ -1,68 +0,0 @@
<?php
namespace Tests\Unit\MetadataResolver;
use App\MetadataResolver\PixivResolver;
use Tests\TestCase;
class PixivResolverTest extends TestCase
{
use CreateMockedResolver;
public function setUp()
{
parent::setUp();
if (!$this->shouldUseMock()) {
sleep(1);
}
}
public function testIllust()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Pixiv/illust.json');
$this->createResolver(PixivResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://www.pixiv.net/member_illust.php?mode=medium&illust_id=68188073');
$this->assertEquals('coffee break', $metadata->title);
$this->assertEquals('投稿者: 裕' . PHP_EOL, $metadata->description);
$this->assertEquals('https://i.pixiv.cat/img-master/img/2018/04/12/00/01/28/68188073_p0_master1200.jpg', $metadata->image);
$this->assertEquals(['オリジナル', 'カフェ', '眼鏡', 'イヤホン', 'ぱっつん', '艶ぼくろ', '眼鏡っ娘', 'オリジナル5000users入り'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://www.pixiv.net/ajax/illust/68188073', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testIllustMultiPages()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Pixiv/illustMultiPages.json');
$this->createResolver(PixivResolver::class, $responseText);
$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/75899985', (string) $this->handler->getLastRequest()->getUri());
}
}
public function testManga()
{
$responseText = file_get_contents(__DIR__ . '/../../fixture/Pixiv/manga.json');
$this->createResolver(PixivResolver::class, $responseText);
$metadata = $this->resolver->resolve('https://www.pixiv.net/member_illust.php?mode=medium&illust_id=46713544');
$this->assertEquals('冬の日ラブラブ', $metadata->title);
$this->assertEquals('投稿者: Aza' . PHP_EOL . 'ラブラブエッチのらくがき' . PHP_EOL . PHP_EOL . '三万フォロワー感謝します~' . PHP_EOL . PHP_EOL . '最近忙しいので、自分の時間が少ない・・・', $metadata->description);
$this->assertEquals('https://i.pixiv.cat/img-master/img/2014/10/25/00/06/58/46713544_p0_master1200.jpg', $metadata->image);
$this->assertEquals(['落書き', 'おっぱい', 'オリジナル', 'パイズリ', '中出し', 'だいしゅきホールド', '愛のあるセックス', '黒髪ロング', 'オリジナル10000users入り'], $metadata->tags);
if ($this->shouldUseMock()) {
$this->assertSame('https://www.pixiv.net/ajax/illust/46713544', (string) $this->handler->getLastRequest()->getUri());
}
}
}

View File

@@ -1,140 +0,0 @@
<?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

@@ -1,51 +0,0 @@
<?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');
}
}

View File

@@ -1,437 +0,0 @@
{
"content": {
"attributes": {
"artists": {
"meta": {
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"name": "Artists"
},
"id": 2,
"name_read": "Artists",
"new_content_count": 0,
"pages": null,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.304746387Z",
"slug": "artists",
"source": "live",
"visibility": 1
},
"children": [
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "薙派",
"name_en": "chiba",
"published": "",
"searchTerms": "ちば,チバ",
"tankoubonLabel": "",
"visibility": true
},
"id": 1722,
"name_read": "ちば",
"new_content_count": 0,
"pages": null,
"parent_id": 2,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.303687274Z",
"slug": "chiba",
"source": "live",
"visibility": 1
}
]
},
"label": {
"meta": {
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "Labels",
"name_en": "",
"searchTerms": "",
"visibility": true
},
"id": 638,
"name_read": "",
"new_content_count": 0,
"pages": null,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.304743971Z",
"slug": "label",
"source": "live",
"visibility": 1
},
"children": [
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "First double page",
"name_en": "",
"searchTerms": "",
"visibility": true
},
"id": 659,
"name_read": "",
"new_content_count": 0,
"pages": null,
"parent_id": 638,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.30368064Z",
"slug": "label-firstdoublepage",
"source": "live",
"visibility": 1
}
]
},
"tags": {
"meta": {
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"name": "Tags"
},
"id": 1,
"name_read": "Tags",
"new_content_count": 0,
"pages": null,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.304745145Z",
"slug": "tags",
"source": "live",
"visibility": 1
},
"children": [
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "お姉さん",
"name_en": "Mature sister",
"published": "",
"searchTerms": "おねえさん,年上,おねーさん,オネエサン",
"tankoubonLabel": "",
"visibility": true
},
"id": 59,
"name_read": "おねえさん",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.303682097Z",
"slug": "oneesan",
"source": "live",
"visibility": 1
},
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "ショタ",
"name_en": "Little boy",
"published": "",
"searchTerms": "しょた,ショタコン,小学生,中学生",
"tankoubonLabel": "",
"visibility": true
},
"id": 75,
"name_read": "しょた",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.303683565Z",
"slug": "shota",
"source": "live",
"visibility": 1
},
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "ファンタジー",
"name_en": "",
"published": "",
"searchTerms": "ふぁんたじー,SF,妖怪",
"tankoubonLabel": "",
"visibility": true
},
"id": 98,
"name_read": "ふぁんたじー",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.30368434Z",
"slug": "fantasy",
"source": "live",
"visibility": 1
},
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "巨乳",
"name_en": "Big breasts",
"published": "",
"searchTerms": "きょにゅう,キョニュウ,爆乳",
"tankoubonLabel": "",
"visibility": true
},
"id": 37,
"name_read": "きょにゅう",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.303686492Z",
"slug": "kyonyu",
"source": "live",
"visibility": 1
},
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "野外・露出",
"name_en": "In public",
"published": "",
"searchTerms": "やがい,ろしゅつ,露出狂,アオカン,青姦",
"tankoubonLabel": "",
"visibility": true
},
"id": 53,
"name_read": "やがい",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.30368814Z",
"slug": "yagai",
"source": "live",
"visibility": 1
},
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "羞恥",
"name_en": "Shy girl",
"published": "",
"searchTerms": "しゅうち,シュウチ,羞恥プレイ",
"tankoubonLabel": "",
"visibility": true
},
"id": 47,
"name_read": "しゅうち",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.303688932Z",
"slug": "shuchi",
"source": "live",
"visibility": 1
}
]
},
"tags-hidden": {
"meta": {
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "Hidden tags",
"name_en": "",
"published": "",
"searchTerms": "",
"tankoubonLabel": "",
"visibility": true
},
"id": 783,
"name_read": "",
"new_content_count": 0,
"pages": null,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.304741513Z",
"slug": "tags-hidden",
"source": "live",
"visibility": 1
},
"children": [
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "COMICメガストアαsearch",
"name_en": "",
"published": "",
"searchTerms": "メガストア,めがすとあ",
"tankoubonLabel": "",
"visibility": true
},
"id": 1009,
"name_read": "",
"new_content_count": 0,
"pages": null,
"parent_id": 783,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:56:11.303678935Z",
"slug": "megastore-search",
"source": "live",
"visibility": 1
}
]
}
},
"body": "",
"cdn_public": "https://cdn.komiflo.com/resized",
"cdn_thumbs": "",
"children": [],
"comments_count": 3,
"data": {
"category": "",
"censorship": "モザイク修正",
"download_type": "",
"isbn": "",
"link_amazon": "",
"link_dlsite": "",
"link_dmm": "",
"link_wani": "",
"msrp": "",
"naughty": "",
"restricted": "",
"size": "",
"title": "魔法少女とえっち物語",
"url": ""
},
"expiry": "2020-06-20T15:00:00Z",
"id": 5490,
"imgs": null,
"key_data": "",
"key_hash": "",
"liked": false,
"likes_count": 127,
"named_imgs": {
"cover": {
"id": 79325,
"original": 81185,
"width": 4299,
"height": 6071,
"ident": "cover",
"filename": "contents/23a4cd530060b8607aa434f4b299b249e71a4d5c.jpg",
"variants": [
"148_desktop_small",
"296_desktop_small_2x",
"198_desktop_medium",
"396_desktop_medium_2x",
"247_desktop_large",
"494_desktop_large_2x",
"160_mobile_narrow",
"320_mobile_narrow_2x",
"207_mobile_medium",
"414_mobile_medium_2x",
"188_mobile_large",
"376_mobile_large_2x",
"564_mobile_large_3x",
"346_mobile"
]
}
},
"page_count": 0,
"parents": [
{
"body": "",
"cdn_public": "",
"cdn_thumbs": "",
"data": {
"category": "",
"download_type": "",
"isbn": "",
"link_amazon": "",
"link_dlsite": "",
"link_dmm": "",
"link_wani": "",
"msrp": "780",
"release_date": "",
"size": "",
"title": "メガストアα 19.07",
"url": ""
},
"expiry": "2020-06-20T15:00:00Z",
"id": 5474,
"likes_count": 0,
"page_count": null,
"premium": false,
"public": false,
"published": "2019-06-20T15:00:00Z",
"reading_lists": null,
"signature": "",
"signature_expires": "2019-06-27T02:56:11Z",
"slug": null,
"source": "cache",
"type": "volume"
}
],
"premium": false,
"public": true,
"published": "2019-06-20T15:00:00Z",
"reading_lists": [],
"signature": "?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9jZG4ua29taWZsby5jb20vKi9jb250ZW50cy8qIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIzOS4xMTEuMjE4LjE2MC8zMiJ9LCJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTU2MTYwNDE3MX19fV19&Signature=ilu4WlHoMMecmk8Ab3UuJ3LBTe~FhQxoGVdPbBF9CTrTB-Teockvf43MgWuAzWgsfFrwmCeV-hedV-iEx07B3S~D7ObXWCFcbPd1rb12D0qY~NF2SfGTv8lIbCDMQkc9wyUtE5K4MlZ35Bm4mZRv9HtEZkX1yjkVuAV7sBScBfJUkfnlg6yYsL2d2g4tDkN8gCOjZChUODetZPm05qwTmItIbq0kQhirgXNV~R1z~kFRwsgoBYClCq3vpQCsCy7tbKGmzHz6ku-PgpopqsOCmAaCl9Jh4D2pw8R64aREw6SX4tSoe7NPKG4KbtLzBsio260luuORDeaFcTjvlQI0~g__&Key-Pair-Id=APKAIILYVN5NFPDL7WIA",
"signature_expires": "2019-06-27T02:56:11Z",
"slug": null,
"source": "live",
"type": "chapter"
},
"success": true
}

View File

@@ -1,298 +0,0 @@
{
"content": {
"attributes": {
"artists": {
"meta": {
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"name": "Artists"
},
"id": 2,
"name_read": "Artists",
"new_content_count": 0,
"pages": null,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:50:55.176026561Z",
"slug": "artists",
"source": "live",
"visibility": 1
},
"children": [
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "EROKI",
"name_en": "eroki",
"published": "",
"searchTerms": "えろき,エロキ",
"tankoubonLabel": "",
"visibility": true
},
"id": 836,
"name_read": "えろき",
"new_content_count": 0,
"pages": null,
"parent_id": 2,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:50:55.174698472Z",
"slug": "eroki",
"source": "live",
"visibility": 1
}
]
},
"tags": {
"meta": {
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"name": "Tags"
},
"id": 1,
"name_read": "Tags",
"new_content_count": 0,
"pages": null,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:50:55.176028723Z",
"slug": "tags",
"source": "live",
"visibility": 1
},
"children": [
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "お姉さん",
"name_en": "Mature sister",
"published": "",
"searchTerms": "おねえさん,年上,おねーさん,オネエサン",
"tankoubonLabel": "",
"visibility": true
},
"id": 59,
"name_read": "おねえさん",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:50:55.174699935Z",
"slug": "oneesan",
"source": "live",
"visibility": 1
},
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "しつけ",
"name_en": "Discipline",
"published": "",
"searchTerms": "しつけ,躾,シツケ",
"tankoubonLabel": "",
"visibility": true
},
"id": 69,
"name_read": "しつけ",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:50:55.174701095Z",
"slug": "shitsuke",
"source": "live",
"visibility": 1
},
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "オリジナル",
"name_en": "",
"published": "",
"searchTerms": "おりじなる,オリジナル",
"tankoubonLabel": "",
"visibility": true
},
"id": 534,
"name_read": "おりじなる",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:50:55.174702761Z",
"slug": "original",
"source": "live",
"visibility": 1
},
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "ショートカット",
"name_en": "",
"published": "",
"searchTerms": "ショートヘアー,ショート,しょーと,しょーとへあ",
"tankoubonLabel": "",
"visibility": true
},
"id": 798,
"name_read": "しょーとかっと",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:50:55.174703509Z",
"slug": "shorthair",
"source": "live",
"visibility": 1
},
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "逆転",
"name_en": "",
"published": "",
"searchTerms": "ぎゃくてん,女性優位,ギャクテン",
"tankoubonLabel": "",
"visibility": true
},
"id": 74,
"name_read": "ぎゃくてん",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:50:55.174705548Z",
"slug": "gyakuten",
"source": "live",
"visibility": 1
},
{
"cdn_public": "",
"cdn_thumbs": "",
"content_count": 0,
"data": {
"href": "",
"ipRestrict": "",
"name": "巨乳",
"name_en": "Big breasts",
"published": "",
"searchTerms": "きょにゅう,キョニュウ,爆乳",
"tankoubonLabel": "",
"visibility": true
},
"id": 37,
"name_read": "きょにゅう",
"new_content_count": 0,
"pages": null,
"parent_id": 1,
"published": null,
"signature": "",
"signature_expires": "2019-06-26T14:50:55.174706294Z",
"slug": "kyonyu",
"source": "live",
"visibility": 1
}
]
}
},
"body": "",
"cdn_public": "https://cdn.komiflo.com/resized",
"cdn_thumbs": "",
"children": [],
"comments_count": 26,
"data": {
"category": "",
"censorship": "黒棒による修正",
"download_type": "",
"isbn": "",
"link_amazon": "",
"link_dlsite": "",
"link_dmm": "",
"link_wani": "",
"msrp": "",
"naughty": "",
"restricted": "",
"size": "",
"title": "生まれなおしプログラム",
"url": ""
},
"expiry": null,
"id": 3414,
"imgs": null,
"key_data": "",
"key_hash": "",
"liked": false,
"likes_count": 627,
"named_imgs": {
"cover": {
"id": 49645,
"original": 50622,
"width": 4299,
"height": 6071,
"ident": "cover",
"filename": "contents/71cfb83640aead3cdd35e4329c4e2f427606a11d.jpg",
"variants": [
"148_desktop_small",
"296_desktop_small_2x",
"198_desktop_medium",
"396_desktop_medium_2x",
"247_desktop_large",
"494_desktop_large_2x",
"160_mobile_narrow",
"320_mobile_narrow_2x",
"207_mobile_medium",
"414_mobile_medium_2x",
"188_mobile_large",
"376_mobile_large_2x",
"564_mobile_large_3x",
"346_mobile"
]
}
},
"page_count": 0,
"parents": [],
"premium": false,
"public": true,
"published": "2018-04-10T15:00:00Z",
"reading_lists": [],
"signature": "?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9jZG4ua29taWZsby5jb20vKi9jb250ZW50cy8qIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIzOS4xMTEuMjE4LjE2MC8zMiJ9LCJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTU2MTYwMzg1NX19fV19&Signature=bZFuvU1rgv2iBSSFlxyoexOIjjacWW4Sxe--EEjI2ruQPNnZE8iU542yCsWBSrmHfFOXFcYNKIf3PmTAxwjS-CeoyRc~O0VO6T9bNdlinFICMezNTPlYe0Ri~nUWxQ8Oy364ik5zrd5RwHmEOVMjfuc96N6ivrcL9Q5tfi-2sFs~8S9m-IH76Kf7dLXn8~TRPfGFj8bfyoDcn42YfCvfXzl4D92EnKjQO52x2~KICQR3X7igirQ6X1GmuYEoJd9GAYZlKNKUEQch7T6dpR-uJZEJ5hOJDsWrIJkvoMu9ZTBgdZOZGuNLfWunAJ0NhovNlN6-D8PmlhSd79Mu0P2LUA__&Key-Pair-Id=APKAIILYVN5NFPDL7WIA",
"signature_expires": "2019-06-27T02:50:55Z",
"slug": null,
"source": "live",
"type": "chapter"
},
"success": true
}

View File

@@ -1,824 +0,0 @@
{
"error": false,
"message": "",
"body": {
"illustId": "68188073",
"illustTitle": "coffee break",
"illustComment": "",
"id": "68188073",
"title": "coffee break",
"description": "",
"illustType": 0,
"createDate": "2018-04-11T15:01:28+00:00",
"uploadDate": "2018-04-11T15:01:28+00:00",
"restrict": 0,
"xRestrict": 0,
"sl": 2,
"urls": {
"mini": "https://i.pximg.net/c/48x48/img-master/img/2018/04/12/00/01/28/68188073_p0_square1200.jpg",
"thumb": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/04/12/00/01/28/68188073_p0_square1200.jpg",
"small": "https://i.pximg.net/c/540x540_70/img-master/img/2018/04/12/00/01/28/68188073_p0_master1200.jpg",
"regular": "https://i.pximg.net/img-master/img/2018/04/12/00/01/28/68188073_p0_master1200.jpg",
"original": "https://i.pximg.net/img-original/img/2018/04/12/00/01/28/68188073_p0.jpg"
},
"tags": {
"authorId": "17810",
"isLocked": false,
"tags": [
{
"tag": "オリジナル",
"locked": true,
"deletable": false,
"userId": "17810",
"romaji": "orijinaru",
"translation": {
"en": "original"
},
"userName": "裕"
},
{
"tag": "カフェ",
"locked": true,
"deletable": false,
"userId": "17810",
"romaji": "kafe",
"translation": {
"en": "cafe"
},
"userName": "裕"
},
{
"tag": "眼鏡",
"locked": true,
"deletable": false,
"userId": "17810",
"romaji": "megane",
"translation": {
"en": "glasses"
},
"userName": "裕"
},
{
"tag": "イヤホン",
"locked": true,
"deletable": false,
"userId": "17810",
"romaji": "iyahonn",
"translation": {
"en": "earphones"
},
"userName": "裕"
},
{
"tag": "ぱっつん",
"locked": false,
"deletable": false,
"romaji": "pattsunn",
"translation": {
"en": "straight fringe"
}
},
{
"tag": "艶ぼくろ",
"locked": false,
"deletable": false,
"romaji": "tsuyabokuro"
},
{
"tag": "眼鏡っ娘",
"locked": false,
"deletable": false,
"romaji": "meganekko",
"translation": {
"en": "girl with glasses"
}
},
{
"tag": "オリジナル5000users入り",
"locked": false,
"deletable": false,
"romaji": "orijinarugosennyu-za-zuiri",
"translation": {
"en": "original 5000+ bookmarks"
}
}
],
"writable": false
},
"storableTags": [
"RTJMXD26Ak",
"-UnxstvmLW",
"Nbvc4l7O_x",
"FTUtcpiOkA",
"w0fH70xUZS",
"27uevOlfIe",
"Sjwi7bh6-s",
"_pwIgrV8TB"
],
"userId": "17810",
"userName": "裕",
"userAccount": "youcapriccio",
"userIllusts": {
"14053843": null,
"14053937": null,
"14054027": null,
"14054186": null,
"14062828": null,
"14477076": null,
"14792405": null,
"16046742": null,
"16138239": null,
"16352926": null,
"16452748": null,
"16915557": null,
"17083628": null,
"17210510": null,
"17386995": null,
"17423518": null,
"17448062": null,
"17543415": null,
"17568036": null,
"17593779": null,
"17619003": null,
"17628888": null,
"17698823": null,
"17817803": null,
"17942662": null,
"18161965": null,
"18212527": null,
"18837942": null,
"19413060": null,
"19692459": null,
"19966924": null,
"19972770": null,
"20324120": null,
"20340204": null,
"20366995": null,
"20471558": null,
"20602724": null,
"20604539": null,
"20688177": null,
"21091157": null,
"21458619": null,
"21465117": null,
"21499486": null,
"21761917": null,
"22045640": null,
"22123124": null,
"22197758": null,
"22218971": null,
"22234319": null,
"22283588": null,
"22646212": null,
"22671292": null,
"23077173": null,
"23652482": null,
"24064845": null,
"24665326": null,
"24679135": null,
"24712190": null,
"24947762": null,
"25329936": null,
"26366272": null,
"27393935": null,
"27485745": null,
"27666949": null,
"28259132": null,
"28342787": null,
"28472420": null,
"28542432": null,
"28802580": null,
"28944777": null,
"29191265": null,
"29205875": null,
"29684473": null,
"29783263": null,
"30192166": null,
"31110886": null,
"31537645": null,
"32646946": null,
"32750353": null,
"33202416": null,
"33395376": null,
"33440266": null,
"35365709": null,
"35460263": null,
"36004858": null,
"36165748": null,
"36700962": null,
"36701188": null,
"36701484": null,
"36701689": null,
"37016640": null,
"37095482": null,
"37547592": null,
"39164365": null,
"40884078": null,
"41559080": null,
"46072865": null,
"46201289": null,
"46278624": null,
"47055452": null,
"47778617": null,
"48069391": null,
"48695249": null,
"48803034": null,
"49208325": null,
"49928045": null,
"51884036": null,
"51945556": null,
"52323083": null,
"52335660": null,
"52420382": null,
"52665902": null,
"52698908": null,
"52879266": null,
"53242280": null,
"53349656": null,
"53416534": null,
"53539911": null,
"53691135": null,
"53883574": null,
"53883648": null,
"54260186": null,
"54772276": null,
"54804756": null,
"54928943": null,
"54959965": null,
"55189849": null,
"55486830": null,
"55608689": null,
"55624737": null,
"55722012": null,
"55758248": null,
"55882194": null,
"56678994": null,
"57209033": null,
"57249918": null,
"57330537": null,
"57405593": null,
"57420595": null,
"57775178": null,
"58076340": null,
"59119603": null,
"59261109": null,
"59561361": null,
"59575686": null,
"60021663": null,
"60053226": null,
"60083767": null,
"60421993": null,
"60619841": null,
"60865442": null,
"61015613": null,
"61198859": null,
"61367766": null,
"61544285": null,
"61717134": null,
"61824584": null,
"61914664": null,
"62114491": null,
"62226468": null,
"62991520": null,
"63100455": null,
"63227860": null,
"63515109": null,
"63867496": null,
"64082433": null,
"64304193": null,
"64516472": null,
"64723379": null,
"64930347": null,
"64975155": null,
"65195542": null,
"65405890": null,
"65655985": null,
"65671343": null,
"65690745": null,
"65706774": null,
"65736319": null,
"65982587": null,
"66005055": null,
"66106458": null,
"66414630": null,
"66494466": null,
"66595810": null,
"66681398": null,
"66700481": null,
"66716698": null,
"66772099": null,
"67134385": null,
"67148315": null,
"67207903": null,
"67496395": null,
"67656921": null,
"67868039": null,
"67881973": null,
"67882087": {
"illustId": "67882087",
"illustTitle": "魔龍",
"id": "67882087",
"title": "魔龍",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/03/24/00/05/13/67882087_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"ドラゴン",
"魔龍",
"仕事絵"
],
"userId": "17810",
"userName": "裕",
"width": 1494,
"height": 1000,
"pageCount": 2,
"isBookmarkable": null,
"bookmarkData": null
},
"67932654": {
"illustId": "67932654",
"illustTitle": "武器デザイン",
"id": "67932654",
"title": "武器デザイン",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/03/27/00/16/43/67932654_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"仕事絵",
"ファンタジー",
"武器"
],
"userId": "17810",
"userName": "裕",
"width": 1383,
"height": 1573,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"67932696": {
"illustId": "67932696",
"illustTitle": "ファンタジーキャラ×6",
"id": "67932696",
"title": "ファンタジーキャラ×6",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/03/27/00/18/33/67932696_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"仕事絵",
"ファンタジー",
"デフォルメ",
"SD"
],
"userId": "17810",
"userName": "裕",
"width": 970,
"height": 812,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"67947316": {
"illustId": "67947316",
"illustTitle": "春ピンク🌸",
"id": "67947316",
"title": "春ピンク🌸",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/03/28/00/05/33/67947316_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"女の子",
"ファッション",
"カチューシャ編み",
"ピアス",
"アイシャドウ",
"マニキュア",
"茶髪"
],
"userId": "17810",
"userName": "裕",
"width": 1173,
"height": 1227,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"68064045": {
"illustId": "68064045",
"illustTitle": "Girls🌸",
"id": "68064045",
"title": "Girls🌸",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/04/04/00/00/32/68064045_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"ガールズイラスト",
"ファッション",
"ピアス",
"アイシャドウ",
"マニキュア",
"茶髪",
"パーマ"
],
"userId": "17810",
"userName": "裕",
"width": 800,
"height": 1148,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"68146376": {
"illustId": "68146376",
"illustTitle": "ねこ娘",
"id": "68146376",
"title": "ねこ娘",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/04/09/00/14/20/68146376_p0_square1200.jpg",
"description": "",
"tags": [
"ゲゲゲの鬼太郎",
"ねこ娘",
"6期猫娘",
"ゲゲゲの鬼太郎1000users入り"
],
"userId": "17810",
"userName": "裕",
"width": 1200,
"height": 1697,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"68188073": {
"illustId": "68188073",
"illustTitle": "coffee break",
"id": "68188073",
"title": "coffee break",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/04/12/00/01/28/68188073_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"カフェ",
"眼鏡",
"イヤホン",
"ぱっつん",
"艶ぼくろ",
"眼鏡っ娘",
"オリジナル5000users入り"
],
"userId": "17810",
"userName": "裕",
"width": 1200,
"height": 842,
"pageCount": 1,
"isBookmarkable": true,
"bookmarkData": null
},
"68232025": {
"illustId": "68232025",
"illustTitle": "木漏れ日",
"id": "68232025",
"title": "木漏れ日",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/04/15/00/07/57/68232025_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"女の子",
"木漏れ日",
"猫",
"オフショルダー",
"猫と女の子",
"オリジナル500users入り"
],
"userId": "17810",
"userName": "裕",
"width": 1200,
"height": 1446,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"68561488": {
"illustId": "68561488",
"illustTitle": "雨上がりとJK",
"id": "68561488",
"title": "雨上がりとJK",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/05/04/00/38/19/68561488_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"女子高生",
"コミティア",
"COMITIA124",
"制服",
"白ハイソックス",
"魅惑のすね",
"ロングヘアー",
"オリジナル10000users入り"
],
"userId": "17810",
"userName": "裕",
"width": 600,
"height": 767,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"68625248": {
"illustId": "68625248",
"illustTitle": "ドット柄×眼鏡",
"id": "68625248",
"title": "ドット柄×眼鏡",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/05/07/00/57/20/68625248_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"女の子",
"女子高生",
"ドット柄",
"眼鏡",
"制服",
"腕時計",
"リュックサック",
"リボン",
"オリジナル5000users入り"
],
"userId": "17810",
"userName": "裕",
"width": 600,
"height": 848,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"68684760": {
"illustId": "68684760",
"illustTitle": "告白の日",
"id": "68684760",
"title": "告白の日",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/05/11/00/00/14/68684760_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"仕事絵",
"女子高生",
"制服",
"カルピス",
"ラブレター",
"カルピスウォーター",
"オリジナル1000users入り"
],
"userId": "17810",
"userName": "裕",
"width": 1400,
"height": 700,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"68780252": {
"illustId": "68780252",
"illustTitle": "たとえばお伽噺に出てくるような、そんな魔法使い",
"id": "68780252",
"title": "たとえばお伽噺に出てくるような、そんな魔法使い",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/05/17/00/03/26/68780252_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"仕事絵",
"蒼空",
"オリジナル500users入り"
],
"userId": "17810",
"userName": "裕",
"width": 800,
"height": 1141,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"68936315": {
"illustId": "68936315",
"illustTitle": "謎のヒロインX",
"id": "68936315",
"title": "謎のヒロインX",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/05/27/00/01/02/68936315_p0_square1200.jpg",
"description": "",
"tags": [
"Fate/GrandOrder",
"謎のヒロインX",
"FGO",
"Fate/GO1000users入り",
"FGOイラコン2"
],
"userId": "17810",
"userName": "裕",
"width": 2893,
"height": 4092,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"69000379": null,
"69045498": null,
"69138520": null,
"69204438": null,
"69263984": null,
"69311774": null,
"69326765": null,
"69340502": null,
"69390965": null,
"69419351": null,
"69498750": null,
"69755373": null,
"69781341": null,
"69972875": null,
"70042642": null,
"70272492": null,
"70419208": null,
"70959974": null,
"70992219": null,
"71006962": null,
"71022606": null,
"71056067": null,
"71076458": null,
"71094391": null,
"71274492": null,
"71462679": null,
"72235293": null,
"72480342": null,
"72514297": null,
"72535044": null,
"72551222": null,
"72565887": null,
"72581189": null,
"72596181": null,
"72611658": null,
"72629786": null,
"72648764": null,
"72668158": null,
"72683532": null,
"72698000": null,
"72712777": null,
"72744221": null,
"72764549": null,
"72780210": null,
"72795236": null,
"72810723": null,
"72826398": null,
"72841779": null,
"72859874": null,
"72879945": null,
"72894635": null,
"73169245": null,
"73169325": null,
"73206108": null,
"73600652": null,
"74143168": null,
"74157207": null,
"74170787": null,
"74187191": null,
"74208185": null,
"74223553": null,
"74251605": null,
"74265532": null,
"74451789": null,
"74478687": null,
"74502113": null,
"74542366": null,
"74650363": null,
"74664239": null,
"74666682": null,
"74791171": null,
"74827564": null,
"75226739": null,
"75242973": null
},
"likeData": false,
"width": 1200,
"height": 842,
"pageCount": 1,
"bookmarkCount": 5431,
"likeCount": 4324,
"commentCount": 10,
"responseCount": 0,
"viewCount": 35092,
"isHowto": false,
"isOriginal": true,
"imageResponseOutData": [],
"imageResponseData": [],
"imageResponseCount": 0,
"pollData": null,
"seriesNavData": null,
"descriptionBoothId": null,
"descriptionYoutubeId": null,
"comicPromotion": null,
"contestBanners": [],
"factoryGoods": {
"integratable": true,
"integrated": false
},
"isBookmarkable": true,
"bookmarkData": null,
"contestData": null,
"zoneConfig": {
"responsive": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=illust_responsive&format=js&s=0&up=0&ng=w&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg43qwdceqt404kl9&num=5d06c0df289"
},
"300x250": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=illust_rectangle&format=js&s=0&up=0&ng=w&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg43qwdcett5g1ucx&num=5d06c0df449"
},
"header": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=header&format=js&s=0&up=0&ng=w&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg43qwdcewbo66sio&num=5d06c0df704"
},
"footer": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=footer&format=js&s=0&up=0&ng=w&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg43qwdceypre876g&num=5d06c0df256"
},
"expandedFooter": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=multiple_illust_viewer&format=js&s=0&up=0&ng=w&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg43qwdcf11vpcj6t&num=5d06c0df904"
},
"logo": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=logo_side&format=js&s=0&up=0&ng=w&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg43qwdcf3cd2h2z3&num=5d06c0df383"
},
"500x500": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=bigbanner&format=js&s=0&up=0&ng=w&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg43qwdcf5o97vzyt&num=5d06c0df945"
}
},
"extraData": {
"meta": {
"title": "【オリジナル】「coffee break」/「裕」のイラスト [pixiv]",
"description": "この作品 「coffee break」 は 「オリジナル」「カフェ」 等のタグがつけられた「裕」さんのイラストです。 「」",
"keywords": "オリジナル,カフェ,眼鏡,イヤホン,ぱっつん,艶ぼくろ,眼鏡っ娘,オリジナル5000users入り,イラスト,pixiv,ピクシブ",
"canonical": "https://www.pixiv.net/member_illust.php?mode=medium&illust_id=68188073"
}
},
"noLoginData": {
"breadcrumbs": [
"創作",
"オリジナル"
],
"zengoIdWorks": {
"prev": {
"id": "68188072",
"title": "Winter Soldier_Infinity War ver."
},
"next": {
"id": "68188074",
"title": "【腐】翔太受けまとめ"
}
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,604 +0,0 @@
{
"error": false,
"message": "",
"body": {
"illustId": "46713544",
"illustTitle": "冬の日ラブラブ",
"illustComment": "ラブラブエッチのらくがき<br /><br />三万フォロワー感謝します~<br /><br />最近忙しいので、自分の時間が少ない・・・",
"id": "46713544",
"title": "冬の日ラブラブ",
"description": "ラブラブエッチのらくがき<br /><br />三万フォロワー感謝します~<br /><br />最近忙しいので、自分の時間が少ない・・・",
"illustType": 1,
"createDate": "2014-10-24T15:06:58+00:00",
"uploadDate": "2014-10-24T15:06:58+00:00",
"restrict": 0,
"xRestrict": 1,
"sl": 6,
"urls": {
"mini": "https://i.pximg.net/c/48x48/img-master/img/2014/10/25/00/06/58/46713544_p0_square1200.jpg",
"thumb": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2014/10/25/00/06/58/46713544_p0_square1200.jpg",
"small": "https://i.pximg.net/c/540x540_70/img-master/img/2014/10/25/00/06/58/46713544_p0_master1200.jpg",
"regular": "https://i.pximg.net/img-master/img/2014/10/25/00/06/58/46713544_p0_master1200.jpg",
"original": "https://i.pximg.net/img-original/img/2014/10/25/00/06/58/46713544_p0.jpg"
},
"tags": {
"authorId": "502217",
"isLocked": false,
"tags": [
{
"tag": "R-18",
"locked": true,
"deletable": false,
"userId": "502217",
"romaji": null,
"userName": "Aza"
},
{
"tag": "落書き",
"locked": true,
"deletable": false,
"userId": "502217",
"romaji": "rakugaki",
"translation": {
"en": "doodle"
},
"userName": "Aza"
},
{
"tag": "おっぱい",
"locked": true,
"deletable": false,
"userId": "502217",
"romaji": "oppai",
"translation": {
"en": "breasts"
},
"userName": "Aza"
},
{
"tag": "オリジナル",
"locked": true,
"deletable": false,
"userId": "502217",
"romaji": "orijinaru",
"translation": {
"en": "original"
},
"userName": "Aza"
},
{
"tag": "パイズリ",
"locked": false,
"deletable": false,
"romaji": "paizuri",
"translation": {
"en": "paizuri"
}
},
{
"tag": "中出し",
"locked": false,
"deletable": false,
"romaji": "nakadashi",
"translation": {
"en": "creampie"
}
},
{
"tag": "だいしゅきホールド",
"locked": false,
"deletable": false,
"romaji": "daishukiho-rudo",
"translation": {
"en": "leg lock"
}
},
{
"tag": "愛のあるセックス",
"locked": false,
"deletable": false,
"romaji": "ainoarusekkusu",
"translation": {
"en": "love-making"
}
},
{
"tag": "黒髪ロング",
"locked": false,
"deletable": false,
"romaji": "kurokamironngu",
"translation": {
"en": "long black hair"
}
},
{
"tag": "オリジナル10000users入り",
"locked": false,
"deletable": false,
"romaji": "orijinaruichimannyu-za-zuiri",
"translation": {
"en": "original 10000+ bookmarks"
}
}
],
"writable": false
},
"storableTags": [
"0xsDLqCEW6",
"KvAGITxIxH",
"Ie2c51_4Sp",
"RTJMXD26Ak",
"AI_aJCDFn0",
"MM6RXH_rlN",
"MmtTUk7gNU",
"LEmyJ-RN72",
"pYlUxeIoeg",
"jH0uD88V6F"
],
"userId": "502217",
"userName": "Aza",
"userAccount": "zaxwu",
"userIllusts": {
"2982154": null,
"3232171": null,
"9683924": null,
"9982638": null,
"10486890": null,
"13450140": null,
"13594508": null,
"15091512": null,
"15584077": null,
"18502761": null,
"19428567": null,
"21337912": null,
"23139081": null,
"26446486": null,
"26602193": null,
"29381152": null,
"30918820": null,
"31543061": null,
"32237888": null,
"32760977": null,
"32797035": null,
"33407004": null,
"34272641": null,
"35659365": {
"illustId": "35659365",
"illustTitle": "Redial",
"id": "35659365",
"title": "Redial",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2013/05/13/00/41/01/35659365_p0_square1200.jpg",
"description": "",
"tags": [
"初音ミク",
"Redial",
"無限ループ",
"ミクダヨー",
"ポリン",
"VOCALOID1000users入り",
"VOCALOID"
],
"userId": "502217",
"userName": "Aza",
"width": 1650,
"height": 1300,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"36344943": {
"illustId": "36344943",
"illustTitle": "バニーちーちゃん",
"id": "36344943",
"title": "バニーちーちゃん",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2013/06/14/10/20/58/36344943_p0_square1200.jpg",
"description": "",
"tags": [
"佐々木千穂",
"バニーガール",
"はたらく魔王さま!",
"おっぱい",
"パンスト",
"ロリ爆乳",
"黒バニー",
"ちーちゃん",
"手袋",
"はたらく魔王さま!500users入り"
],
"userId": "502217",
"userName": "Aza",
"width": 1200,
"height": 1350,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"38288483": {
"illustId": "38288483",
"illustTitle": "ログインゲーム",
"id": "38288483",
"title": "ログインゲーム",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2013/09/04/10/37/02/38288483_p0_square1200.jpg",
"description": "",
"tags": [
"ファイナルファンタジー14",
"ララフェル",
"FF100users入り"
],
"userId": "502217",
"userName": "Aza",
"width": 600,
"height": 1128,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"40513649": {
"illustId": "40513649",
"illustTitle": "クリスマス",
"id": "40513649",
"title": "クリスマス",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2013/12/26/00/13/24/40513649_p0_square1200.jpg",
"description": "",
"tags": [
"オリジナル",
"クリスマス",
"ハイヒール",
"オリジナル100users入り",
"女の子"
],
"userId": "502217",
"userName": "Aza",
"width": 900,
"height": 900,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"40865549": {
"illustId": "40865549",
"illustTitle": "ヲ級",
"id": "40865549",
"title": "ヲ級",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2014/01/10/00/48/39/40865549_p0_square1200.jpg",
"description": "",
"tags": [
"艦これ",
"空母ヲ級",
"落書き",
"深海棲艦",
"艦隊これくしょん",
"艦これ100users入り"
],
"userId": "502217",
"userName": "Aza",
"width": 800,
"height": 1056,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"44463100": {
"illustId": "44463100",
"illustTitle": "ノアちゃん",
"id": "44463100",
"title": "ノアちゃん",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2014/07/03/00/06/00/44463100_p0_square1200.jpg",
"description": "",
"tags": [
"パズドラ",
"ノア",
"パズドラ100users入り",
"おでこ"
],
"userId": "502217",
"userName": "Aza",
"width": 1200,
"height": 1200,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"46713544": {
"illustId": "46713544",
"illustTitle": "冬の日ラブラブ",
"id": "46713544",
"title": "冬の日ラブラブ",
"illustType": 1,
"xRestrict": 1,
"restrict": 0,
"sl": 6,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2014/10/25/00/06/58/46713544_p0_square1200.jpg",
"description": "ラブラブエッチのらくがき<br /><br />三万フォロワー感謝します~<br /><br />最近忙しいので、自分の時間が少ない・・・",
"tags": [
"R-18",
"落書き",
"おっぱい",
"オリジナル",
"パイズリ",
"中出し",
"だいしゅきホールド",
"愛のあるセックス",
"黒髪ロング",
"オリジナル10000users入り"
],
"userId": "502217",
"userName": "Aza",
"width": 800,
"height": 800,
"pageCount": 20,
"isBookmarkable": true,
"bookmarkData": null
},
"49623591": {
"illustId": "49623591",
"illustTitle": "らくがきまとめ4",
"id": "49623591",
"title": "らくがきまとめ4",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2015/04/03/00/15/53/49623591_p0_square1200.jpg",
"description": "",
"tags": [
"落書き",
"極上の尻",
"パズドラ",
"ぴっちりスーツ",
"魔性の潮",
"加賀",
"艦これ100users入り",
"潮(艦隊これくしょん)",
"100users入り",
"バニーガール"
],
"userId": "502217",
"userName": "Aza",
"width": 1000,
"height": 1080,
"pageCount": 38,
"isBookmarkable": null,
"bookmarkData": null
},
"51747015": {
"illustId": "51747015",
"illustTitle": "バニー潮ちゃん",
"id": "51747015",
"title": "バニー潮ちゃん",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2015/08/03/21/22/52/51747015_p0_square1200.jpg",
"description": "",
"tags": [
"艦これ",
"バニーガール",
"バニーの日",
"潮っぱい",
"魔性の潮",
"まったく、駆逐艦は最高だぜ!!",
"艦々バニー",
"潮(艦隊これくしょん)",
"艦隊これくしょん",
"艦これ1000users入り"
],
"userId": "502217",
"userName": "Aza",
"width": 1000,
"height": 1421,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"52206867": {
"illustId": "52206867",
"illustTitle": "水着おっぱいまとめ",
"id": "52206867",
"title": "水着おっぱいまとめ",
"illustType": 1,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2015/08/27/00/55/49/52206867_p0_square1200.jpg",
"description": "",
"tags": [
"おっぱい",
"水着",
"落書き",
"巨乳",
"挟まれたい谷間",
"デカァァァァァいッ説明不要!!",
"愛宕/パチュリー/千斗いすず/柏崎星奈/丹生谷森夏/ハトホル",
"千斗いすず"
],
"userId": "502217",
"userName": "Aza",
"width": 500,
"height": 875,
"pageCount": 7,
"isBookmarkable": null,
"bookmarkData": null
},
"52584590": {
"illustId": "52584590",
"illustTitle": "楓ちゃん",
"id": "52584590",
"title": "楓ちゃん",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2015/09/18/23/35/41/52584590_p0_square1200.jpg",
"description": "",
"tags": [
"アイドルマスターシンデレラガールズ",
"オッドアイ",
"高垣楓",
"アイマス1000users入り"
],
"userId": "502217",
"userName": "Aza",
"width": 900,
"height": 900,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"64877227": {
"illustId": "64877227",
"illustTitle": "マシュ",
"id": "64877227",
"title": "マシュ",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2017/09/10/00/10/03/64877227_p0_square1200.jpg",
"description": "",
"tags": [
"マシュ",
"Fate/GrandOrder",
"素晴らしすぎる",
"極上の乳",
"マシュ・キリエライト",
"Fate/GO1000users入り",
"濡れ透け",
"マシュマロおっぱい"
],
"userId": "502217",
"userName": "Aza",
"width": 1000,
"height": 1000,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"66698671": {
"illustId": "66698671",
"illustTitle": "モテそうですよね",
"id": "66698671",
"title": "モテそうですよね",
"illustType": 0,
"xRestrict": 0,
"restrict": 0,
"sl": 2,
"url": "https://i.pximg.net/c/250x250_80_a2/img-master/img/2018/01/08/00/47/32/66698671_p0_square1200.jpg",
"description": "",
"tags": [
"輝夜月",
"バーチャルYouTuber",
"魅惑の谷間",
"バーチャルYouTuber1000users入り"
],
"userId": "502217",
"userName": "Aza",
"width": 1200,
"height": 1200,
"pageCount": 1,
"isBookmarkable": null,
"bookmarkData": null
},
"69620476": null
},
"likeData": false,
"width": 800,
"height": 800,
"pageCount": 20,
"bookmarkCount": 16448,
"likeCount": 13048,
"commentCount": 70,
"responseCount": 0,
"viewCount": 483175,
"isHowto": false,
"isOriginal": true,
"imageResponseOutData": [],
"imageResponseData": [],
"imageResponseCount": 0,
"pollData": null,
"seriesNavData": null,
"descriptionBoothId": null,
"descriptionYoutubeId": null,
"comicPromotion": null,
"contestBanners": [],
"factoryGoods": {
"integratable": false,
"integrated": false
},
"isBookmarkable": true,
"bookmarkData": null,
"contestData": null,
"zoneConfig": {
"responsive": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=illust_responsive&format=js&s=0&up=0&ng=g&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg4dukaxjl9lcz20o&num=5d1245e1507"
},
"300x250": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=illust_rectangle&format=js&s=0&up=0&ng=g&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg4dukaxjo8fldij4&num=5d1245e15"
},
"500x500": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=bigbanner&format=js&s=0&up=0&ng=g&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg4dukaxjqltfp2la&num=5d1245e182"
},
"header": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=header&format=js&s=0&up=0&ng=g&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg4dukaxjsv9fca5h&num=5d1245e1969"
},
"footer": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=footer&format=js&s=0&up=0&ng=g&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg4dukaxjv5vqfo0g&num=5d1245e1914"
},
"expandedFooter": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=multiple_illust_viewer&format=js&s=0&up=0&ng=g&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg4dukaxjxd4y5zlv&num=5d1245e1125"
},
"logo": {
"url": "https://pixon.ads-pixiv.net/show?zone_id=logo_side&format=js&s=0&up=0&ng=g&l=ja&uri=%2Fajax%2Fillust%2F_PARAM_&is_spa=1&ab_test_digits_first=5&ab_test_digits_second=5&Yuid=MjgDVlY&suid=Pg4dukaxjzmhr6fid&num=5d1245e1989"
}
},
"extraData": {
"meta": {
"title": "[R-18] 【落書き】「冬の日ラブラブ」/「Aza」のマンガ [pixiv]",
"description": "この作品 「冬の日ラブラブ」 は 「R-18」「落書き」 等のタグがつけられた「Aza」さんの漫画です。 「ラブラブエッチのらくがき三万フォロワー感謝します~最近忙しいので、自分の時間が少ない・・・」",
"keywords": "R-18,落書き,おっぱい,オリジナル,パイズリ,中出し,だいしゅきホールド,愛のあるセックス,黒髪ロング,オリジナル10000users入り,イラスト,pixiv,ピクシブ",
"canonical": "https://www.pixiv.net/member_illust.php?mode=medium&illust_id=46713544"
}
},
"noLoginData": {
"breadcrumbs": [
"日常",
"R-18"
],
"zengoIdWorks": {
"prev": {
"id": "46713543",
"title": "ゆい様"
},
"next": {
"id": "46713545",
"title": "木吉"
}
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1 +0,0 @@
{"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"}]}

View File

@@ -2333,7 +2333,7 @@ d3@^3.0.6:
resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8"
integrity sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=
date-fns@^1.27.2, date-fns@^1.30.1:
date-fns@^1.27.2:
version "1.30.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
@@ -4607,9 +4607,9 @@ lodash.uniq@^4.5.0:
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
log-symbols@^1.0.2:
version "1.0.2"