Storing original tags.
|  | @ -244,7 +244,12 @@ const releaseDirectorFragment = ` | |||
| `;
 | ||||
| 
 | ||||
| const releaseTagsFragment = ` | ||||
|     tags: releasesTags(orderBy: TAG_BY_TAG_ID__PRIORITY_DESC) { | ||||
|     tags: releasesTags( | ||||
| 		orderBy: TAG_BY_TAG_ID__PRIORITY_DESC | ||||
| 		filter: { | ||||
| 			tagId: { isNull: false } | ||||
| 		} | ||||
| 	) { | ||||
|       tag { | ||||
|         name | ||||
|         priority | ||||
|  |  | |||
|  | @ -792,7 +792,6 @@ exports.up = knex => Promise.resolve() | |||
| 	})) | ||||
| 	.then(() => knex.schema.createTable('releases_tags', (table) => { | ||||
| 		table.integer('tag_id', 12) | ||||
| 			.notNullable() | ||||
| 			.references('id') | ||||
| 			.inTable('tags'); | ||||
| 
 | ||||
|  | @ -802,6 +801,8 @@ exports.up = knex => Promise.resolve() | |||
| 			.inTable('releases') | ||||
| 			.onDelete('cascade'); | ||||
| 
 | ||||
| 		table.text('original_tag'); | ||||
| 
 | ||||
| 		table.unique(['tag_id', 'release_id']); | ||||
| 	})) | ||||
| 	.then(() => knex.schema.createTable('releases_search', (table) => { | ||||
|  |  | |||
| After Width: | Height: | Size: 3.6 MiB | 
| After Width: | Height: | Size: 823 KiB | 
| After Width: | Height: | Size: 8.5 KiB | 
| After Width: | Height: | Size: 8.9 KiB | 
| After Width: | Height: | Size: 41 KiB | 
| After Width: | Height: | Size: 42 KiB | 
| After Width: | Height: | Size: 892 KiB | 
| After Width: | Height: | Size: 628 KiB | 
| After Width: | Height: | Size: 6.6 KiB | 
| After Width: | Height: | Size: 6.7 KiB | 
| After Width: | Height: | Size: 29 KiB | 
| After Width: | Height: | Size: 30 KiB | 
| After Width: | Height: | Size: 7.2 KiB | 
| After Width: | Height: | Size: 6.6 KiB | 
| After Width: | Height: | Size: 32 KiB | 
| After Width: | Height: | Size: 30 KiB | 
| After Width: | Height: | Size: 349 KiB | 
| After Width: | Height: | Size: 373 KiB | 
| After Width: | Height: | Size: 2.5 MiB | 
| After Width: | Height: | Size: 8.1 KiB | 
| After Width: | Height: | Size: 38 KiB | 
| After Width: | Height: | Size: 3.0 MiB | 
| After Width: | Height: | Size: 7.8 KiB | 
| After Width: | Height: | Size: 38 KiB | 
|  | @ -10471,7 +10471,7 @@ const sites = [ | |||
| 		name: 'West Coast Productions', | ||||
| 		slug: 'westcoastproductions', | ||||
| 		url: 'https://westcoastproductions.com', | ||||
| 		alias: ['wcp'], | ||||
| 		alias: ['wcp', 'wcpclub'], | ||||
| 		tags: ['black-cock'], | ||||
| 		parameters: { | ||||
| 			studio: false, | ||||
|  |  | |||
|  | @ -594,10 +594,12 @@ const tagMedia = [ | |||
| 	['69', 0, 'Abby Lee Brazil and Ramon Nomar', 'wicked'], | ||||
| 	['69', 4, 'Abella Danger and Karma Rx in "Neon Dreaming"', 'brazzers'], | ||||
| 	['69', 2, 'Abigail Mac and Kissa Sins in "Lesbian Anal Workout"', 'hardx'], | ||||
| 	['airtight', 'adriana_chechik_hope_howell_hopehowellxxx_1', 'Adriana Chechik and Hope Howell in "Hope And Adriana\'s Gangbang', 'hopehowellxxx'], | ||||
| 	['airtight', 7, 'Lana Rhoades in "Gangbang Me 3"', 'hardx'], | ||||
| 	['airtight', 'hime_marie_blackedraw', 'Hime Marie', 'blackedraw'], | ||||
| 	['airtight', 6, 'Remy Lacroix in "Ass Worship 14"', 'julesjordan'], | ||||
| 	['airtight', 'anissa_kate_legalporno', 'Anissa Kate in GP1962', 'legalporno'], | ||||
| 	['airtight', 'adriana_chechik_hope_howell_hopehowellxxx_1', 'Adriana Chechik and Hope Howell in "Hope And Adriana\'s Gangbang', 'hopehowellxxx'], | ||||
| 	['airtight', 'emily_willis_blacked', 'Emily Willis', 'blacked'], | ||||
| 	['airtight', 'diamond_foxxx_milfslikeitbig', 'Diamond Foxx in "Diamond\'s Bday Gangbang"', 'milfslikeitbig'], | ||||
| 	['airtight', 'tory_lane_bigtitsatwork', 'Tory Lane in "I\'m Your Christmas Bonus"', 'bigtitsatwork'], | ||||
| 	['airtight', 11, 'Malena Nazionale in "Rocco\'s Perverted Secretaries 2: Italian Edition"', 'roccosiffredi'], | ||||
|  | @ -610,6 +612,7 @@ const tagMedia = [ | |||
| 	['airtight', 5, 'Chloe Amour in "DP Masters 4"', 'julesjordan'], | ||||
| 	['airtight', 9, 'Cindy Shine in GP1658'], | ||||
| 	['anal', 5, 'Abella Danger', 'hardx'], | ||||
| 	['anal', 'alexa_flexy_private_1', 'Alexa Flexy in "Seeks Anal Volunteers"', 'private'], | ||||
| 	['anal', 'kira_noir_julesjordan', 'Kira Noir in "Kira Noir Opens Her Ass For Manuel"', 'julesjordan'], | ||||
| 	['anal', 'courtney_taylor_brazzers', 'Courtney Taylor in "Pounding That Pussy By The Pool"', 'brazzers'], | ||||
| 	['anal', 'kelly_oliveira_teenfidelity_1', 'Kelly Oliveira in "Keep It Going"', 'teenfidelity'], | ||||
|  | @ -689,6 +692,7 @@ const tagMedia = [ | |||
| 	['bts', 0, 'Janice Griffith in "Day With A Pornstar: Janice"', 'brazzers'], | ||||
| 	['bts', 1, 'Madison Ivy in "Day With A Pornstar"', 'brazzers'], | ||||
| 	['bts', 2, 'Christy Mack', 'digitalplayground'], | ||||
| 	['bukkake', 'yui_kawagoe_spermmania', 'Yui Kawagoe', 'spermmania'], | ||||
| 	['bukkake', 0, 'Jaye Summers in "Facialized 5"', 'hardx'], | ||||
| 	['bukkake', 'ana_foxxx_hardx', 'Ana Foxxx in "Facialized Vol. 4"', 'hardx'], | ||||
| 	['bukkake', 'jasmine_byrne_julesjordan', 'Jasmine Byrne in "Flesh Hunter 10"', 'julesjordan'], | ||||
|  | @ -896,6 +900,7 @@ const tagMedia = [ | |||
| 	['free-use', 'veruca_james_brazzersexxtra', 'Veruca James in "The Perfect Maid"', 'brazzersexxtra'], | ||||
| 	['gangbang', 5, 'Carter Cruise\'s first gangbang in "Slut Puppies 9"', 'julesjordan'], | ||||
| 	['gangbang', 'kristen_scott_julesjordan', 'Kristen Scott in "Interracial Gangbang!"', 'julesjordan'], | ||||
| 	['gangbang', 'emily_willis_blacked', 'Emily Willis', 'blacked'], | ||||
| 	['gangbang', 'monika_fox_legalporno', 'Monika Fox in GL479', 'legalporno'], | ||||
| 	['gangbang', 7, 'Alexa Flexy in GL376', 'legalporno'], | ||||
| 	['gangbang', 'silvia_dellai_legalporno', 'Silvia Dellai in GIO1825', 'legalporno'], | ||||
|  | @ -940,6 +945,7 @@ const tagMedia = [ | |||
| 	['mff', 'azul_hermosa_isis_love_pornstarslikeitbig', 'Azul Hermosa, Isis Love and Zac Wild in "She Likes Rough Quickies"', 'pornstarslikeitbig'], | ||||
| 	['mfm', 'kyra_black_21sextury', 'Kyra Black', '21sextury'], | ||||
| 	['mfm', 'juelz_ventura_babygotboobs_3a', 'Juelz Ventura in "A Deep DP For Dessert"', 'babygotboobs'], | ||||
| 	['mfm', 'emily_willis_blacked', 'Emily Willis', 'blacked'], | ||||
| 	['mfm', 0, 'Vina Sky in "Jules Jordan\'s Three Ways"', 'julesjordan'], | ||||
| 	['mfm', 'anne_amari_wefuckblackgirls', 'Anne Amari', 'wefuckblackgirls'], | ||||
| 	['mfm', 8, 'Ariana Marie in "DP Masters 7"', 'julesjordan'], | ||||
|  |  | |||
							
								
								
									
										18
									
								
								src/tags.js
								
								
								
								
							
							
						
						|  | @ -117,22 +117,26 @@ async function getEntityTags(releases) { | |||
| function buildReleaseTagAssociations(releases, tagIdsBySlug, entityTagIdsByEntityId, type) { | ||||
| 	const tagAssociations = releases | ||||
| 		.map((release) => { | ||||
| 			const entityTagIds = entityTagIdsByEntityId[release.entity?.id] || []; | ||||
| 			const releaseTags = release.tags || []; | ||||
| 			const entityTagIds = entityTagIdsByEntityId[release.entity?.id].map(tag => ({ id: tag.id, origin: tag.name })) || []; | ||||
| 			const releaseTags = release.tags?.filter(Boolean) || []; | ||||
| 
 | ||||
| 			const releaseTagIds = releaseTags.every(tag => typeof tag === 'number') | ||||
| 			const releaseTagsWithIds = releaseTags.every(tag => typeof tag === 'number') | ||||
| 				? releaseTags // obsolete scraper returned pre-matched tags
 | ||||
| 				: releaseTags.map(tag => tagIdsBySlug[slugify(tag)]); | ||||
| 				: releaseTags.map(tag => ({ | ||||
| 					id: tagIdsBySlug[slugify(tag)], | ||||
| 					original: tag, | ||||
| 				})); | ||||
| 
 | ||||
| 			const tags = [...new Set( | ||||
| 				// filter duplicates and empties
 | ||||
| 				releaseTagIds | ||||
| 				releaseTagsWithIds | ||||
| 					.concat(entityTagIds) | ||||
| 					.filter(Boolean), | ||||
| 			)] | ||||
| 				.map(tagId => ({ | ||||
| 				.map(tag => ({ | ||||
| 					[`${type}_id`]: release.id, | ||||
| 					tag_id: tagId, | ||||
| 					tag_id: tag.id, | ||||
| 					original_tag: tag.original, | ||||
| 				})); | ||||
| 
 | ||||
| 			return tags; | ||||
|  |  | |||