Skip to content

Commit

Permalink
Make all optional attributes nullable instead of arbitrary values
Browse files Browse the repository at this point in the history
  • Loading branch information
Hedon-dev committed Sep 29, 2024
1 parent 0adc620 commit 87983fa
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 60 deletions.
54 changes: 33 additions & 21 deletions lib/plugins/official_plugins/pornhub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class PornhubPlugin extends PluginBase implements PluginInterface {
.split(":")
.map((e) => int.parse(e))
.toList();
Duration duration = const Duration(seconds: -1);
Duration? duration;
if (durationList != null) {
duration = Duration(seconds: durationList[0] * 60 + durationList[1]);
}
Expand Down Expand Up @@ -199,14 +199,17 @@ class PornhubPlugin extends PluginBase implements PluginInterface {
.trim();

// determine video views
int views = 0;
int? views;
String? viewsString = resultDiv
.querySelector('span[class="views"]')
?.querySelector("var")
?.text;

// just added means 0, means skip the whole part coz views is already 0
if (viewsString != "just added" && viewsString != null) {
if (viewsString == "just added") {
views = 0;
} else if (viewsString != null) {
views = 0;
if (viewsString.endsWith("K")) {
if (viewsString.contains(".")) {
views = int.parse(viewsString.split(".")[1][0]) * 100;
Expand All @@ -228,7 +231,7 @@ class PornhubPlugin extends PluginBase implements PluginInterface {
int.parse(viewsString.substring(0, viewsString.length - 1)) *
1000000;
} else {
views = int.parse(viewsString);
views = int.tryParse(viewsString);
}
}

Expand All @@ -237,7 +240,7 @@ class PornhubPlugin extends PluginBase implements PluginInterface {
?.querySelector("div")
?.text
.trim();
int ratings = -1;
int? ratings;
if (ratingsString != null) {
ratings =
int.parse(ratingsString.substring(0, ratingsString.length - 1));
Expand Down Expand Up @@ -281,7 +284,7 @@ class PornhubPlugin extends PluginBase implements PluginInterface {
jscript.lastIndexOf('autoFullscreen":true};') + 21));

// ratings
int? ratingsPositive = -1;
int? ratingsPositive;
String? ratingsPositiveString =
rawHtml.querySelector('span[class="votesUp"]')?.text;
if (ratingsPositiveString != null) {
Expand All @@ -290,11 +293,11 @@ class PornhubPlugin extends PluginBase implements PluginInterface {
0, ratingsPositiveString.length - 1)) *
1000;
} else {
ratingsPositive = int.parse(ratingsPositiveString);
ratingsPositive = int.tryParse(ratingsPositiveString);
}
}

int? ratingsNegative = -1;
int? ratingsNegative;
String? ratingsNegativeString =
rawHtml.querySelector('span[class="votesDown"]')?.text;
if (ratingsNegativeString != null) {
Expand All @@ -303,22 +306,26 @@ class PornhubPlugin extends PluginBase implements PluginInterface {
0, ratingsNegativeString.length - 1)) *
1000;
} else {
ratingsNegative = int.parse(ratingsNegativeString);
ratingsNegative = int.tryParse(ratingsNegativeString);
}
}

int ratingsTotal = ratingsPositive + ratingsNegative;
int? ratingsTotal;
if (ratingsPositive != null || ratingsNegative != null) {
ratingsTotal = ratingsPositive! + ratingsNegative!;
}

// convert views string into views total int
int? viewsTotal = -1;
int viewsDecimal = 0;
int? viewsTotal;
String? viewsString = rawHtml
.querySelector('div[class="ratingInfo"]')
?.querySelector('div[class="views"]')
?.querySelector("span")
?.text;

if (viewsString != null) {
viewsTotal = 0;
int viewsDecimal = 0;
if (viewsString.contains(".")) {
// round to the nearest 100
viewsDecimal = int.parse(viewsString.split(".")[1][0]) * 100;
Expand Down Expand Up @@ -354,27 +361,30 @@ class PornhubPlugin extends PluginBase implements PluginInterface {
.querySelector('div[class="pornstarsWrapper js-pornstarsWrapper"]')
?.querySelectorAll("a");

List<String> actors = [];
List<String>? actors = [];
if (actorsList != null) {
for (Element element in actorsList) {
actors.add(element.text);
}
}
if (actors.isEmpty) {
actors = null;
}

// categories
List<Element>? categoriesList = rawHtml
.querySelector('div[class="categoriesWrapper"]')
?.querySelectorAll("a");

List<String> categories = [];
List<String>? categories = [];
if (categoriesList != null) {
for (Element element in categoriesList) {
categories.add(element.text);
}
}

// TODO: Either find actual date or convert apprx date given by pornhub to unix
DateTime date = DateTime.utc(1970, 1, 1);
if (categories.isEmpty) {
categories = null;
}

Map<int, Uri> m3u8Map = {};
for (Map<String, dynamic> video in jscriptMap["mediaDefinitions"]) {
Expand All @@ -390,20 +400,22 @@ class PornhubPlugin extends PluginBase implements PluginInterface {
return UniversalVideoMetadata(
videoID: videoId,
m3u8Uris: m3u8Map,
title: jscriptMap["video_title"],
title: jscriptMap["video_title"] ?? "-",
plugin: this,
author: authorString,
authorID: authorId,
actors: actors,
description: rawHtml.querySelector(".ab-info > p:nth-child(1)")?.text ??
"No description",
description: rawHtml.querySelector(".ab-info > p:nth-child(1)")?.text,
viewsTotal: viewsTotal,
tags: null,
categories: categories,
uploadDate: date,
// TODO: Either find actual date or convert approx date given by pornhub to unix
uploadDate: null,
ratingsPositiveTotal: ratingsPositive,
ratingsNegativeTotal: ratingsNegative,
ratingsTotal: ratingsTotal,
virtualReality: jscriptMap["isVR"] == 1,
chapters: null,
rawHtml: rawHtml);
}

Expand Down
97 changes: 58 additions & 39 deletions lib/plugins/official_plugins/xhamster.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,24 @@ class XHamsterPlugin extends PluginBase implements PluginInterface {
.startsWith("thumb-list__item video-thumb")) {
// each result has 2 sub-divs
List<Element>? subElements = resultDiv.children;
String? author = subElements[1]

Element? uploaderElement = subElements[1]
.querySelector('div[class="video-thumb-uploader"]')
?.children[0]
.querySelector('a[class="video-uploader__name"]')
?.text
.trim();
?.children[0];
String? author;
if (uploaderElement != null) {
// Amateur videos don't have an uploader on the results page
if (uploaderElement.children.length == 1 &&
uploaderElement.children[0].className == "video-thumb-views") {
author = "Unknown amateur author";
} else {
author = uploaderElement
.querySelector('a[class="video-uploader__name"]')
?.text
.trim();
}
}

String? thumbnail =
subElements[0].querySelector('img')?.attributes['src'];
String? videoPreview = subElements[0].attributes['data-previewvideo'];
Expand All @@ -119,7 +131,7 @@ class XHamsterPlugin extends PluginBase implements PluginInterface {
.map((e) => int.parse(e))
.toList();

Duration duration = const Duration(seconds: -1);
Duration? duration;
if (durationList.length == 2) {
duration =
Duration(seconds: durationList[0] * 60 + durationList[1]);
Expand All @@ -132,7 +144,7 @@ class XHamsterPlugin extends PluginBase implements PluginInterface {
}

// determine video resolution
int resolution = 0;
int? resolution;
bool virtualReality = false;
if (subElements[0].querySelector('i[class^="xh-icon"]') != null) {
switch (subElements[0]
Expand All @@ -145,23 +157,23 @@ class XHamsterPlugin extends PluginBase implements PluginInterface {
case "beta-thumb-uhd":
resolution = 2160;
case "beta-thumb-vr":
resolution = -1;
virtualReality = true;
}
} else {
resolution = -1;
}

// determine video views
int views = 0;
String viewsString = subElements[1]
.querySelector("div[class='video-thumb-views']")!
.text
int? views;
String? viewsString = subElements[1]
.querySelector("div[class='video-thumb-views']")
?.text
.trim()
.split(" views")[0];

// just added means 0, means skip the whole part coz views is already 0
if (viewsString != "just added") {
if (viewsString == "just added") {
views = 0;
} else if (viewsString != null) {
views = 0;
if (viewsString.endsWith("K")) {
if (viewsString.contains(".")) {
views = int.parse(viewsString.split(".")[1][0]) * 100;
Expand All @@ -183,23 +195,20 @@ class XHamsterPlugin extends PluginBase implements PluginInterface {
int.parse(viewsString.substring(0, viewsString.length - 1)) *
1000000;
} else {
views = int.parse(viewsString);
views = int.tryParse(viewsString);
}
}

results.add(UniversalSearchResult(
videoID: iD ?? "-",
title: title ?? "-",
plugin: this,
author: author ?? "-",
// XHamster only shows verified authors names on the results page
// -> If author name was scraped, then the author is verified
verifiedAuthor: author != null,
thumbnail: thumbnail,
videoPreview: videoPreview != null ? Uri.parse(videoPreview) : null,
duration: duration,
viewsTotal: views,
// TODO: Find a way to determine ratings (dont seem to be in the html)
ratingsPositivePercent: null,
maxQuality: resolution,
virtualReality: virtualReality,
));
Expand All @@ -225,23 +234,30 @@ class XHamsterPlugin extends PluginBase implements PluginInterface {
rawHtml.querySelector('.with-player-container > h1:nth-child(1)');

// ratings
List<String> ratingRaw =
rawHtml.querySelector(".rb-new__info")!.text.split(" / ");
int ratingsPositive = int.parse(ratingRaw[0].replaceAll(",", ""));
int ratingsNegative = int.parse(ratingRaw[1].replaceAll(",", ""));
int ratingsTotal = ratingsPositive + ratingsNegative;
List<String>? ratingRaw =
rawHtml.querySelector(".rb-new__info")?.text.split(" / ");
int? ratingsPositive;
int? ratingsNegative;
int? ratingsTotal;
if (ratingRaw != null) {
ratingsPositive = int.tryParse(ratingRaw[0].replaceAll(",", ""));
ratingsNegative = int.tryParse(ratingRaw[1].replaceAll(",", ""));
if (ratingsPositive != null && ratingsNegative != null) {
ratingsTotal = ratingsPositive + ratingsNegative;
}
}

// Inside the script element, find the views
String viewsString = jscript.split('"views":').last;
int viewsTotal =
int.parse(viewsString.substring(0, viewsString.indexOf(',')));
int? viewsTotal =
int.tryParse(viewsString.substring(0, viewsString.indexOf(',')));

// author
Element? authorRaw = rawHtml.querySelector(".video-tag--subscription");

// Assume the account doesn't exist anymore
String authorString = "Unavailable";
String authorId = "unavailable";
String? authorString;
String? authorId;
if (authorRaw != null) {
// Most authors have a profile picture. However, those that do not, get a
// Letter instead of their profile picture. This letter then gets caught
Expand All @@ -262,8 +278,8 @@ class XHamsterPlugin extends PluginBase implements PluginInterface {
// First element is always the author -> remove it
rawContainer.children.removeAt(0);
// categories and actors are in the same list -> sort into two lists
List<String> categories = [];
List<String> actors = [];
List<String>? categories = [];
List<String>? actors = [];
for (Element element in rawContainer.children) {
if (element.children[0].attributes["href"] != null) {
if (element.children[0].attributes["href"]!
Expand All @@ -275,9 +291,15 @@ class XHamsterPlugin extends PluginBase implements PluginInterface {
}
}
}
if (categories.isEmpty) {
categories = null;
}
if (actors.isEmpty) {
actors = null;
}

// Use the tooltip as video upload date
DateTime date = DateTime.utc(1970, 1, 1);
DateTime? date;
String? dateString = rawHtml
.querySelector(
'div[class="entity-info-container__date tooltip-nocache"]')
Expand All @@ -295,10 +317,8 @@ class XHamsterPlugin extends PluginBase implements PluginInterface {
try {
date = DateTime.parse(dateString);
} on FormatException {
logger.w("COULDNT CONVERT DATE TO DATETIME!!! SETTING TO 1970");
logger.w("Couldnt convert date to datetime: $dateString");
}
} else {
logger.w("COULDNT FIND DATE!!! SETTING TO 1970");
}

if (videoTitle == null ||
Expand All @@ -319,17 +339,16 @@ class XHamsterPlugin extends PluginBase implements PluginInterface {
author: authorString,
authorID: authorId,
actors: actors,
description:
rawHtml.querySelector(".ab-info > p:nth-child(1)")?.text ??
"No description",
description: rawHtml.querySelector(".ab-info > p:nth-child(1)")?.text,
viewsTotal: viewsTotal,
// xhamster does not have tags
tags: null,
categories: categories,
uploadDate: date,
ratingsPositiveTotal: ratingsPositive,
ratingsNegativeTotal: ratingsNegative,
ratingsTotal: ratingsTotal,
virtualReality: false,
chapters: null,
rawHtml: rawHtml);
}
}
Expand Down

0 comments on commit 87983fa

Please sign in to comment.