diff --git a/Contents/Code/PAsiteList.py b/Contents/Code/PAsiteList.py index ee8258896..5c7a6c784 100644 --- a/Contents/Code/PAsiteList.py +++ b/Contents/Code/PAsiteList.py @@ -188,6 +188,7 @@ import siteBrandNewAmateurs import sitePornbox import siteJesseLoadsMonsterFacials +import networkGASM searchSites = { 0: ('BlackedRaw', 'https://www.blackedraw.com', '/graphql'), @@ -1956,6 +1957,23 @@ 1863: ('Touch My Wife', 'http://www.touchmywife.com', 'https://tsmkfa364q-dsn.algolia.net/1/indexes/*/queries'), 1864: ('Taboo Heat', 'http://www.tabooheat.com', 'https://tsmkfa364q-dsn.algolia.net/1/indexes/*/queries'), 1865: ('B Skow', 'http://www.bskow.com', 'https://tsmkfa364q-dsn.algolia.net/1/indexes/*/queries'), + 1866: ('GASM', 'https://www.gasm.com', '/search/videos?s='), + 1867: ('Magma Film', 'https://www.gasm.com', '/search/videos?s='), + 1868: ('JapanHD', 'https://www.gasm.com', '/search/videos?s='), + 1869: ('Pure XXX Films', 'https://www.gasm.com', '/search/videos?s='), + 1870: ('Harmony Vision', 'https://www.gasm.com', '/search/videos?s='), + 1871: ('Paradise Films', 'https://www.gasm.com', '/search/videos?s='), + 1872: ('Leche69', 'https://www.gasm.com', '/search/videos?s='), + 1873: ('Cosplay Babes', 'https://www.gasm.com', '/search/videos?s='), + 1874: ('Fun Movies', 'https://www.gasm.com', '/search/videos?s='), + 1875: ('MMV Films', 'https://www.gasm.com', '/search/videos?s='), + 1876: ('Inflagranti', 'https://www.gasm.com', '/search/videos?s='), + 1877: ('Hot Gold', 'https://www.gasm.com', '/search/videos?s='), + 1878: ('The Undercover Lover', 'https://www.gasm.com', '/search/videos?s='), + 1879: ('Herzog', 'https://www.gasm.com', '/search/videos?s='), + 1880: ('Butt Formation', 'https://www.gasm.com', '/search/videos?s='), + 1881: ('PornXN', 'https://www.gasm.com', '/search/videos?s='), + 1882: ('Filthy and Fisting', 'https://www.gasm.com', '/search/videos?s='), } abbreviations = ( @@ -2087,6 +2105,7 @@ ('^ht ', 'Hogtied '), ('^hussieauditions', 'HussiePass'), ('^hustl3r ', 'Hustler '), + ('^hv ', 'HarmonyVision '), ('^ihaw ', 'IHaveAWife '), ('^iktg ', 'IKnowThatGirl '), ('^il ', 'ImmoralLive '), @@ -2182,6 +2201,7 @@ ('^ps ', 'PropertySex '), ('^ptt ', 'Petite '), ('^pud ', 'PublicDisgrace '), + ('^pxf ', 'PureXXXFilms '), ('^pyx ', 'PurgatoryX '), ('^reg ', 'RealExGirlfriends '), ('^rkp ', 'RKPrime '), @@ -3283,4 +3303,8 @@ def getProviderFromSiteNum(siteNum): elif siteNum == 1824: provider = siteJesseLoadsMonsterFacials + # GASM + elif 1866 <= siteNum <= 1882: + provider = networkGASM + return provider diff --git a/Contents/Code/PAutils.py b/Contents/Code/PAutils.py index bc65e4039..93dd1c3b9 100644 --- a/Contents/Code/PAutils.py +++ b/Contents/Code/PAutils.py @@ -288,6 +288,7 @@ def parseTitle(s, siteNum): s = re.sub(r'\,(?![\s|\d])', ', ', s) s = s.replace('_', ' ') s = s.replace('’', '\'') + s = s.replace('´', '\'') s = preParseTitle(s) word_list = re.split(' ', s) diff --git a/Contents/Code/networkGASM.py b/Contents/Code/networkGASM.py new file mode 100644 index 000000000..504389972 --- /dev/null +++ b/Contents/Code/networkGASM.py @@ -0,0 +1,153 @@ +import PAsearchSites +import PAutils + + +def search(results, lang, siteNum, searchData): + sceneID = None + parts = searchData.title.split() + if unicode(parts[0], 'UTF-8').isdigit(): + sceneID = parts[0] + searchData.title = searchData.title.replace(sceneID, '', 1).strip() + + if sceneID: + sceneURL = '%s/post/details/%s' % (PAsearchSites.getSearchBaseURL(siteNum), sceneID) + req = PAutils.HTTPRequest(sceneURL) + searchResult = HTML.ElementFromString(req.text) + + titleNoFormatting = searchResult.xpath('//h1[@class="post_title"]/span')[0].text_content() + curID = PAutils.Encode(sceneURL) + subSite = PAutils.parseTitle(searchResult.xpath('//a[contains(@href, "/studio/profile/")]')[0].text_content().split(':')[-1].strip(), siteNum) + + date = searchResult.xpath('//h3[@class="post_date"]') + if date: + releaseDate = datetime.strptime(date[0].text_content().strip(), '%b %d, %Y').strftime('%Y-%m-%d') + else: + releaseDate = searchData.dateFormat() if searchData.date else '' + displayDate = releaseDate if date else '' + + score = 100 + + results.Append(MetadataSearchResult(id='%s|%d|%s' % (curID, siteNum, releaseDate), name='%s [%s] %s' % (PAutils.parseTitle(titleNoFormatting, siteNum), subSite, displayDate), score=score, lang=lang)) + else: + searchData.encoded = slugify(searchData.title, lowercase=True, separator='+') + searchURL = PAsearchSites.getSearchSearchURL(siteNum) + searchData.encoded + if 1867 <= siteNum <= 1882: + searchURL = '%s&channel=%s' % (searchURL, PAutils.getDictKeyFromValues(channelIdDB, PAsearchSites.getSearchSiteName(siteNum).lower())[0]) + req = PAutils.HTTPRequest(searchURL) + searchResults = HTML.ElementFromString(req.text) + + for searchResult in searchResults.xpath('//div[contains(@class, "results_item")]'): + titleNoFormatting = searchResult.xpath('.//a[@class="post_title"]')[0].text_content() + curID = PAutils.Encode(searchResult.xpath('.//a[@class="post_title"]/@href')[0]) + subSite = PAutils.parseTitle(searchResult.xpath('.//a[@class="post_channel"]')[0].text_content().split(':')[-1].strip(), siteNum) + searchID = searchResult.xpath('.//div[contains(@class, "post_item")]/@data-post-id')[0] + + releaseDate = searchData.dateFormat() if searchData.date else '' + + if sceneID and int(sceneID) == searchID: + score = 100 + else: + score = 100 - Util.LevenshteinDistance(searchData.title.lower(), titleNoFormatting.lower()) + + results.Append(MetadataSearchResult(id='%s|%d|%s' % (curID, siteNum, releaseDate), name='%s [%s]' % (PAutils.parseTitle(titleNoFormatting, siteNum), subSite), score=score, lang=lang)) + + return results + + +def update(metadata, lang, siteNum, movieGenres, movieActors, art): + metadata_id = str(metadata.id).split('|') + sceneURL = PAutils.Decode(metadata_id[0]) + if not sceneURL.startswith('http'): + sceneURL = PAsearchSites.getSearchBaseURL(siteNum) + sceneURL + sceneDate = metadata_id[2] + req = PAutils.HTTPRequest(sceneURL) + detailsPageElements = HTML.ElementFromString(req.text) + + # Title + metadata.title = PAutils.parseTitle(detailsPageElements.xpath('//h1[@class="post_title"]/span')[0].text_content().strip(), siteNum) + + # Summary + metadata.summary = detailsPageElements.xpath('//h2[@class="post_description"]')[0].text_content() + + # Studio + metadata.studio = 'GASM' + + # Tagline and Collection(s) + tagline = PAutils.parseTitle(detailsPageElements.xpath('//a[contains(@href, "/studio/profile/")]')[0].text_content().strip(), siteNum) + metadata.tagline = tagline + metadata.collections.add(tagline) + + # Release Date + date = detailsPageElements.xpath('//h3[@class="post_date"]') + if date: + date_object = datetime.strptime(date[0].text_content().strip(), '%b %d, %Y') + metadata.originally_available_at = date_object + metadata.year = metadata.originally_available_at.year + elif sceneDate: + date_object = parse(sceneDate) + metadata.originally_available_at = date_object + metadata.year = metadata.originally_available_at.year + + # Genres + for genreLink in detailsPageElements.xpath('//a[contains(@href, "/search?s=")]'): + genreName = genreLink.text_content().strip() + + movieGenres.addGenre(genreName) + + # Actor(s) + for actorLink in detailsPageElements.xpath('//a[contains(@href, "models/")]'): + actorName = actorLink.text_content().strip() + actorPhotoURL = '' + + movieActors.addActor(actorName, actorPhotoURL) + + # Posters/Background + xpaths = [ + '//img[@class="item_cover"]/@src', + '//meta[@name="twitter:image"]/@content' + ] + + for xpath in xpaths: + for poster in detailsPageElements.xpath(xpath): + art.append(poster) + + Log('Artwork found: %d' % len(art)) + for idx, posterUrl in enumerate(art, 1): + if not PAsearchSites.posterAlreadyExists(posterUrl, metadata): + # Download image file for analysis + try: + image = PAutils.HTTPRequest(posterUrl) + im = StringIO(image.content) + resized_image = Image.open(im) + width, height = resized_image.size + # Add the image proxy items to the collection + if width > 1: + # Item is a poster + metadata.posters[posterUrl] = Proxy.Media(image.content, sort_order=idx) + if width > height: + # Item is an art item + metadata.art[posterUrl] = Proxy.Media(image.content, sort_order=idx) + except: + pass + + return metadata + + +channelIdDB = { + '23': ['harmony vision'], + '102': ['butt formation'], + '105': ['pure xxx films'], + '8110': ['cosplay babes'], + '8111': ['filthy and fisting'], + '8112': ['fun movies'], + '8113': ['herzog'], + '8114': ['hot gold'], + '8115': ['inflagranti'], + '8116': ['japanhd'], + '8117': ['Leche69'], + '8118': ['magma film'], + '8119': ['mmv films'], + '8120': ['paradise films'], + '8121': ['pornxn'], + '8122': ['the undercover lover'], +} diff --git a/docs/sitelist.md b/docs/sitelist.md index 120a4c8e7..47a54c2ba 100644 --- a/docs/sitelist.md +++ b/docs/sitelist.md @@ -636,6 +636,23 @@ If you're having difficulty finding the SceneID, double-check [PAsiteList.py](.. - POV Perverts - Twisted Visual + #### Gangbang Creampie | ✅ ++ #### GASM | ✅ + - Butt Formation + - Cosplay Babes + - Filthy and Fisting + - Fun Movies + - Harmony Vision + - Herzog + - Hot Gold + - Inflagranti + - JapanHD + - Leche69 + - Magma Film + - MMV Films + - Paradise Films + - PornXN + - Pure XXX Films + - The Undercover Lover + #### Gender X | ✅ + #### Girl Grind | ✅ + #### GirlfriendsFilms | ✅