Skip to content

Commit 24ad338

Browse files
committed
2025.6.12.0
YT MainModShared: fix environment output YouTubeMediaContainerBase: fix 'm3u8' audio formats SCrawler UserDataBase: text downloading with saved posts; update 'ID' property (handle '_ForceSaveUserInfo') API.Bluesky: data is not downloaded API.Reddit: update 'RedditViewExchange'; set base inheritance; inherit default settings for new users API.ALL: update functions with property 'ID'
1 parent ff0c458 commit 24ad338

File tree

16 files changed

+146
-59
lines changed

16 files changed

+146
-59
lines changed

Changelog.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
# 2025.6.12.0
2+
3+
*2025-06-12*
4+
5+
- Updated
6+
- yt-dlp up to version **2025.06.09**
7+
- Fixed
8+
- Sites:
9+
- YouTube: audio formats of protocol `m3u8` are not handled correctly
10+
- BlueSky: data is not downloaded in some cases
11+
- Reddit: new users do not inherit default text settings
12+
- Saved posts: text downloading with saved posts
13+
- Environment incorrect output
14+
115
# 2025.6.1.0
216

317
*2025-06-01*

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
3535
# What can program do:
3636
- Download pictures and videos from user profiles:
3737
- YouTube videos, shorts, community feeds, users, artists, playlists, music, tracks;
38-
- Reddit images, galleries of images, videos, saved posts;
38+
- Reddit images, galleries of images, videos, text, saved posts;
3939
- Redgifs images and videos (https://www.redgifs.com/);
40-
- Twitter images and videos, saved (bookmarked) posts, likes, communities;
41-
- Bluesky images and videos;
42-
- OnlyFans images and videos, saved (bookmarked) posts, stories;
40+
- Twitter images and videos, text, saved (bookmarked) posts, likes, communities;
41+
- Bluesky images and videos, text;
42+
- OnlyFans images and videos, text, saved (bookmarked) posts, stories;
4343
- JustForFans images and videos, saved (bookmarked) posts;
4444
- Mastodon images and videos, saved (bookmarked) posts;
45-
- Instagram images and videos, tagged posts, stories, saved posts;
46-
- Threads images and videos, saved posts;
45+
- Instagram images and videos, text, tagged posts, stories, saved posts;
46+
- Threads images and videos, text, saved posts;
4747
- Facebook images and videos, stories, saved posts;
4848
- TikTok images and videos;
4949
- Pinterest boards, users, saved posts;

SCrawler.YouTube/MainModShared.vb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Imports System.Threading
1010
Imports PersonalUtilities.Tools
1111
Imports PersonalUtilities.Tools.Web
1212
Imports PersonalUtilities.Functions.Messaging
13+
Imports PersonalUtilities.Functions.RegularExpressions
1314
Imports SCrawler.DownloadObjects.STDownloader
1415
Public Module MainModShared
1516
Public Property BATCH As BatchExecutor
@@ -135,9 +136,11 @@ Namespace Editors
135136
Public Shared Function GetProgramEnvirText(ByVal EnvirData As IDownloaderSettings, ByVal IsYouTube As Boolean) As String
136137
Try
137138
Dim output$ = String.Empty
139+
Dim verAfter As RParams = RParams.DM("\A\w\:\\.*", 0, EDP.ReturnValue)
138140
Using b As New BatchExecutor(True)
139141
Dim f As SFile
140142
Dim cmd$, ff$, vText$
143+
Dim ii%
141144

142145
For i% = 0 To IIf(IsYouTube, 1, 3)
143146
cmd = "--version"
@@ -154,7 +157,17 @@ Namespace Editors
154157
Else
155158
b.Reset()
156159
b.Execute($"""{f}"" {cmd}", EDP.None)
157-
If b.OutputData.Count > 3 Then vText = b.OutputData(3) Else vText = "undefined"
160+
'If b.OutputData.Count > 3 Then vText = b.OutputData(3) Else vText = "undefined"
161+
162+
vText = String.Empty
163+
With b.OutputData
164+
If .Count > 0 Then
165+
ii = .FindIndex(Function(bb) Not CStr(RegexReplace(bb, verAfter)).IsEmptyString)
166+
If ii >= 0 And ii + 1 <= .Count - 1 Then vText = .Item(ii + 1)
167+
End If
168+
End With
169+
If vText.IsEmptyString Then vText = "undefined"
170+
158171
output.StringAppendLine($"{ff} version: {vText}")
159172
End If
160173
End If

SCrawler.YouTube/My Project/AssemblyInfo.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
3232
' by using the '*' as shown below:
3333
' <Assembly: AssemblyVersion("1.0.*")>
3434

35-
<Assembly: AssemblyVersion("2025.6.1.0")>
36-
<Assembly: AssemblyFileVersion("2025.6.1.0")>
35+
<Assembly: AssemblyVersion("2025.6.12.0")>
36+
<Assembly: AssemblyFileVersion("2025.6.12.0")>
3737
<Assembly: NeutralResourcesLanguage("en")>

SCrawler.YouTube/Objects/YouTubeMediaContainerBase.vb

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ Namespace API.YouTube.Objects
738738
#Region "Command"
739739
<XMLEC> Public Property UseCookies As Boolean = MyYouTubeSettings.DefaultUseCookies Implements IYouTubeMediaContainer.UseCookies
740740
Protected Const mp3 As String = "mp3"
741+
Private Const mp4 As String = "mp4"
741742
Private Const aac As String = "aac"
742743
Private Const ac3 As String = "ac3"
743744
Protected PostProcessing_AudioAC3 As Boolean = False
@@ -773,7 +774,12 @@ Namespace API.YouTube.Objects
773774
'2023.3.4 -> 2023.7.6
774775
'cmd.StringAppend($"ba*[format_id={SelectedAudio.ID}]", "+")
775776
cmd.StringAppend(SelectedAudio.ID, "+")
776-
If OutputAudioCodec.StringToLower = ac3 Then
777+
If SelectedVideoIndex >= 0 And SelectedAudio.ProtocolType = Protocols.m3u8 And
778+
(SelectedAudio.Codec.StringToLower = mp4 Or OutputAudioCodec.StringToLower = mp4) Then
779+
PostProcessing_AudioAC3 = True
780+
formats.StringAppend($"--merge-output-format ""{mp4}{IIf(OutputVideoExtension.IsEmptyString, String.Empty, $"/{OutputVideoExtension.StringToLower}")}""", " ")
781+
atCodec = aac
782+
ElseIf OutputAudioCodec.StringToLower = ac3 Then
777783
PostProcessing_AudioAC3 = True
778784
formats.StringAppend($"--audio-format {aac}", " ")
779785
atCodec = aac
@@ -1753,9 +1759,12 @@ Namespace API.YouTube.Objects
17531759
If If(e({"formats"})?.Count, 0) > 0 Then
17541760
Dim obj As MediaObject
17551761
Dim nValue#
1756-
Dim sValue$
1762+
Dim sValue$ = String.Empty
17571763
Dim allowWebm As Boolean = MyYouTubeSettings.DefaultVideoAllowWebm
1758-
Dim validCodecValue As Func(Of String, Boolean) = Function(codec) Not codec.IsEmptyString AndAlso Not codec = "none"
1764+
Dim validCodecValue As Func(Of String, Boolean) = Function(ByVal codec As String) As Boolean
1765+
sValue = codec
1766+
Return Not codec.IsEmptyString AndAlso Not codec = "none"
1767+
End Function
17591768

17601769
For Each ee In e({"formats"})
17611770
obj = New MediaObject With {
@@ -1779,19 +1788,30 @@ Namespace API.YouTube.Objects
17791788
If obj.Size <= 0 And obj.Bitrate > 0 And Duration.TotalSeconds > 0 Then _
17801789
obj.Size = (obj.Bitrate / 8 * Duration.TotalSeconds).RoundVal(2)
17811790

1782-
sValue = ee.Value("vcodec")
1783-
If validCodecValue(sValue) Then
1791+
'sValue = ee.Value("vcodec")
1792+
If validCodecValue(ee.Value("vcodec")) Then
17841793
obj.Type = UMTypes.Video
17851794
obj.Codec = sValue.Split(".").First
17861795
If validCodecValue(ee.Value("acodec")) Then obj.Type = av
1796+
ElseIf validCodecValue(ee.Value("acodec")) Then
1797+
obj.Type = UMTypes.Audio
1798+
obj.Codec = sValue.Split(".").First
17871799
Else
1788-
sValue = ee.Value("acodec")
1789-
If validCodecValue(sValue) Then
1790-
obj.Type = UMTypes.Audio
1791-
obj.Codec = sValue.Split(".").First
1792-
Else
1793-
Continue For
1800+
Dim fd As Boolean = False
1801+
sValue = ee.Value("format_note")
1802+
If Not sValue.IsEmptyString Then
1803+
With ListAddList(Nothing, sValue.Split(","), CType(Function(v) CStr(v).StringToLower.StringTrim, Func(Of Object, Object)), EDP.ReturnValue)
1804+
If .ListContains({"high", "low"}) Then
1805+
obj.Type = UMTypes.Audio
1806+
obj.Codec = ee.Value("ext")
1807+
If obj.Protocol.StringToLower.StartsWith("m3u8") Then obj.Protocol = "m3u8"
1808+
If obj.Bitrate <= 0 Then obj.Bitrate = IIf(.Contains("high"), 129, 53)
1809+
If obj.Size <= 0 Then obj.Size = 1
1810+
fd = True
1811+
End If
1812+
End With
17941813
End If
1814+
If Not fd Then Continue For
17951815
End If
17961816
MediaObjects.Add(obj)
17971817
Next
@@ -1803,15 +1823,18 @@ Namespace API.YouTube.Objects
18031823
Dim data As New List(Of MediaObject)(MediaObjects.Where(Function(mo) mo.Type = t And mo.Extension = webm))
18041824
If data.Count > 0 Then
18051825
Dim d As MediaObject = Nothing
1806-
Dim expWebm As Predicate(Of MediaObject) = Function(mo) mo.Extension = webm
1807-
Dim expAVC As Predicate(Of MediaObject) = Function(mo) mo.Codec.IfNullOrEmpty("/").ToLower.StartsWith(avc)
1826+
Dim allWebm As Boolean = False, allAVC As Boolean = False
1827+
Dim expWebm As Predicate(Of MediaObject) = Function(mo) Not allWebm And mo.Extension = webm
1828+
Dim expAVC As Predicate(Of MediaObject) = Function(mo) Not allAVC And mo.Codec.IfNullOrEmpty("/").ToLower.StartsWith(avc)
18081829
Dim comp As Func(Of MediaObject, Predicate(Of MediaObject), Boolean, Boolean, Boolean) =
18091830
Function(mo, exp, isTrue, checkHttp) mo.Type = t And exp.Invoke(mo) = isTrue And mo.Width = d.Width And
18101831
(Not checkHttp OrElse mo.ProtocolType = Protocols.https)
18111832
Dim CountWebm As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expWebm, False, allowWebm)
18121833
Dim RemoveWebm As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expWebm, True, allowWebm)
18131834
Dim CountAVC As Func(Of MediaObject, Boolean) = Function(mo) comp.Invoke(mo, expAVC, True, False)
18141835
Dim RemoveAVC As Predicate(Of MediaObject) = Function(mo) comp.Invoke(mo, expAVC, False, False)
1836+
allWebm = data.All(FPredicate(Of MediaObject).ToFunc(expWebm))
1837+
allAVC = data.All(FPredicate(Of MediaObject).ToFunc(expAVC))
18151838
For Each d In data
18161839
If MediaObjects.Count = 0 Then Exit For
18171840
If MediaObjects.LongCount(CountWebm) > 0 Then MediaObjects.RemoveAll(RemoveWebm)

SCrawler.YouTubeDownloader/My Project/AssemblyInfo.vb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
3232
' by using the '*' as shown below:
3333
' <Assembly: AssemblyVersion("1.0.*")>
3434

35-
<Assembly: AssemblyVersion("2025.6.1.0")>
36-
<Assembly: AssemblyFileVersion("2025.6.1.0")>
35+
<Assembly: AssemblyVersion("2025.6.12.0")>
36+
<Assembly: AssemblyFileVersion("2025.6.12.0")>
3737
<Assembly: NeutralResourcesLanguage("en")>

SCrawler/API/Base/UserDataBase.vb

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,20 @@ Namespace API.Base
252252
#End Region
253253
#Region "User name, ID, exist, suspend, options"
254254
Friend User As UserInfo
255+
Private _IsSavedPosts As Boolean = False
255256
Friend Property IsSavedPosts As Boolean Implements IPluginContentProvider.IsSavedPosts
257+
Get
258+
Return _IsSavedPosts
259+
End Get
260+
Set(ByVal __IsSavedPosts As Boolean)
261+
_IsSavedPosts = __IsSavedPosts
262+
If _IsSavedPosts Then
263+
DownloadText = True
264+
DownloadTextPosts = True
265+
DownloadTextSpecialFolder = True
266+
End If
267+
End Set
268+
End Property
256269
Private _UserExists As Boolean = True
257270
Friend Overridable Property UserExists As Boolean Implements IUserData.Exists, IPluginContentProvider.UserExists
258271
Get
@@ -300,7 +313,16 @@ Namespace API.Base
300313
Return If(Exact, _NameTrue, _NameTrue.IfNullOrEmpty(Name))
301314
End Get
302315
End Property
303-
Friend Overridable Property ID As String = String.Empty Implements IUserData.ID, IPluginContentProvider.ID
316+
Private _ID As String = String.Empty
317+
Friend Property ID As String Implements IUserData.ID, IPluginContentProvider.ID
318+
Get
319+
Return _ID
320+
End Get
321+
Set(ByVal NewId As String)
322+
If Not _ID = NewId Then EnvirChanged(NewId)
323+
_ID = NewId
324+
End Set
325+
End Property
304326
Protected _FriendlyName As String = String.Empty
305327
Friend Overridable Property FriendlyName As String Implements IUserData.FriendlyName
306328
Get
@@ -985,8 +1007,8 @@ BlockNullPicture:
9851007
ReadyForDownload = x.Value(Name_ReadyForDownload).FromXML(Of Boolean)(True)
9861008
DownloadImages = x.Value(Name_DownloadImages).FromXML(Of Boolean)(True)
9871009
DownloadVideos = x.Value(Name_DownloadVideos).FromXML(Of Boolean)(True)
988-
DownloadText = x.Value(Name_DownloadText).FromXML(Of Boolean)(False)
989-
DownloadTextPosts = x.Value(Name_DownloadTextPosts).FromXML(Of Boolean)(False)
1010+
DownloadText = x.Value(Name_DownloadText).FromXML(Of Boolean)(IsSavedPosts)
1011+
DownloadTextPosts = x.Value(Name_DownloadTextPosts).FromXML(Of Boolean)(IsSavedPosts)
9901012
DownloadTextSpecialFolder = x.Value(Name_DownloadTextSpecialFolder).FromXML(Of Boolean)(True)
9911013
_IconBannerDownloaded = x.Value(Name_IconBannerDownloaded).FromXML(Of Boolean)(False)
9921014
DownloadedVideos(True) = x.Value(Name_VideoCount).FromXML(Of Integer)(0)
@@ -1222,7 +1244,8 @@ BlockNullPicture:
12221244
Select Case Caller
12231245
Case NameOf(UserExists) : If Not _EnvirUserExists = CBool(NewValue) Then _EnvirChanged = True : _EnvirInvokeUserUpdated = True
12241246
Case NameOf(UserSuspended) : If Not _EnvirUserSuspended = CBool(NewValue) Then _EnvirChanged = True : _EnvirInvokeUserUpdated = True
1225-
Case NameOf(NameTrue) : _EnvirChanged = True : _EnvirInvokeUserUpdated = True : _ForceSaveUserInfo = True : _ForceSaveUserInfoOnException = True
1247+
Case NameOf(NameTrue) : _EnvirChanged = True : _ForceSaveUserInfo = True : _ForceSaveUserInfoOnException = True
1248+
Case NameOf(ID) : _EnvirChanged = True : _ForceSaveUserInfo = True : _ForceSaveUserInfoOnException = True
12261249
Case Else : _EnvirChanged = True
12271250
End Select
12281251
End If

SCrawler/API/Bluesky/UserData.vb

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Namespace API.Bluesky
2727
Return If(ID.IsEmptyString, String.Empty, SymbolsConverter.ASCII.EncodeSymbolsOnly(ID))
2828
End Get
2929
End Property
30+
Private ReadOnly _TmpPosts2 As List(Of String)
3031
#End Region
3132
#Region "Loader"
3233
Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
@@ -42,6 +43,7 @@ Namespace API.Bluesky
4243
#Region "Initializer"
4344
Friend Sub New()
4445
UseInternalM3U8Function = True
46+
_TmpPosts2 = New List(Of String)
4547
End Sub
4648
#End Region
4749
#Region "Token"
@@ -62,11 +64,17 @@ Namespace API.Bluesky
6264
#Region "Download"
6365
Private _PostCount As Integer = 0
6466
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
65-
If Not CBool(MySettings.CookiesEnabled.Value) Then Responser.Cookies.Clear()
66-
UpdateToken(, True)
67-
_TokenUpdateCount = 0
68-
_PostCount = 0
69-
DownloadData(String.Empty, Token)
67+
_TmpPosts2.Clear()
68+
Try
69+
If Not CBool(MySettings.CookiesEnabled.Value) Then Responser.Cookies.Clear()
70+
UpdateToken(, True)
71+
_TokenUpdateCount = 0
72+
_PostCount = 0
73+
DownloadData(String.Empty, Token)
74+
Finally
75+
_TempPostsList.ListAddList(_TmpPosts2, LNC)
76+
_TmpPosts2.Clear()
77+
End Try
7078
End Sub
7179
Private Overloads Sub DownloadData(ByVal Cursor As String, ByVal Token As CancellationToken)
7280
Dim URL$ = String.Empty
@@ -117,7 +125,8 @@ Namespace API.Bluesky
117125
Private Function DefaultParser(ByVal e As EContainer, Optional ByVal CheckDateLimits As Boolean = True, Optional ByRef NextCursor As String = Nothing,
118126
Optional ByVal CheckTempPosts As Boolean = True, Optional ByVal State As UStates = UStates.Unknown) As Integer
119127
Const exitReturn% = CInt(DateResult.Exit) * -1
120-
Dim postID$, postDate$, __url$, __urlBase$, __txt$
128+
Const skipReturn% = CInt(DateResult.Skip) * -1
129+
Dim postID$, postDate$, __url$, __urlBase$, __txt$, __userId$
121130
Dim updateUrl As Boolean
122131
Dim c% = 0
123132
Dim m As UserMedia
@@ -128,21 +137,26 @@ Namespace API.Bluesky
128137
postDate = String.Empty
129138
__urlBase = String.Empty
130139
__txt = String.Empty
140+
__userId = .Value({"author"}, "did")
131141
With .Item({"record"})
132142
If .ListExists Then
133143
'2025-01-28T02:42:12.415Z
134144
postDate = .Value("createdAt")
135145
NextCursor = postDate
136146
If CheckDateLimits Then
137147
Select Case CheckDatesLimit(postDate, DateProvider)
138-
Case DateResult.Skip : Return CInt(DateResult.Skip) * -1 'Continue For
148+
Case DateResult.Skip : Return skipReturn 'Continue For
139149
Case DateResult.Exit : Return exitReturn 'Exit Sub
140150
End Select
141151
End If
142152

143153
If CheckTempPosts Then
144-
If _TempPostsList.Contains(postID) Then Return exitReturn Else _TempPostsList.Add(postID)
154+
'If _TempPostsList.Contains(postID) Then Return exitReturn Else _TempPostsList.Add(postID)
155+
If _TempPostsList.Contains(postID) Then Return exitReturn Else _TmpPosts2.Add(postID)
145156
End If
157+
158+
If ParseUserMediaOnly And Not ID.IsEmptyString And Not __userId.IsEmptyString And Not ID = __userId Then Return skipReturn
159+
146160
__urlBase = $"https://bsky.app/profile/{NameTrue}/post/{postID}"
147161
End If
148162
End With
@@ -338,6 +352,12 @@ Namespace API.Bluesky
338352
Return 0
339353
End If
340354
End Function
355+
#End Region
356+
#Region "IDisposable Support"
357+
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
358+
If disposing Then _TmpPosts2.Clear()
359+
MyBase.Dispose(disposing)
360+
End Sub
341361
#End Region
342362
End Class
343363
End Namespace

SCrawler/API/Facebook/UserData.vb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -676,10 +676,7 @@ Namespace API.Facebook
676676
End If
677677
Token_Photosby = RegexReplace(r, Regex_Photos_by)
678678
If StoryBucket.IsEmptyString Then StoryBucket = RegexReplace(r, Regex_StoryBucket)
679-
If ID.IsEmptyString Then
680-
ID = RegexReplace(r, Regex_UserID)
681-
If Not ID.IsEmptyString Then _ForceSaveUserInfo = True
682-
End If
679+
If ID.IsEmptyString Then ID = RegexReplace(r, Regex_UserID)
683680
End If
684681
Catch ex As Exception
685682
ProcessException(ex, Token, "get user token",, resp)

0 commit comments

Comments
 (0)