mirror of
https://github.com/AAndyProgram/SCrawler.git
synced 2026-03-14 15:52:18 +00:00
API.Mastodon: hide 503 error API.PornHub: minor fixes API.RedGifs: fix 'DataGone' Minor bugs
939 lines
48 KiB
VB.net
939 lines
48 KiB
VB.net
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
|
|
' This program is free software: you can redistribute it and/or modify
|
|
' it under the terms of the GNU General Public License as published by
|
|
' the Free Software Foundation, either version 3 of the License, or
|
|
' (at your option) any later version.
|
|
'
|
|
' This program is distributed in the hope that it will be useful,
|
|
' but WITHOUT ANY WARRANTY
|
|
Imports System.Threading
|
|
Imports SCrawler.API.Base
|
|
Imports SCrawler.API.YouTube.Objects
|
|
Imports PersonalUtilities.Functions.XML
|
|
Imports PersonalUtilities.Functions.RegularExpressions
|
|
Imports PersonalUtilities.Tools.Web.Clients
|
|
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
|
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
|
Namespace API.PornHub
|
|
Friend Class UserData : Inherits UserDataBase
|
|
Private Const UrlPattern As String = "https://www.pornhub.com/{0}"
|
|
#Region "Declarations"
|
|
#Region "XML names"
|
|
Private Const Name_PersonType As String = "PersonType"
|
|
Private Const Name_NameTrue As String = "NameTrue"
|
|
Private Const Name_PhotoPageModel As String = "PhotoPageModel"
|
|
Private Const Name_DownloadUHD As String = "DownloadUHD"
|
|
Private Const Name_DownloadUploaded As String = "DownloadUploaded"
|
|
Private Const Name_DownloadTagged As String = "DownloadTagged"
|
|
Private Const Name_DownloadPrivate As String = "DownloadPrivate"
|
|
Private Const Name_DownloadFavorite As String = "DownloadFavorite"
|
|
Private Const Name_DownloadGifs As String = "DownloadGifs"
|
|
Private Const Name_DownloadPhotoOnlyFromModelHub As String = "DownloadPhotoOnlyFromModelHub"
|
|
Private Const Name_IsUser As String = "IsUser"
|
|
#End Region
|
|
#Region "Structures"
|
|
Private Structure FlashVar : Implements IRegExCreator
|
|
Friend Name As String
|
|
Friend Value As String
|
|
Public Shared Widening Operator CType(ByVal Name As String) As FlashVar
|
|
Return New FlashVar With {.Name = Name}
|
|
End Operator
|
|
Private Function CreateFromArray(ByVal ParamsArray() As String) As Object Implements IRegExCreator.CreateFromArray
|
|
If ParamsArray.ListExists(2) Then
|
|
Name = ParamsArray(0)
|
|
Value = ParamsArray(1)
|
|
If Not Value.IsEmptyString Then Value = Value.Replace(""" + """, String.Empty).Replace("""", String.Empty).StringTrim
|
|
End If
|
|
Return Me
|
|
End Function
|
|
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
|
|
Return CType(Obj, FlashVar).Name = Name
|
|
End Function
|
|
End Structure
|
|
Private Structure UserVideo : Implements IRegExCreator
|
|
Friend URL As String
|
|
Friend ID As String
|
|
Friend Title As String
|
|
Friend Type As VideoTypes
|
|
Friend Function ToUserMedia(Optional ByVal SpecialFolder As String = Nothing) As UserMedia
|
|
Return New UserMedia(URL, UTypes.VideoPre) With {
|
|
.File = If(Title.IsEmptyString, .File, New SFile($"{Title}.mp4")),
|
|
.Post = ID,
|
|
.SpecialFolder = SpecialFolder
|
|
}
|
|
End Function
|
|
Private Function CreateFromArray(ByVal ParamsArray() As String) As Object Implements IRegExCreator.CreateFromArray
|
|
If ParamsArray.ListExists(4) Then
|
|
URL = ParamsArray(0)
|
|
ID = RegexReplace(URL, RegexVideo_Video_VideoKey)
|
|
If ID.IsEmptyString Then
|
|
URL = String.Empty
|
|
Else
|
|
URL = String.Format(UrlPattern, URL.TrimStart("/"))
|
|
Title = TitleHtmlConverter(ParamsArray(1))
|
|
If Not ParamsArray(2).IsEmptyString Then
|
|
Type = VideoTypes.Private
|
|
ElseIf Not ParamsArray(3).IsEmptyString Then
|
|
Type = VideoTypes.Tagged
|
|
Else
|
|
Type = VideoTypes.Uploaded
|
|
End If
|
|
End If
|
|
End If
|
|
Return Me
|
|
End Function
|
|
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
|
|
Return DirectCast(Obj, UserVideo).URL = URL
|
|
End Function
|
|
End Structure
|
|
Private Structure PhotoBlock : Implements IRegExCreator
|
|
Friend AlbumID As String
|
|
Friend Data As String
|
|
Private Function CreateFromArray(ByVal ParamsArray() As String) As Object Implements IRegExCreator.CreateFromArray
|
|
If ParamsArray.ListExists(2) Then
|
|
AlbumID = ParamsArray(0)
|
|
Data = ParamsArray(1).StringTrim
|
|
End If
|
|
Return Me
|
|
End Function
|
|
End Structure
|
|
#End Region
|
|
#Region "Enums"
|
|
Private Enum PhotoPageModels As Integer
|
|
Undefined = 0
|
|
PornHubPage = 1
|
|
ModelHubPage = 2
|
|
End Enum
|
|
Private Enum VideoTypes
|
|
Undefined
|
|
Uploaded
|
|
[Private]
|
|
Tagged
|
|
Favorite
|
|
End Enum
|
|
#End Region
|
|
#Region "Constants"
|
|
Private Const PersonTypeModel As String = "model"
|
|
Private Const PersonTypeUser As String = "users"
|
|
Private Const PersonTypePornstar As String = "pornstar"
|
|
Private Const PersonTypeCannel As String = "channels"
|
|
#End Region
|
|
#Region "Person"
|
|
Friend Property PersonType As String
|
|
Friend Property NameTrue As String
|
|
Friend Overrides Property FriendlyName As String
|
|
Get
|
|
If _FriendlyName.IsEmptyString Then Return NameTrue Else Return _FriendlyName
|
|
End Get
|
|
Set(ByVal n As String)
|
|
_FriendlyName = n
|
|
End Set
|
|
End Property
|
|
#End Region
|
|
#Region "Advanced fields"
|
|
Friend Overrides ReadOnly Property FeedIsUser As Boolean
|
|
Get
|
|
Return IsUser
|
|
End Get
|
|
End Property
|
|
Private Property PhotoPageModel As PhotoPageModels = PhotoPageModels.Undefined
|
|
Friend Property DownloadUHD As Boolean = False
|
|
Friend Property DownloadUploaded As Boolean = True
|
|
Friend Property DownloadTagged As Boolean = False
|
|
Friend Property DownloadPrivate As Boolean = False
|
|
Friend Property DownloadFavorite As Boolean = False
|
|
Friend Property DownloadGifs As Boolean
|
|
Friend Property DownloadPhotoOnlyFromModelHub As Boolean = True
|
|
Private _IsUser As Boolean = True
|
|
Friend Overrides ReadOnly Property IsUser As Boolean
|
|
Get
|
|
Return _IsUser
|
|
End Get
|
|
End Property
|
|
Friend Property QueryString As String
|
|
Get
|
|
If IsUser Then
|
|
Return String.Empty
|
|
Else
|
|
Return GetNonUserUrl(0)
|
|
End If
|
|
End Get
|
|
Set(ByVal q As String)
|
|
UpdateUserOptions(True, q)
|
|
End Set
|
|
End Property
|
|
Friend Overrides ReadOnly Property SpecialLabels As IEnumerable(Of String)
|
|
Get
|
|
Return {SearchRequestLabelName}
|
|
End Get
|
|
End Property
|
|
#End Region
|
|
#Region "ExchangeOptions"
|
|
Friend Overrides Function ExchangeOptionsGet() As Object
|
|
Return New UserExchangeOptions(Me)
|
|
End Function
|
|
Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
|
|
If Not Obj Is Nothing AndAlso TypeOf Obj Is UserExchangeOptions Then
|
|
With DirectCast(Obj, UserExchangeOptions)
|
|
DownloadUHD = .DownloadUHD
|
|
DownloadUploaded = .DownloadUploaded
|
|
DownloadTagged = .DownloadTagged
|
|
DownloadPrivate = .DownloadPrivate
|
|
DownloadFavorite = .DownloadFavorite
|
|
DownloadGifs = .DownloadGifs
|
|
DownloadPhotoOnlyFromModelHub = .DownloadPhotoOnlyFromModelHub
|
|
QueryString = .QueryString
|
|
End With
|
|
End If
|
|
End Sub
|
|
#End Region
|
|
Private ReadOnly Property MySettings As SiteSettings
|
|
Get
|
|
Return DirectCast(HOST.Source, SiteSettings)
|
|
End Get
|
|
End Property
|
|
Private ReadOnly LastPageIDs As List(Of String)
|
|
#End Region
|
|
#Region "Initializer"
|
|
Friend Sub New()
|
|
LastPageIDs = New List(Of String)
|
|
UseInternalM3U8Function = True
|
|
UseClientTokens = True
|
|
End Sub
|
|
#End Region
|
|
#Region "Loader"
|
|
Private Function UpdateUserOptions(Optional ByVal Force As Boolean = False, Optional ByVal NewUrl As String = Nothing) As Boolean
|
|
|
|
If Not Force OrElse (Not IsUser AndAlso Not NewUrl.IsEmptyString AndAlso MyFileSettings.Exists) Then
|
|
Dim eObj As Plugin.ExchangeOptions = Nothing
|
|
If Force Then eObj = MySettings.IsMyUser(NewUrl)
|
|
If (Force And Not eObj.UserName.IsEmptyString) Or (Not Force And Not Name.IsEmptyString And NameTrue.IsEmptyString) Then
|
|
If Not If(Force, eObj.Options, Options).IsEmptyString Then
|
|
If IsUser And Force Then
|
|
Return False
|
|
Else
|
|
_IsUser = False
|
|
Options = If(Force, eObj.Options, Options)
|
|
NameTrue = Options
|
|
If Not Force Then
|
|
Settings.Labels.Add(SearchRequestLabelName)
|
|
Labels.ListAddValue(SearchRequestLabelName, LNC)
|
|
Labels.Sort()
|
|
Return True
|
|
End If
|
|
End If
|
|
Else
|
|
_IsUser = True
|
|
Dim n$() = Name.Split("_")
|
|
If n.ListExists(2) Then
|
|
NameTrue = Name.Replace($"{n(0)}_", String.Empty)
|
|
PersonType = n(0)
|
|
End If
|
|
End If
|
|
End If
|
|
End If
|
|
Return False
|
|
End Function
|
|
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
|
|
With Container
|
|
If Loading Then
|
|
PersonType = .Value(Name_PersonType)
|
|
NameTrue = .Value(Name_NameTrue)
|
|
PhotoPageModel = .Value(Name_PhotoPageModel).FromXML(Of Integer)(PhotoPageModels.Undefined)
|
|
DownloadUHD = .Value(Name_DownloadUHD).FromXML(Of Boolean)(False)
|
|
DownloadUploaded = .Value(Name_DownloadUploaded).FromXML(Of Boolean)(True)
|
|
DownloadTagged = .Value(Name_DownloadTagged).FromXML(Of Boolean)(False)
|
|
DownloadPrivate = .Value(Name_DownloadPrivate).FromXML(Of Boolean)(False)
|
|
DownloadFavorite = .Value(Name_DownloadFavorite).FromXML(Of Boolean)(False)
|
|
DownloadGifs = .Value(Name_DownloadGifs).FromXML(Of Integer)(False)
|
|
DownloadPhotoOnlyFromModelHub = .Value(Name_DownloadPhotoOnlyFromModelHub).FromXML(Of Boolean)(True)
|
|
_IsUser = .Value(Name_IsUser).FromXML(Of Boolean)(True)
|
|
UpdateUserOptions()
|
|
Else
|
|
If UpdateUserOptions() Then .Value(Name_LabelsName) = LabelsString
|
|
.Add(Name_PersonType, PersonType)
|
|
.Add(Name_NameTrue, NameTrue)
|
|
.Add(Name_PhotoPageModel, CInt(PhotoPageModel))
|
|
.Add(Name_DownloadUHD, DownloadUHD.BoolToInteger)
|
|
.Add(Name_DownloadUploaded, DownloadUploaded.BoolToInteger)
|
|
.Add(Name_DownloadTagged, DownloadTagged.BoolToInteger)
|
|
.Add(Name_DownloadPrivate, DownloadPrivate.BoolToInteger)
|
|
.Add(Name_DownloadFavorite, DownloadFavorite.BoolToInteger)
|
|
.Add(Name_DownloadGifs, DownloadGifs.BoolToInteger)
|
|
.Add(Name_DownloadPhotoOnlyFromModelHub, DownloadPhotoOnlyFromModelHub.BoolToInteger)
|
|
.Add(Name_IsUser, IsUser.BoolToInteger)
|
|
|
|
'Debug.WriteLine(GetNonUserUrl(0))
|
|
'Debug.WriteLine(GetNonUserUrl(2))
|
|
End If
|
|
End With
|
|
End Sub
|
|
#End Region
|
|
#Region "Downloading"
|
|
#Region "Download override"
|
|
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
|
|
Try
|
|
Responser.ResetStatus()
|
|
|
|
If IsSavedPosts Then
|
|
PersonType = PersonTypeUser
|
|
NameTrue = MySettings.SavedPostsUserName.Value
|
|
End If
|
|
|
|
Dim limit% = If(DownloadTopCount, -1)
|
|
If DownloadVideos Then
|
|
|
|
If IsSavedPosts Or Not IsUser Or PersonType = PersonTypeUser Then
|
|
DownloadUserVideos(1, VideoTypes.Favorite, False, Token)
|
|
Else
|
|
If DownloadUploaded Then
|
|
LastPageIDs.Clear()
|
|
DownloadUserVideos(1, VideoTypes.Uploaded, False, Token)
|
|
End If
|
|
If DownloadTagged Then
|
|
LastPageIDs.Clear()
|
|
Dim lBefore% = _TempMediaList.Count
|
|
DownloadUserVideos(1, VideoTypes.Tagged, False, Token)
|
|
If PersonType = PersonTypePornstar And lBefore = _TempMediaList.Count Then
|
|
LastPageIDs.Clear()
|
|
DownloadUserVideos(1, VideoTypes.Tagged, True, Token)
|
|
End If
|
|
End If
|
|
If DownloadPrivate Then
|
|
LastPageIDs.Clear()
|
|
DownloadUserVideos(1, VideoTypes.Private, False, Token)
|
|
End If
|
|
If DownloadFavorite Then
|
|
LastPageIDs.Clear()
|
|
DownloadUserVideos(1, VideoTypes.Favorite, False, Token)
|
|
End If
|
|
End If
|
|
|
|
If _TempMediaList.Count > 0 Then
|
|
_TempMediaList.RemoveAll(Function(m) Not m.Type = UTypes.m3u8 And Not m.Type = UTypes.VideoPre)
|
|
If limit > 0 And _TempMediaList.Count > limit Then _TempMediaList.ListAddList(_TempMediaList.ListTake(-1, limit), LAP.ClearBeforeAdd)
|
|
End If
|
|
End If
|
|
|
|
If DownloadGifs And Not IsSavedPosts And Not IsSubscription And IsUser Then DownloadUserGifs(Token)
|
|
If DownloadImages And Not IsSubscription And IsUser Then DownloadUserPhotos(Token)
|
|
Finally
|
|
Responser.Mode = Responser.Modes.Default
|
|
Responser.Method = "GET"
|
|
ProgressPre.Done()
|
|
End Try
|
|
End Sub
|
|
#End Region
|
|
#Region "Download video"
|
|
Friend Function GetNonUserUrl(ByVal Page As Integer) As String
|
|
If IsUser Then
|
|
Return String.Empty
|
|
Else
|
|
Dim url$ = $"https://www.pornhub.com/{Options}"
|
|
If Page > 1 Then
|
|
If url.Contains("?") Then
|
|
url &= $"&page={Page}"
|
|
Else
|
|
url = url.TrimEnd("/")
|
|
url &= $"?page={Page}"
|
|
End If
|
|
End If
|
|
Return url
|
|
End If
|
|
End Function
|
|
Private Sub DownloadUserVideos(ByVal Page As Integer, ByVal Type As VideoTypes, ByVal SecondMode As Boolean, ByVal Token As CancellationToken)
|
|
Dim URL$ = String.Empty
|
|
ProgressPre.ChangeMax(1)
|
|
Try
|
|
Dim specFolder$ = String.Empty
|
|
Dim tryNextPage As Boolean = False
|
|
Dim limit% = If(DownloadTopCount, -1)
|
|
If IsUser Then
|
|
URL = $"https://www.pornhub.com/{PersonType}/{NameTrue}"
|
|
If Type = VideoTypes.Uploaded Then
|
|
URL &= "/videos/upload"
|
|
ElseIf Type = VideoTypes.Tagged Then
|
|
If Not SecondMode Then URL &= "/videos"
|
|
specFolder = "Tagged"
|
|
ElseIf Type = VideoTypes.Private Then
|
|
URL &= "/videos/private"
|
|
specFolder = "Private"
|
|
ElseIf Type = VideoTypes.Favorite Then
|
|
URL &= "/videos/favorites"
|
|
If Not PersonType = PersonTypeUser Then specFolder = "Favorite"
|
|
Else
|
|
Throw New ArgumentException($"Type '{Type}' is not implemented in the video download function", "Type")
|
|
End If
|
|
If Page > 1 Then URL &= $"?page={Page}"
|
|
Else
|
|
URL = GetNonUserUrl(Page)
|
|
End If
|
|
|
|
ThrowAny(Token)
|
|
|
|
'Debug.WriteLine(URL)
|
|
Dim r$ = Responser.GetResponse(URL)
|
|
If Not r.IsEmptyString Then
|
|
Dim l As List(Of UserVideo) = RegexFields(Of UserVideo)(r, {RegexUserVideos}, {6, 7, 3, 10})
|
|
If l.ListExists Then l = l.ListTake(3, l.Count).ToList
|
|
If l.ListExists Then
|
|
If IsUser Then
|
|
If Type = VideoTypes.Favorite Then
|
|
l.RemoveAll(Function(uv) uv.Type = VideoTypes.Private)
|
|
ElseIf Not PersonType = PersonTypeCannel Then
|
|
l.RemoveAll(Function(uv) Not uv.Type = Type)
|
|
End If
|
|
End If
|
|
If l.Count > 0 Then l.RemoveAll(Function(uv) uv.ID.IsEmptyString Or uv.URL.IsEmptyString)
|
|
If l.Count > 0 Then
|
|
Dim lBefore% = l.Count
|
|
Dim nonLastPageDetected As Boolean = False
|
|
Dim newLastPageIDs As New List(Of String)
|
|
l.RemoveAll(Function(ByVal uv As UserVideo) As Boolean
|
|
If Not _TempPostsList.Contains(uv.ID) Then
|
|
_TempPostsList.Add(uv.ID)
|
|
newLastPageIDs.Add(uv.ID)
|
|
Return False
|
|
Else
|
|
If Not LastPageIDs.Contains(uv.ID) Then nonLastPageDetected = True
|
|
'Debug.WriteLine($"[REMOVED]: {uv.Title}")
|
|
Return True
|
|
End If
|
|
End Function)
|
|
'Debug.WriteLineIf(l.Count > 0, l.Select(Function(ll) ll.Title).ListToString(vbNewLine))
|
|
If l.Count > 0 Then _TempMediaList.ListAddList(l.Select(Function(uv) uv.ToUserMedia(specFolder)))
|
|
LastPageIDs.Clear()
|
|
If newLastPageIDs.Count > 0 Then LastPageIDs.AddRange(newLastPageIDs) : newLastPageIDs.Clear()
|
|
If l.Count > 0 AndAlso (l.Count = lBefore Or Not nonLastPageDetected) AndAlso
|
|
Not (limit > 0 And _TempMediaList.Count >= limit) Then tryNextPage = True
|
|
End If
|
|
End If
|
|
End If
|
|
|
|
If tryNextPage Then DownloadUserVideos(Page + 1, Type, SecondMode, Token)
|
|
Catch regex_ex As RegexFieldsTextBecameNullException
|
|
If Not IsSavedPosts Then MyMainLOG = $"{ToStringForLog()}: videos not found. You may need to update your credentials."
|
|
Catch ex As Exception
|
|
ProcessException(ex, Token, $"videos downloading error [{URL}]")
|
|
Finally
|
|
ProgressPre.Perform()
|
|
End Try
|
|
End Sub
|
|
#End Region
|
|
#Region "Download GIF"
|
|
Private Sub DownloadUserGifs(ByVal Token As CancellationToken)
|
|
Dim URL$ = $"https://www.pornhub.com/{PersonType}/{NameTrue}/gifs"
|
|
Try
|
|
ThrowAny(Token)
|
|
Dim r$ = Responser.GetResponse(URL)
|
|
If Not r.IsEmptyString Then
|
|
Dim n$
|
|
Dim m As UserMedia = Nothing
|
|
Dim l As List(Of RegexMatchStruct) = RegexFields(Of RegexMatchStruct)(r, {Regex_Gif_Array}, {1}, EDP.ReturnValue)
|
|
Dim l2 As List(Of String) = Nothing
|
|
Dim l3 As List(Of String) = Nothing
|
|
If l.ListExists Then l2 = l.Select(Function(ll) $"gif/{ll.Arr(0).Replace("gif", String.Empty)}").ToList
|
|
If l2.ListExists Then
|
|
ProgressPre.ChangeMax(l2.Count)
|
|
For Each gif$ In l2
|
|
If Not _TempPostsList.Contains(gif) Then
|
|
_TempPostsList.Add(gif)
|
|
URL = $"https://www.pornhub.com/{gif}"
|
|
m = New UserMedia(URL, UTypes.Video) With {.Post = gif, .SpecialFolder = "GIFs\"}
|
|
ProgressPre.Perform()
|
|
ThrowAny(Token)
|
|
Try
|
|
r = Responser.GetResponse(URL)
|
|
If Not r.IsEmptyString Then
|
|
If l3.ListExists Then l3.Clear() : l3 = Nothing
|
|
l3 = RegexReplace(r, Regex_Gif_UrlName)
|
|
If l3.ListExists(3) Then
|
|
m.URL = l3(2)
|
|
m.File = m.URL
|
|
n = TitleHtmlConverter(l3(1))
|
|
If MySettings.DownloadGifsAsMp4.Value Then m.File.Extension = "mp4"
|
|
If Not n.IsEmptyString Then m.File.Name = n
|
|
End If
|
|
End If
|
|
Catch gif_down_ex As Exception
|
|
m.State = UserMedia.States.Missing
|
|
End Try
|
|
_TempMediaList.ListAddValue(m)
|
|
End If
|
|
Next
|
|
End If
|
|
If l.ListExists Then l.Clear()
|
|
If l2.ListExists Then l2.Clear()
|
|
If l3.ListExists Then l3.Clear()
|
|
End If
|
|
Catch ex As Exception
|
|
ProcessException(ex, Token, $"gifs downloading error [{URL}]")
|
|
End Try
|
|
End Sub
|
|
#End Region
|
|
#Region "Download photo"
|
|
Private Function CreatePhotoFile(ByVal URL As String, ByVal File As SFile) As SFile
|
|
Dim pFile$ = RegexReplace(URL, Regex_Photo_File)
|
|
If Not pFile.IsEmptyString Then Return New SFile(pFile) Else Return File
|
|
End Function
|
|
Private Const PhotoUrlPattern_ModelHub As String = "https://www.modelhub.com/{0}/photos"
|
|
Private Const PhotoUrlPattern_PornHub As String = "https://www.pornhub.com/{0}/{1}/photos"
|
|
Private Sub DownloadUserPhotos(ByVal Token As CancellationToken)
|
|
Try
|
|
If IsSavedPosts Then
|
|
DownloadUserPhotos_SavedPosts(Token)
|
|
ElseIf PersonType = PersonTypeModel Then
|
|
If PhotoPageModel = PhotoPageModels.Undefined Then
|
|
If DownloadUserPhotos_ModelHub(Token) Then PhotoPageModel = PhotoPageModels.ModelHubPage
|
|
ThrowAny(Token)
|
|
If PhotoPageModel = PhotoPageModels.Undefined AndAlso Not DownloadPhotoOnlyFromModelHub AndAlso
|
|
DownloadUserPhotos_PornHub(Token) Then PhotoPageModel = PhotoPageModels.PornHubPage
|
|
Else
|
|
Select Case PhotoPageModel
|
|
Case PhotoPageModels.ModelHubPage : DownloadUserPhotos_ModelHub(Token)
|
|
Case PhotoPageModels.PornHubPage : If Not DownloadPhotoOnlyFromModelHub Then DownloadUserPhotos_PornHub(Token)
|
|
End Select
|
|
End If
|
|
ElseIf Not DownloadPhotoOnlyFromModelHub Then
|
|
DownloadUserPhotos_PornHub(Token)
|
|
End If
|
|
ThrowAny(Token)
|
|
Catch ex As Exception
|
|
ProcessException(ex, Token, "photos downloading error")
|
|
End Try
|
|
End Sub
|
|
Private Function DownloadUserPhotos_ModelHub(ByVal Token As CancellationToken) As Boolean
|
|
Dim URL$ = String.Empty
|
|
Try
|
|
Dim j As EContainer
|
|
Dim jErr As New ErrorsDescriber(EDP.SendToLog + EDP.ReturnValue)
|
|
Dim albumName$
|
|
If PersonType = PersonTypeModel Then
|
|
URL = String.Format(PhotoUrlPattern_ModelHub, NameTrue)
|
|
Dim r$ = Responser.GetResponse(URL)
|
|
If Not r.IsEmptyString Then
|
|
Dim l As List(Of PhotoBlock) = RegexFields(Of PhotoBlock)(r, {Regex_Photo_ModelHub_PhotoBlocks}, {1, 2}, EDP.ReturnValue)
|
|
If l.ListExists Then l.RemoveAll(Function(ll) ll.Data.IsEmptyString)
|
|
If l.ListExists Then
|
|
ProgressPre.ChangeMax(l.Count)
|
|
Dim albumRegex As RParams = RParams.DMS("", 1, EDP.ReturnValue)
|
|
For Each block As PhotoBlock In l
|
|
ProgressPre.Perform()
|
|
If Not _TempPostsList.Contains(block.AlbumID) Then _TempPostsList.Add(block.AlbumID) Else Continue For
|
|
albumRegex.Pattern = "<li id=""" & block.AlbumID & """ class=""modelBox"">[\r\n\s]*?<div class=""modelPhoto"">[\r\n\s]*?\<[^\>]*?alt=""([^""]*)"""
|
|
albumName = StringTrim(RegexReplace(r, albumRegex))
|
|
If albumName.IsEmptyString Then albumName = block.AlbumID
|
|
j = JsonDocument.Parse("{" & block.Data & "}", jErr)
|
|
If Not j Is Nothing Then
|
|
If If(j("urls")?.Count, 0) > 0 Then
|
|
_TempMediaList.ListAddList(j("urls").Select(Function(jj) _
|
|
New UserMedia(jj.ItemF({0}).XmlIfNothingValue, UTypes.Picture) With {
|
|
.SpecialFolder = $"Albums\{albumName}\",
|
|
.File = CreatePhotoFile(.URL, .File)}), LNC)
|
|
End If
|
|
j.Dispose()
|
|
End If
|
|
Next
|
|
l.Clear()
|
|
End If
|
|
End If
|
|
End If
|
|
Return True
|
|
Catch ex As Exception
|
|
ThrowAny(Token)
|
|
Return False
|
|
End Try
|
|
End Function
|
|
Private Overloads Function DownloadUserPhotos_PornHub(ByVal Token As CancellationToken) As Boolean
|
|
Try
|
|
Dim albumName$
|
|
Dim page%
|
|
Dim r$ = Responser.GetResponse(String.Format(PhotoUrlPattern_PornHub, PersonType, NameTrue))
|
|
If Not r.IsEmptyString Then
|
|
Dim l As List(Of PhotoBlock) = RegexFields(Of PhotoBlock)(r, {Regex_Photo_PornHub_PhotoBlocks}, {2, 1}, EDP.ReturnValue)
|
|
If l.ListExists Then l.RemoveAll(Function(ll) ll.AlbumID.IsEmptyString)
|
|
If l.ListExists Then
|
|
ProgressPre.ChangeMax(l.Count)
|
|
For Each block As PhotoBlock In l
|
|
ProgressPre.Perform()
|
|
If Not _TempPostsList.Contains(block.AlbumID) Then _TempPostsList.Add(block.AlbumID) Else Continue For
|
|
albumName = block.Data
|
|
If albumName.IsEmptyString Then
|
|
albumName = block.AlbumID.Split("/").LastOrDefault.StringTrim
|
|
Else
|
|
albumName = TitleHtmlConverter(albumName)
|
|
End If
|
|
page = 1
|
|
Do While DownloadUserPhotos_PornHub(page, block.AlbumID, albumName, Token) : page += 1 : Loop
|
|
Next
|
|
l.Clear()
|
|
End If
|
|
End If
|
|
Return True
|
|
Catch ex As Exception
|
|
ThrowAny(Token)
|
|
Return False
|
|
End Try
|
|
End Function
|
|
Private Overloads Function DownloadUserPhotos_PornHub(ByVal Page As Integer, ByVal AlbumID As String, ByVal AlbumName As String,
|
|
ByVal Token As CancellationToken) As Boolean
|
|
Try
|
|
Dim r$ = Responser.GetResponse($"https://www.pornhub.com{AlbumID}{IIf(Page = 1, String.Empty, $"?page={Page}")}")
|
|
If Not r.IsEmptyString Then
|
|
Dim l As List(Of String) = RegexReplace(r, Regex_Photo_PornHub_AlbumPhotoArr)
|
|
If l.ListExists Then l.RemoveAll(Function(_url) _url.IsEmptyString)
|
|
If l.ListExists Then
|
|
ProgressPre.ChangeMax(l.Count)
|
|
For Each url$ In l
|
|
ProgressPre.Perform()
|
|
ThrowAny(Token)
|
|
Try
|
|
r = Responser.GetResponse(url)
|
|
If Not r.IsEmptyString Then
|
|
url = RegexReplace(r, Regex_Photo_PornHub_SinglePhoto)
|
|
If Not url.IsEmptyString Then _
|
|
_TempMediaList.ListAddValue(New UserMedia(url, UTypes.Picture) With {
|
|
.SpecialFolder = $"Albums\{AlbumName}\",
|
|
.File = CreatePhotoFile(url, .File)}, LNC)
|
|
End If
|
|
Catch
|
|
End Try
|
|
Next
|
|
l.Clear()
|
|
Return True
|
|
End If
|
|
End If
|
|
Return False
|
|
Catch ex As Exception
|
|
ThrowAny(Token)
|
|
Return False
|
|
End Try
|
|
End Function
|
|
Private Function DownloadUserPhotos_SavedPosts(ByVal Token As CancellationToken) As Boolean
|
|
Const HtmlPageNotFoundPhoto$ = "Page Not Found"
|
|
Dim URL$ = $"https://www.pornhub.com/{PersonType}/{NameTrue}/photos/favorites"
|
|
Try
|
|
Dim r$ = Responser.GetResponse(URL)
|
|
If Not r.IsEmptyString Then
|
|
If r.Contains(HtmlPageNotFoundPhoto) Then Return False
|
|
Dim urls As List(Of String) = RegexReplace(r, Regex_Photo_PornHub_AlbumPhotoArr)
|
|
If urls.ListExists Then
|
|
Dim NewUrl$, pFile$
|
|
Dim m As UserMedia
|
|
Dim l2 As List(Of UserMedia) = urls.Select(Function(__url) New UserMedia(__url, UTypes.Picture) With {
|
|
.Post = __url.Split("/").LastOrDefault}).ToList
|
|
urls.Clear()
|
|
If l2.ListExists Then l2.RemoveAll(Function(media) media.URL.IsEmptyString)
|
|
If l2.ListExists Then
|
|
Dim lBefore% = l2.Count
|
|
If _TempPostsList.Count > 0 Then l2.RemoveAll(Function(media) _TempPostsList.Contains(media.Post.ID))
|
|
If l2.Count > 0 Then
|
|
ProgressPre.ChangeMax(l2.Count)
|
|
For i% = 0 To l2.Count - 1
|
|
ProgressPre.Perform()
|
|
m = l2(i)
|
|
ThrowAny(Token)
|
|
Try
|
|
r = Responser.GetResponse(m.URL)
|
|
If Not r.IsEmptyString Then
|
|
NewUrl = RegexReplace(r, Regex_Photo_PornHub_SinglePhoto)
|
|
If Not NewUrl.IsEmptyString Then
|
|
m.URL = NewUrl
|
|
pFile = RegexReplace(NewUrl, Regex_Photo_File)
|
|
If Not pFile.IsEmptyString Then m.File = pFile Else m.File = NewUrl
|
|
_TempPostsList.ListAddValue(m.Post.ID, LNC)
|
|
Else
|
|
Throw New Exception
|
|
End If
|
|
End If
|
|
Catch
|
|
m.State = UserMedia.States.Missing
|
|
End Try
|
|
_TempMediaList.ListAddValue(m, LNC)
|
|
Next
|
|
End If
|
|
Return l2.Count = lBefore
|
|
End If
|
|
End If
|
|
End If
|
|
Return False
|
|
Catch ex As Exception
|
|
Return ProcessException(ex, Token, $"photos downloading error [{URL}]") = 1
|
|
End Try
|
|
End Function
|
|
#End Region
|
|
#End Region
|
|
#Region "ReparseVideo"
|
|
Protected Overloads Overrides Sub ReparseVideo(ByVal Token As CancellationToken)
|
|
If IsSubscription Then
|
|
ReparseVideoSubscriptions(Token)
|
|
Else
|
|
ReparseVideo(Token, False)
|
|
End If
|
|
End Sub
|
|
Private Overloads Sub ReparseVideo(ByVal Token As CancellationToken, ByVal CreateFileName As Boolean,
|
|
Optional ByRef Data As IYouTubeMediaContainer = Nothing)
|
|
Const ERR_NEW_URL$ = "ERR_NEW_URL"
|
|
Dim URL$ = String.Empty
|
|
Try
|
|
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(tm) tm.Type = UTypes.VideoPre) Then
|
|
Dim m As UserMedia
|
|
Dim r$, NewUrl$, tmpName$
|
|
ProgressPre.ChangeMax(_TempMediaList.Count)
|
|
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
|
ProgressPre.Perform()
|
|
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
|
m = _TempMediaList(i)
|
|
ThrowAny(Token)
|
|
Try
|
|
URL = m.URL
|
|
r = Responser.Curl(URL)
|
|
If Not r.IsEmptyString Then
|
|
NewUrl = CreateVideoURL(r)
|
|
If NewUrl.IsEmptyString Then
|
|
Throw New Exception With {.HelpLink = ERR_NEW_URL}
|
|
Else
|
|
m.URL = NewUrl
|
|
m.Type = UTypes.m3u8
|
|
If CreateFileName Then
|
|
tmpName = RegexReplace(r, RegexVideoPageTitle)
|
|
If Not tmpName.IsEmptyString Then
|
|
If Not Data Is Nothing Then Data.Title = tmpName
|
|
m.File.Name = TitleHtmlConverter(tmpName)
|
|
m.File.Extension = "mp4"
|
|
End If
|
|
End If
|
|
_TempMediaList(i) = m
|
|
End If
|
|
Else
|
|
_TempMediaList.RemoveAt(i)
|
|
End If
|
|
Catch mid_ex As Exception
|
|
If mid_ex.HelpLink = ERR_NEW_URL OrElse DownloadingException(mid_ex, "") = 1 Then
|
|
m.State = UserMedia.States.Missing
|
|
_TempMediaList(i) = m
|
|
Else
|
|
_TempMediaList.RemoveAt(i)
|
|
End If
|
|
End Try
|
|
End If
|
|
Next
|
|
End If
|
|
Catch ex As Exception
|
|
ProcessException(ex, Token, "video reparsing error", False)
|
|
End Try
|
|
End Sub
|
|
Private Sub ReparseVideoSubscriptions(ByVal Token As CancellationToken)
|
|
Try
|
|
If _TempMediaList.Count > 0 AndAlso _TempMediaList.Exists(Function(tm) tm.Type = UTypes.VideoPre) Then
|
|
Dim m As UserMedia
|
|
Dim r$, URL$, tmpName$, thumb$
|
|
Dim c% = 0
|
|
Dim rErr As New ErrorsDescriber(EDP.ReturnValue)
|
|
Progress.Maximum += _TempMediaList.Count
|
|
For i% = _TempMediaList.Count - 1 To 0 Step -1
|
|
Progress.Perform()
|
|
If _TempMediaList(i).Type = UTypes.VideoPre Then
|
|
If Not DownloadTopCount.HasValue OrElse c <= DownloadTopCount.Value Then
|
|
m = _TempMediaList(i)
|
|
ThrowAny(Token)
|
|
Try
|
|
URL = m.URL_BASE
|
|
r = Responser.GetResponse(URL,, rErr)
|
|
If Not r.IsEmptyString Then
|
|
m.Type = UTypes.m3u8
|
|
|
|
thumb = RegexReplace(r, Regex_VideosThumb_OG_IMAGE)
|
|
If Not thumb.IsEmptyString Then m.URL = thumb
|
|
|
|
tmpName = RegexReplace(r, RegexVideoPageTitle)
|
|
If Not tmpName.IsEmptyString Then
|
|
m.File.Name = TitleHtmlConverter(tmpName)
|
|
m.File.Extension = "mp4"
|
|
m.PictureOption = tmpName
|
|
End If
|
|
|
|
_TempMediaList(i) = m
|
|
c += 1
|
|
Else
|
|
_TempMediaList.RemoveAt(i)
|
|
End If
|
|
Catch mid_ex As Exception
|
|
_TempMediaList.RemoveAt(i)
|
|
End Try
|
|
Else
|
|
_TempMediaList.RemoveAt(i)
|
|
End If
|
|
End If
|
|
Next
|
|
End If
|
|
Catch ex As Exception
|
|
ProcessException(ex, Token, "subscriptions video reparsing error", False)
|
|
End Try
|
|
End Sub
|
|
#End Region
|
|
#Region "ReparseMissing"
|
|
Protected Overrides Sub ReparseMissing(ByVal Token As CancellationToken)
|
|
Dim rList As New List(Of Integer)
|
|
Try
|
|
If ContentMissingExists Then
|
|
Dim m As UserMedia
|
|
Dim r$
|
|
Dim eCurl As New ErrorsDescriber(EDP.ReturnValue)
|
|
ProgressPre.ChangeMax(_ContentList.Count)
|
|
For i% = 0 To _ContentList.Count - 1
|
|
ProgressPre.Perform()
|
|
m = _ContentList(i)
|
|
If m.State = UserMedia.States.Missing AndAlso Not m.URL_BASE.IsEmptyString Then
|
|
ThrowAny(Token)
|
|
r = Responser.Curl(m.URL_BASE,, eCurl)
|
|
If Not r.IsEmptyString Then
|
|
Dim NewUrl$ = CreateVideoURL(r)
|
|
If Not NewUrl.IsEmptyString Then
|
|
m.URL = NewUrl
|
|
_TempMediaList.ListAddValue(m, LNC)
|
|
rList.Add(i)
|
|
End If
|
|
End If
|
|
End If
|
|
Next
|
|
End If
|
|
Catch ex As Exception
|
|
ProcessException(ex, Token, "missing data downloading error")
|
|
Finally
|
|
If rList.Count > 0 Then
|
|
For i% = rList.Count - 1 To 0 Step -1 : _ContentList.RemoveAt(rList(i)) : Next
|
|
rList.Clear()
|
|
End If
|
|
End Try
|
|
End Sub
|
|
#End Region
|
|
#Region "Download content"
|
|
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
|
DownloadContentDefault(Token)
|
|
End Sub
|
|
Protected Overrides Function DownloadM3U8(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile, ByVal Token As CancellationToken) As SFile
|
|
Return M3U8.Download(URL, Responser, DestinationFile, DownloadUHD, Token, Progress, Not IsSingleObjectDownload)
|
|
End Function
|
|
#End Region
|
|
#Region "CreateVideoURL"
|
|
Private Function CreateVideoURL(ByVal r As String) As String
|
|
If r.IsEmptyString Then
|
|
Return String.Empty
|
|
Else
|
|
Dim u$ = CreateVideoURL_FlashVars(r)
|
|
If u.IsEmptyString Then u = CreateVideoURL_MediaDef(r)
|
|
Return u
|
|
End If
|
|
End Function
|
|
Private Function CreateVideoURL_FlashVars(ByVal r As String) As String
|
|
Try
|
|
Dim OutStr$ = String.Empty
|
|
Dim OutList As New List(Of String)
|
|
Dim tmpUrl$
|
|
Dim i%
|
|
If Not r.IsEmptyString Then
|
|
Dim _VarBlock$, var$, v$
|
|
Dim vars As List(Of FlashVar)
|
|
Dim compiler As List(Of String)
|
|
Dim _VarBlocks As List(Of String) = RegexReplace(r, RegexVideo_FlashVarsBlocks)
|
|
If _VarBlocks.ListExists Then
|
|
For Each _VarBlock In _VarBlocks
|
|
tmpUrl = String.Empty
|
|
vars = RegexFields(Of FlashVar)(_VarBlock, {RegexVideo_FlashVars_Vars}, {1, 2})
|
|
compiler = RegexReplace(_VarBlock, RegexVideo_FlashVars_Compiler)
|
|
If vars.ListExists And compiler.ListExists Then
|
|
For Each var In compiler
|
|
i = vars.IndexOf(var)
|
|
If i >= 0 Then
|
|
v = vars(i).Value
|
|
If Not v.IsEmptyString Then tmpUrl &= v
|
|
End If
|
|
Next
|
|
vars.Clear()
|
|
compiler.Clear()
|
|
End If
|
|
If Not tmpUrl.IsEmptyString Then OutList.Add(tmpUrl)
|
|
Next
|
|
End If
|
|
End If
|
|
|
|
If OutList.Count > 0 Then OutList.RemoveAll(Function(u) u.IsEmptyString)
|
|
If OutList.Count > 0 Then
|
|
i = OutList.FindIndex(Function(u) u.Contains("urlset"))
|
|
If i >= 0 Then
|
|
OutStr = OutList(i)
|
|
Else
|
|
Dim newUrls As New List(Of Sizes)
|
|
Dim tmpSize%?
|
|
For Each tmpUrl In OutList
|
|
tmpSize = AConvert(Of Integer)(RegexReplace(tmpUrl, RegexVideo_FlashVars_UrlResolution), AModes.Var, Nothing)
|
|
If tmpSize.HasValue Then newUrls.Add(New Sizes(tmpSize.Value, tmpUrl))
|
|
Next
|
|
If newUrls.Count > 0 Then
|
|
newUrls.Sort()
|
|
OutStr = newUrls(0).Data
|
|
newUrls.Clear()
|
|
Else
|
|
OutStr = OutList(0)
|
|
End If
|
|
End If
|
|
End If
|
|
OutList.Clear()
|
|
Return OutStr
|
|
Catch regex_ex As RegexFieldsTextBecameNullException
|
|
MyMainLOG = $"{ToStringForLog()}: something is wrong when parsing flashvars.{vbCr}{regex_ex.Message}"
|
|
Return String.Empty
|
|
Catch ex As Exception
|
|
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.PornHub.UserData.CreateVideoURL_FlashVars]", String.Empty)
|
|
End Try
|
|
End Function
|
|
Private Function CreateVideoURL_MediaDef(ByVal r As String) As String
|
|
Try
|
|
Dim result$ = String.Empty
|
|
If Not r.IsEmptyString Then
|
|
Dim script$ = RegexReplace(r, RegexVideo_MediaDef)
|
|
If Not script.IsEmptyString Then
|
|
Using j As EContainer = JsonDocument.Parse(script)
|
|
If j.ListExists Then
|
|
Dim s As List(Of Sizes) = j.Select(Function(jj) New Sizes(jj.Value("quality"), jj.Value("videoUrl"))).ListWithRemove(Function(d) d.HasError Or d.Data.IsEmptyString)
|
|
If s.ListExists Then s.Sort() : result = s(0).Data : s.Clear()
|
|
End If
|
|
End Using
|
|
End If
|
|
End If
|
|
Return result
|
|
Catch ex As Exception
|
|
Return ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.PornHub.UserData.CreateVideoURL_MediaDef]", String.Empty)
|
|
End Try
|
|
End Function
|
|
#End Region
|
|
#Region "DownloadSingleObject"
|
|
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
|
|
_TempMediaList.Add(New UserMedia(Data.URL, UTypes.VideoPre))
|
|
ReparseVideo(Token, True, Data)
|
|
End Sub
|
|
Protected Overrides Sub DownloadSingleObject_PostProcessing(ByVal Data As IYouTubeMediaContainer, Optional ByVal ResetTitle As Boolean = True)
|
|
MyBase.DownloadSingleObject_PostProcessing(Data, False)
|
|
End Sub
|
|
#End Region
|
|
#Region "Exceptions"
|
|
Protected Overrides Function DownloadingException(ByVal ex As Exception, ByVal Message As String,
|
|
Optional ByVal FromPE As Boolean = False, Optional ByVal EObj As Object = Nothing) As Integer
|
|
If Responser.Status = Net.WebExceptionStatus.ConnectionClosed Then
|
|
Return 1
|
|
ElseIf Responser.StatusCode = Net.HttpStatusCode.ServiceUnavailable Then
|
|
Return 2
|
|
Else
|
|
Return 0
|
|
End If
|
|
End Function
|
|
#End Region
|
|
#Region "IDisposable Support"
|
|
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
|
|
If Not disposedValue And disposing Then LastPageIDs.Clear()
|
|
MyBase.Dispose(disposing)
|
|
End Sub
|
|
#End Region
|
|
End Class
|
|
End Namespace |