Removed affiliate table in favor of direct campaign URLs.

This commit is contained in:
DebaucheryLibrarian 2021-06-28 02:50:06 +02:00
parent afbae24f43
commit 385dfb9f75
17 changed files with 317 additions and 176 deletions

View File

@ -0,0 +1,96 @@
<template>
<a
v-if="campaign"
:href="campaign.url"
target="_blank"
class="campaign"
>
<img
v-if="campaign.banner.entity.type === 'network'"
:src="`/img/banners/${campaign.banner.entity.slug}/${campaign.banner.id}.jpeg`"
class="campaign-banner"
>
<img
v-if="campaign.banner.entity.type === 'channel' && campaign.banner.entity.parent?.type === 'network'"
:src="`/img/banners/${campaign.banner.entity.parent.slug}/${campaign.banner.entity.slug}/${campaign.banner.id}.jpeg`"
class="campaign-banner"
>
</a>
</template>
<script>
function entityCampaign() {
const bannerCampaigns = this.entity.campaigns
.concat(this.entity.children?.flatMap(child => child.campaigns))
.concat(this.entity.parent?.campaigns)
.filter(campaignX => campaignX.banner?.ratio > 3);
if (bannerCampaigns.length > 0) {
return bannerCampaigns[Math.floor(Math.random() * bannerCampaigns.length)];
}
return null;
}
function tagCampaign() {
const campaignBanners = this.tag.banners.filter(banner => banner.campaigns.length > 0 && banner.ratio > 3);
const banner = campaignBanners[Math.floor(Math.random() * campaignBanners.length)];
if (banner?.campaigns.length > 0) {
return {
...banner.campaigns[Math.floor(Math.random() * banner.campaigns.length)],
banner,
};
}
return null;
}
function campaign() {
if (this.entity) {
return this.entityCampaign();
}
if (this.tag) {
return this.tagCampaign();
}
return null;
}
export default {
props: {
entity: {
type: Object,
default: null,
},
tag: {
type: Object,
default: null,
},
},
computed: {
campaign,
},
methods: {
entityCampaign,
tagCampaign,
},
};
</script>
<style lang="scss" scoped>
.campaign {
height: 100%;
display: inline-flex;
flex-grow: 1;
align-items: center;
justify-content: center;
}
.campaign-banner {
max-height: 100%;
max-width: 100%;
}
</style>

View File

@ -41,25 +41,6 @@
/>
</a>
<a
v-if="campaign"
:href="campaign.affiliate.url"
target="_blank"
class="campaign"
>
<img
v-if="campaign.banner.entity.type === 'network'"
:src="`/img/banners/${campaign.banner.entity.slug}/${campaign.banner.id}.jpeg`"
class="campaign-banner"
>
<img
v-if="campaign.banner.entity.type === 'channel' && campaign.banner.entity.parent?.type === 'network'"
:src="`/img/banners/${campaign.banner.entity.parent.slug}/${campaign.banner.entity.slug}/${campaign.banner.id}.jpeg`"
class="campaign-banner"
>
</a>
<ul
v-if="entity.tags.length > 0"
class="tags"
@ -115,6 +96,10 @@
/>
</Scroll>
<div class="campaign-container">
<Campaign :entity="entity" />
</div>
<FilterBar
ref="filter"
:fetch-releases="fetchEntity"
@ -143,9 +128,9 @@ import Pagination from '../pagination/pagination.vue';
import Releases from '../releases/releases.vue';
import Children from './children.vue';
import Scroll from '../scroll/scroll.vue';
import Campaign from '../campaigns/campaign.vue';
async function fetchEntity(scroll = true) {
this.campaign = null;
this.entityUrl = null;
const { entity, totalCount } = await this.$store.dispatch('fetchEntityBySlugAndType', {
@ -160,16 +145,7 @@ async function fetchEntity(scroll = true) {
this.totalCount = totalCount;
this.pageTitle = entity.name;
const channelBannerCampaigns = entity.campaigns.filter(campaign => campaign.banner);
const networkBannerCampaigns = entity.parent?.campaigns.filter(campaign => campaign.banner);
const bannerCampaigns = channelBannerCampaigns.length > 0 ? channelBannerCampaigns : networkBannerCampaigns;
if (bannerCampaigns.length > 0) {
this.campaign = bannerCampaigns[Math.floor(Math.random() * bannerCampaigns.length)];
}
this.entityUrl = entity.campaigns.find(campaign => !campaign.banner)?.affiliate.url || entity.url;
this.entityUrl = entity.campaigns.find(campaign => !campaign.banner)?.url || entity.url;
if (scroll && this.$refs.filter?.$el) {
this.$refs.filter.$el.scrollIntoView();
@ -194,6 +170,7 @@ export default {
Children,
Releases,
Scroll,
Campaign,
},
data() {
return {
@ -202,7 +179,6 @@ export default {
totalCount: null,
limit: Number(this.$route.query.limit) || 20,
expanded: false,
campaign: null,
entityUrl: null,
};
},
@ -221,7 +197,6 @@ export default {
@import 'breakpoints';
.info {
height: 6rem;
display: flex;
justify-content: space-between;
background: var(--profile);
@ -229,15 +204,17 @@ export default {
}
.link {
max-width: 20rem;
max-width: 15rem;
display: flex;
align-items: center;
box-sizing: border-box;
padding: 1rem;
padding: .5rem 1rem;
text-decoration: none;
}
.link-child {
flex-shrink: 0;
.icon {
fill: var(--lighten);
margin: 0 0 0 1rem;
@ -250,6 +227,7 @@ export default {
.link-parent {
flex-direction: row-reverse;
flex-shrink: 0;
margin: 0 0 0 3rem;
.icon {
@ -276,14 +254,7 @@ export default {
.favicon {
height: 1rem;
}
.campaign {
height: 100%;
}
.campaign-banner {
height: 100%;
flex-shrink: 0;
}
.content-inner {
@ -295,6 +266,12 @@ export default {
background: var(--profile);
}
.campaign-container {
background: var(--background-dim);
text-align: center;
padding: .5rem;
}
.releases {
flex-grow: 1;
}

View File

@ -48,24 +48,7 @@
/>
<div class="campaign-container">
<a
v-if="campaign"
:href="campaign.affiliate.url"
target="_blank"
class="campaign"
>
<img
v-if="campaign.banner.entity.type === 'network'"
:src="`/img/banners/${campaign.banner.entity.slug}/${campaign.banner.id}.jpeg`"
class="campaign-banner"
>
<img
v-if="campaign.banner.entity.type === 'channel' && campaign.banner.entity.parent?.type === 'network'"
:src="`/img/banners/${campaign.banner.entity.parent.slug}/${campaign.banner.entity.slug}/${campaign.banner.id}.jpeg`"
class="campaign-banner"
>
</a>
<Campaign :tag="tag" />
</div>
<FilterBar
@ -97,6 +80,7 @@ import Album from '../album/album.vue';
import Releases from '../releases/releases.vue';
import Pagination from '../pagination/pagination.vue';
import Scroll from '../scroll/scroll.vue';
import Campaign from '../campaigns/campaign.vue';
const converter = new Converter();
@ -115,15 +99,6 @@ async function fetchReleases(scroll = true) {
this.hasMedia = this.tag.poster || this.tag.photos.length > 0;
this.description = this.tag.description && converter.makeHtml(escapeHtml(this.tag.description));
if (tag.banners.length > 0) {
const banner = tag.banners[Math.floor(Math.random() * tag.banners.length)];
this.campaign = {
...banner.campaigns[Math.floor(Math.random() * banner.campaigns.length)],
banner,
};
}
if (scroll && this.$refs.filter) {
this.$refs.filter.$el.scrollIntoView();
}
@ -152,6 +127,7 @@ export default {
Photos,
Pagination,
Scroll,
Campaign,
},
data() {
return {
@ -163,7 +139,6 @@ export default {
pageTitle: null,
hasMedia: false,
expanded: false,
campaign: null,
};
},
computed: {
@ -240,14 +215,4 @@ export default {
background: var(--background-dim);
text-align: center;
}
.campaign {
display: inline-block;
height: 100%;
.campaign-banner {
max-height: 100%;
max-width: 100%;
}
}
</style>

View File

@ -63,6 +63,7 @@ function initEntitiesActions(store, router) {
priority
independent
hasLogo
${campaignsFragment}
}
}
${campaignsFragment}

View File

@ -98,26 +98,32 @@ const actorFields = `
const campaignsFragment = `
campaigns(filter: {
banner: {
bannersTagsConnection: {
none: {
tag: {
slug: {
in: $exclude
or: [
{
banner: {
bannersTagsConnection: {
none: {
tag: {
slug: {
in: $exclude
}
}
}
}
}
}
}
{
bannerExists: false
}
]
}) {
affiliate {
id
url
}
id
url
banner {
id
width
height
ratio
entity {
id
type

View File

@ -120,6 +120,7 @@ function initTagsActions(store, _router) {
id
width
height
ratio
entity {
id
type
@ -135,10 +136,8 @@ function initTagsActions(store, _router) {
}
}
campaigns {
affiliate {
id
url
}
id
url
entity {
id
type

View File

@ -1274,21 +1274,6 @@ exports.up = knex => Promise.resolve()
.notNullable()
.defaultTo(knex.fn.now());
}))
.then(() => knex.schema.createTable('affiliates', (table) => {
table.string('id')
.primary()
.unique()
.notNullable();
table.text('url')
.notNullable();
table.text('comment');
table.datetime('created_at')
.notNullable()
.defaultTo(knex.fn.now());
}))
.then(() => knex.schema.createTable('banners', (table) => {
table.string('id')
.primary()
@ -1338,15 +1323,15 @@ exports.up = knex => Promise.resolve()
.references('id')
.inTable('entities');
table.string('affiliate_id')
.notNullable()
.references('id')
.inTable('affiliates');
table.string('banner_id')
.references('id')
.inTable('banners');
table.text('url')
.notNullable();
table.text('comment');
table.datetime('created_at')
.notNullable()
.defaultTo(knex.fn.now());
@ -1370,8 +1355,8 @@ exports.up = knex => Promise.resolve()
CREATE UNIQUE INDEX unique_actor_slugs_network ON actors (slug, entity_id, entry_id);
CREATE UNIQUE INDEX unique_actor_slugs ON actors (slug) WHERE entity_id IS NULL;
CREATE UNIQUE INDEX unique_entity_campaigns_banner ON campaigns (entity_id, affiliate_id, banner_id);
CREATE UNIQUE INDEX unique_entity_campaigns ON campaigns (entity_id, affiliate_id) WHERE banner_id IS NULL;
CREATE UNIQUE INDEX unique_entity_campaigns_banner ON campaigns (entity_id, url, banner_id);
CREATE UNIQUE INDEX unique_entity_campaigns ON campaigns (entity_id, url) WHERE banner_id IS NULL;
CREATE UNIQUE INDEX releases_search_unique ON releases_search (release_id);
CREATE INDEX releases_search_index ON releases_search USING GIN (document);
@ -1561,6 +1546,10 @@ exports.up = knex => Promise.resolve()
CREATE FUNCTION releases_is_new(release releases) RETURNS boolean AS $$
SELECT EXISTS(SELECT true WHERE (SELECT id FROM batches ORDER BY created_at DESC LIMIT 1) = release.created_batch_id);
$$ LANGUAGE sql STABLE;
CREATE FUNCTION banners_ratio(banner banners) RETURNS real AS $$
SELECT ROUND(banner.width::decimal / banner.height::decimal, 2);
$$ LANGUAGE SQL STABLE;
`);
})
// POLICIES
@ -1729,7 +1718,6 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style
DROP TABLE IF EXISTS banners_tags CASCADE;
DROP TABLE IF EXISTS banners CASCADE;
DROP TABLE IF EXISTS affiliates CASCADE;
DROP TABLE IF EXISTS campaigns CASCADE;
DROP TABLE IF EXISTS batches CASCADE;

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -116,7 +116,7 @@ const tags = [
{
name: 'anal',
slug: 'anal',
description: 'Getting your asshole fucked. Generally considered naughtier, you may or may not find it a pleasurable alternative to vaginal sex. Enjoyable anal sex tends to require practice and patience, a rectal douching ritual, as well and a generous use of water-based lubricant to ensure comfort and prevent small tears that could lead to bacterial infections. Although you cannot get pregnant through anal sex directly, there is an increased risk of passing STDs, so the use of condoms and regular health checks are strongly recommended.',
description: 'Getting your asshole fucked. Generally considered naughtier, you may or may not find it a pleasurable alternative to vaginal sex.',
priority: 9,
group: 'penetration',
},

View File

@ -1,33 +1,48 @@
const bulkInsert = require('../src/utils/bulk-insert');
const affiliates = {
julesjordan_signup: {
url: 'https://enter.julesjordan.com/track/Mzk3MS4yLjMuNi4wLjAuMC4wLjA',
comment: '$30 per signup',
},
manuelferrara_signup: {
url: 'https://enter.manuelferrara.com/track/Mzk3MS4yLjcuMTYuMC4wLjAuMC4w',
comment: '$30 per signup',
},
spermswallowers_signup: {
url: 'https://enter.spermswallowers.com/track/Mzk3MS4yLjUuMTMuMC4wLjAuMC4w',
comment: '$30 per signup',
},
theassfactory_signup: {
url: 'https://enter.theassfactory.com/track/Mzk3MS4yLjEuMS4wLjAuMC4wLjA',
comment: '$30 per signup',
},
legalporno_new: {
url: 'https://www.legalporno.com/new-videos?aff=BW90MHT1DP____',
comment: 'default offer',
},
pornworld_new: {
url: 'https://pornworld.com/new-videos?aff=BW90MHT1DP____',
comment: 'default offer',
},
};
const banners = [
{
id: 'evilangel_728_90_adriana_chechik_gangbang',
width: 728,
height: 90,
network: 'evilangel',
tags: ['gangbang', 'airtight', 'dp', 'dvp', 'facial', 'brunette'],
},
{
id: 'evilangel_728_90_kenzie_reeves_lexi_lore',
width: 728,
height: 90,
network: 'evilangel',
tags: ['anal', 'mff', 'blowjob', 'blonde'],
},
{
id: 'evilangel_970_90_one_dollar',
width: 970,
height: 90,
network: 'evilangel',
tags: ['sex', 'mff'],
},
{
id: 'hardx_770_76_anal',
width: 770,
height: 76,
channel: 'hardx',
tags: ['anal', 'blonde'],
},
{
id: 'hardx_770_76_esperanza_anal',
width: 770,
height: 76,
channel: 'hardx',
tags: ['anal', 'brunette'],
},
{
id: 'hardx_770_76_zoey_monroe_mff',
width: 770,
height: 76,
channel: 'hardx',
tags: ['sex', 'mff', 'blonde'],
},
{
id: 'julesjordan_728_90_jill_kassidy',
width: 728,
@ -84,102 +99,194 @@ const banners = [
network: 'pornworld',
tags: ['mfm', 'sex', 'brunette'],
},
{
id: 'xempire_315_300',
width: 315,
height: 300,
network: 'xempire',
tags: ['blowbang', 'sex', 'black-cock', 'brunette'],
},
{
id: 'xempire_970_90_mff',
width: 970,
height: 90,
network: 'xempire',
tags: ['mff', '69', 'brunette'],
},
];
const links = [
const campaigns = [
{
network: 'julesjordan',
affiliate: 'julesjordan_signup',
network: 'evilangel',
url: 'https://www.iyalc.com/evilangel/go.php?pr=8&su=2&si=128&ad=277470&pa=index&ar=&buffer=',
comment: 'per signup',
},
{
network: 'evilangel',
banner: 'evilangel_728_90_adriana_chechik_gangbang',
url: 'https://www.iyalc.com/evilangel/go.php?pr=8&su=2&si=128&ad=277470&pa=index&ar=&buffer=',
comment: 'per signup',
},
{
network: 'evilangel',
banner: 'evilangel_728_90_kenzie_reeves_lexi_lore',
url: 'https://www.iyalc.com/evilangel/go.php?pr=8&su=2&si=128&ad=277470&pa=index&ar=&buffer=',
comment: 'per signup',
},
{
network: 'evilangel',
banner: 'evilangel_970_90_one_dollar',
url: 'https://www.iyalc.com/evilangel/go.php?pr=8&su=2&si=128&ad=277470&pa=index&ar=&buffer=',
comment: 'per signup',
},
{
channel: 'hardx',
url: 'https://www.blazinglink.com/hardx/go.php?pr=12&su=2&si=68&pa=index&ar=&ad=277470',
comment: '$30 per signup',
},
{
channel: 'hardx',
banner: 'hardx_770_76_anal',
url: 'https://www.blazinglink.com/hardx/go.php?pr=12&su=2&si=68&pa=index&ar=&ad=277470',
comment: '$30 per signup',
},
{
channel: 'hardx',
banner: 'hardx_770_76_esperanza_anal',
url: 'https://www.blazinglink.com/hardx/go.php?pr=12&su=2&si=68&pa=index&ar=&ad=277470',
comment: '$30 per signup',
},
{
channel: 'hardx',
banner: 'hardx_770_76_zoey_monroe_mff',
url: 'https://www.blazinglink.com/hardx/go.php?pr=12&su=2&si=68&pa=index&ar=&ad=277470',
comment: '$30 per signup',
},
{
network: 'julesjordan',
url: 'https://enter.julesjordan.com/track/Mzk3MS4yLjMuNi4wLjAuMC4wLjA',
comment: '$30 per signup',
},
{
network: 'julesjordan',
affiliate: 'julesjordan_signup',
banner: 'julesjordan_728_90_jill_kassidy',
url: 'https://enter.julesjordan.com/track/Mzk3MS4yLjMuNi4wLjAuMC4wLjA',
comment: '$30 per signup',
},
{
network: 'julesjordan',
affiliate: 'julesjordan_signup',
banner: 'julesjordan_728_90_angela_white',
url: 'https://enter.julesjordan.com/track/Mzk3MS4yLjMuNi4wLjAuMC4wLjA',
comment: '$30 per signup',
},
{
network: 'julesjordan',
affiliate: 'julesjordan_signup',
banner: 'julesjordan_728_90_adriana_chechik',
url: 'https://enter.julesjordan.com/track/Mzk3MS4yLjMuNi4wLjAuMC4wLjA',
comment: '$30 per signup',
},
{
network: 'julesjordan',
affiliate: 'julesjordan_signup',
banner: 'julesjordan_728_90_autumn_falls',
url: 'https://enter.julesjordan.com/track/Mzk3MS4yLjMuNi4wLjAuMC4wLjA',
comment: '$30 per signup',
},
{
network: 'julesjordan',
affiliate: 'julesjordan_signup',
banner: 'julesjordan_728_90_gabbie_carter',
url: 'https://enter.julesjordan.com/track/Mzk3MS4yLjMuNi4wLjAuMC4wLjA',
comment: '$30 per signup',
},
{
channel: 'manuelferrara',
affiliate: 'manuelferrara_signup',
url: 'https://enter.manuelferrara.com/track/Mzk3MS4yLjcuMTYuMC4wLjAuMC4w',
comment: '$30 per signup',
},
{
channel: 'manuelferrara',
affiliate: 'manuelferrara_signup',
banner: 'manuelferrara_728_90_asses',
url: 'https://enter.manuelferrara.com/track/Mzk3MS4yLjcuMTYuMC4wLjAuMC4w',
comment: '$30 per signup',
},
{
channel: 'spermswallowers',
affiliate: 'spermswallowers_signup',
url: 'https://enter.spermswallowers.com/track/Mzk3MS4yLjUuMTMuMC4wLjAuMC4w',
comment: '$30 per signup',
},
{
channel: 'theassfactory',
affiliate: 'theassfactory_signup',
url: 'https://enter.theassfactory.com/track/Mzk3MS4yLjEuMS4wLjAuMC4wLjA',
comment: '$30 per signup',
},
{
network: 'legalporno',
affiliate: 'legalporno_new',
url: 'https://www.legalporno.com/new-videos?aff=BW90MHT1DP____',
comment: 'default offer',
},
{
channel: 'legalporno',
affiliate: 'legalporno_new',
banner: 'pornworld_600_120_1',
url: 'https://www.legalporno.com/new-videos?aff=BW90MHT1DP____',
comment: 'default offer',
},
{
channel: 'legalporno',
affiliate: 'legalporno_new',
banner: 'pornworld_600_120_2',
url: 'https://www.legalporno.com/new-videos?aff=BW90MHT1DP____',
comment: 'default offer',
},
{
network: 'pornworld',
affiliate: 'pornworld_new',
url: 'https://pornworld.com/new-videos?aff=BW90MHT1DP____',
comment: 'default offer',
},
{
network: 'pornworld',
affiliate: 'pornworld_new',
banner: 'pornworld_600_120_1',
url: 'https://pornworld.com/new-videos?aff=BW90MHT1DP____',
comment: 'default offer',
},
{
network: 'pornworld',
affiliate: 'pornworld_new',
banner: 'pornworld_600_120_2',
url: 'https://pornworld.com/new-videos?aff=BW90MHT1DP____',
comment: 'default offer',
},
{
network: 'xempire',
url: 'https://www.blazinglink.com/xempire/go.php?pr=12&su=2&si=81&pa=index&ar=&ad=277470',
comment: '$30 per signup',
},
{
network: 'xempire',
banner: 'xempire_970_90_mff',
url: 'https://www.blazinglink.com/xempire/go.php?pr=12&su=2&si=81&pa=index&ar=&ad=277470',
comment: '$30 per signup',
},
{
network: 'xempire',
banner: 'xempire_315_300',
url: 'https://www.blazinglink.com/xempire/go.php?pr=12&su=2&si=81&pa=index&ar=&ad=277470',
comment: '$30 per signup',
},
];
exports.seed = async knex => Promise.resolve()
.then(async () => {
await knex('banners_tags').delete();
await Promise.all([
knex('campaigns').delete(),
knex('affiliates').delete(),
knex('banners').delete(),
]);
await bulkInsert('affiliates', Object.entries(affiliates).map(([key, value]) => ({ id: key, ...value })), false);
const [networks, channels, tags] = await Promise.all([
knex('entities')
.where('type', 'network')
.whereIn('slug', links.concat(banners).map(link => link.network).filter(Boolean)),
.whereIn('slug', campaigns.concat(banners).map(link => link.network).filter(Boolean)),
knex('entities')
.where('type', 'channel')
.whereIn('slug', links.concat(banners).map(link => link.channel).filter(Boolean)),
.whereIn('slug', campaigns.concat(banners).map(link => link.channel).filter(Boolean)),
knex('tags')
.whereIn('slug', banners.flatMap(banner => banner.tags || [])),
]);
@ -188,12 +295,6 @@ exports.seed = async knex => Promise.resolve()
const channelsBySlug = channels.reduce((acc, channel) => ({ ...acc, [channel.slug]: channel }), {});
const tagsBySlug = tags.reduce((acc, tag) => ({ ...acc, [tag.slug]: tag }), {});
const linksWithEntityIdAndAffiliateId = links.map(link => ({
entity_id: networksBySlug[link.network]?.id || channelsBySlug[link.channel]?.id,
affiliate_id: link.affiliate,
banner_id: link.banner,
})).filter(link => link.entity_id && link.affiliate_id);
const bannersWithEntityId = banners.map(banner => ({
id: banner.id,
width: banner.width,
@ -206,7 +307,15 @@ exports.seed = async knex => Promise.resolve()
tag_id: tagsBySlug[tag].id,
})) || []);
console.log(campaigns);
const campaignsWithEntityIdAndAffiliateId = campaigns.map(campaign => ({
entity_id: networksBySlug[campaign.network]?.id || channelsBySlug[campaign.channel]?.id,
url: campaign.url,
banner_id: campaign.banner,
})).filter(link => link.entity_id && link.url);
await bulkInsert('banners', bannersWithEntityId, false);
await bulkInsert('banners_tags', bannerTags, false);
await bulkInsert('campaigns', linksWithEntityIdAndAffiliateId, false);
await bulkInsert('campaigns', campaignsWithEntityIdAndAffiliateId, false);
});