diff --git a/Changelog.md b/Changelog.md
index 353eb58..85798f3 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,17 @@
+# 2023.1.27.0
+
+*2023-01-27*
+
+- Added
+ - Advanced Twitter options for GIFs
+ - Changing the icon of the user creation form based on the selected site
+- Fixed
+ - Pinned Instagram posts reload every time
+- Plugins
+ - Added
+ - `Interaction` option to the `Provider` attribute
+ - `IPropertyProvider` interface
+
# 2023.1.24.1
*2023-01-24*
diff --git a/ProgramScreenshots/SettingsSiteTwitter.png b/ProgramScreenshots/SettingsSiteTwitter.png
index fa55583..224880c 100644
Binary files a/ProgramScreenshots/SettingsSiteTwitter.png and b/ProgramScreenshots/SettingsSiteTwitter.png differ
diff --git a/SCrawler.PluginProvider/Attributes/Attributes.vb b/SCrawler.PluginProvider/Attributes/Attributes.vb
index f7d33c0..0dd2c6a 100644
--- a/SCrawler.PluginProvider/Attributes/Attributes.vb
+++ b/SCrawler.PluginProvider/Attributes/Attributes.vb
@@ -100,6 +100,8 @@ Namespace Plugin.Attributes
''' - only for conversion
'''
Public FieldsChecker As Boolean = False
+ ''' Interaction with changing text field. Default:
+ Public Interaction As Boolean = False
''' Initialize a new Provider attribute. is only allowed
''' The name of the property for which this provider is used
Public Sub New(ByVal PropertyName As String)
diff --git a/SCrawler.PluginProvider/Interfaces/IPropertyProvider.vb b/SCrawler.PluginProvider/Interfaces/IPropertyProvider.vb
new file mode 100644
index 0000000..85508bb
--- /dev/null
+++ b/SCrawler.PluginProvider/Interfaces/IPropertyProvider.vb
@@ -0,0 +1,13 @@
+' 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
+Namespace Plugin
+ Public Interface IPropertyProvider : Inherits IFormatProvider
+ Property PropertyName As String
+ End Interface
+End Namespace
\ No newline at end of file
diff --git a/SCrawler.PluginProvider/My Project/AssemblyInfo.vb b/SCrawler.PluginProvider/My Project/AssemblyInfo.vb
index b9fd8cd..5ad7254 100644
--- a/SCrawler.PluginProvider/My Project/AssemblyInfo.vb
+++ b/SCrawler.PluginProvider/My Project/AssemblyInfo.vb
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below:
'
-
-
+
+
diff --git a/SCrawler.PluginProvider/SCrawler.PluginProvider.vbproj b/SCrawler.PluginProvider/SCrawler.PluginProvider.vbproj
index 3bd708f..c5a6ecd 100644
--- a/SCrawler.PluginProvider/SCrawler.PluginProvider.vbproj
+++ b/SCrawler.PluginProvider/SCrawler.PluginProvider.vbproj
@@ -102,6 +102,7 @@
+
diff --git a/SCrawler/API/Base/UserDataBase.vb b/SCrawler/API/Base/UserDataBase.vb
index d833c12..5693be4 100644
--- a/SCrawler/API/Base/UserDataBase.vb
+++ b/SCrawler/API/Base/UserDataBase.vb
@@ -1023,12 +1023,14 @@ BlockNullPicture:
End If
If Not v.SpecialFolder.IsEmptyString Then
- f.Path = $"{f.PathWithSeparator}{v.SpecialFolder}\".CSFileP.Path
+ f.Path = $"{f.PathWithSeparator}{v.SpecialFolder.StringTrimEnd("*")}\".CSFileP.Path
f.Exists(SFO.Path)
End If
If __isVideo And vsf Then
- f.Path = $"{f.PathWithSeparator}Video"
- If Not v.SpecialFolder.IsEmptyString Then f.Exists(SFO.Path)
+ If v.SpecialFolder.IsEmptyString OrElse Not v.SpecialFolder.EndsWith("*") Then
+ f.Path = $"{f.PathWithSeparator}Video"
+ If Not v.SpecialFolder.IsEmptyString Then f.Exists(SFO.Path)
+ End If
End If
If v.Type = UTypes.m3u8 And UseInternalM3U8Function Then
diff --git a/SCrawler/API/Instagram/UserData.vb b/SCrawler/API/Instagram/UserData.vb
index c16c2e0..4f49608 100644
--- a/SCrawler/API/Instagram/UserData.vb
+++ b/SCrawler/API/Instagram/UserData.vb
@@ -613,17 +613,20 @@ Namespace API.Instagram
With nn
PostIDKV = New PostKV(.Value("code"), .Value("id"), Section)
Pinned = .Contains("timeline_pinned_user_ids")
- If PostKvExists(PostIDKV) And Not Pinned Then Return False
- _TempPostsList.Add(PostIDKV.ID)
- PostsKVIDs.ListAddValue(PostIDKV, LAP.NotContainsOnly)
- PostDate = .Value("taken_at")
- If Not IsSavedPosts Then
- Select Case CheckDatesLimit(PostDate, DateProvider)
- Case DateResult.Skip : Continue For
- Case DateResult.Exit : If Not Pinned Then Return False
- End Select
+ If PostKvExists(PostIDKV) Then
+ If Not Pinned Then Return False
+ Else
+ _TempPostsList.Add(PostIDKV.ID)
+ PostsKVIDs.ListAddValue(PostIDKV, LNC)
+ PostDate = .Value("taken_at")
+ If Not IsSavedPosts Then
+ Select Case CheckDatesLimit(PostDate, DateProvider)
+ Case DateResult.Skip : Continue For
+ Case DateResult.Exit : If Not Pinned Then Return False
+ End Select
+ End If
+ ObtainMedia(.Self, PostIDKV.ID, SpecFolder, PostDate)
End If
- ObtainMedia(.Self, PostIDKV.ID, SpecFolder, PostDate)
End With
Next
Return True
diff --git a/SCrawler/API/Twitter/Declarations.vb b/SCrawler/API/Twitter/Declarations.vb
index a1a055c..1073ac4 100644
--- a/SCrawler/API/Twitter/Declarations.vb
+++ b/SCrawler/API/Twitter/Declarations.vb
@@ -12,6 +12,7 @@ Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.Twitter
Friend Module Declarations
Friend Const TwitterSite As String = "Twitter"
+ Friend Const TwitterSiteKey As String = "AndyProgram_Twitter"
Friend ReadOnly DateProvider As ADateTime = GetDateProvider()
Friend ReadOnly VideoNode As NodeParams() = {New NodeParams("video_info", True, True, True, True, 10)}
Friend ReadOnly VideoSizeRegEx As RParams = RParams.DMS("\d+x(\d+)", 1, EDP.ReturnValue)
diff --git a/SCrawler/API/Twitter/EditorExchangeOptions.vb b/SCrawler/API/Twitter/EditorExchangeOptions.vb
new file mode 100644
index 0000000..dddbf05
--- /dev/null
+++ b/SCrawler/API/Twitter/EditorExchangeOptions.vb
@@ -0,0 +1,27 @@
+' 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
+Namespace API.Twitter
+ Friend Class EditorExchangeOptions
+ Friend Property GifsDownload As Boolean
+ Friend Property GifsSpecialFolder As String
+ Friend Property GifsPrefix As String
+ Friend Sub New()
+ End Sub
+ Friend Sub New(ByVal s As SiteSettings)
+ GifsDownload = s.GifsDownload.Value
+ GifsSpecialFolder = s.GifsSpecialFolder.Value
+ GifsPrefix = s.GifsPrefix.Value
+ End Sub
+ Friend Sub New(ByVal u As UserData)
+ GifsDownload = u.GifsDownload
+ GifsSpecialFolder = u.GifsSpecialFolder
+ GifsPrefix = u.GifsPrefix
+ End Sub
+ End Class
+End Namespace
\ No newline at end of file
diff --git a/SCrawler/API/Twitter/OptionsForm.Designer.vb b/SCrawler/API/Twitter/OptionsForm.Designer.vb
new file mode 100644
index 0000000..3330cfa
--- /dev/null
+++ b/SCrawler/API/Twitter/OptionsForm.Designer.vb
@@ -0,0 +1,148 @@
+' 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
+Namespace API.Twitter
+
+ Partial Friend Class OptionsForm : Inherits System.Windows.Forms.Form
+
+ Protected Overrides Sub Dispose(ByVal disposing As Boolean)
+ Try
+ If disposing AndAlso components IsNot Nothing Then
+ components.Dispose()
+ End If
+ Finally
+ MyBase.Dispose(disposing)
+ End Try
+ End Sub
+ Private components As System.ComponentModel.IContainer
+
+ Private Sub InitializeComponent()
+ Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
+ Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
+ Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
+ Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(OptionsForm))
+ Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
+ Me.CH_DOWN_GIFS = New System.Windows.Forms.CheckBox()
+ Me.TXT_GIF_FOLDER = New PersonalUtilities.Forms.Controls.TextBoxExtended()
+ Me.TXT_GIF_PREFIX = New PersonalUtilities.Forms.Controls.TextBoxExtended()
+ CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
+ TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
+ CONTAINER_MAIN.ContentPanel.SuspendLayout()
+ CONTAINER_MAIN.SuspendLayout()
+ TP_MAIN.SuspendLayout()
+ CType(Me.TXT_GIF_FOLDER, System.ComponentModel.ISupportInitialize).BeginInit()
+ CType(Me.TXT_GIF_PREFIX, System.ComponentModel.ISupportInitialize).BeginInit()
+ Me.SuspendLayout()
+ '
+ 'CONTAINER_MAIN
+ '
+ '
+ 'CONTAINER_MAIN.ContentPanel
+ '
+ CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
+ CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(304, 84)
+ CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
+ CONTAINER_MAIN.LeftToolStripPanelVisible = False
+ CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
+ CONTAINER_MAIN.Name = "CONTAINER_MAIN"
+ CONTAINER_MAIN.RightToolStripPanelVisible = False
+ CONTAINER_MAIN.Size = New System.Drawing.Size(304, 109)
+ CONTAINER_MAIN.TabIndex = 0
+ CONTAINER_MAIN.TopToolStripPanelVisible = False
+ '
+ 'TP_MAIN
+ '
+ TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
+ TP_MAIN.ColumnCount = 1
+ TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
+ TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
+ TP_MAIN.Controls.Add(Me.CH_DOWN_GIFS, 0, 0)
+ TP_MAIN.Controls.Add(Me.TXT_GIF_FOLDER, 0, 1)
+ TP_MAIN.Controls.Add(Me.TXT_GIF_PREFIX, 0, 2)
+ TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
+ TP_MAIN.Location = New System.Drawing.Point(0, 0)
+ TP_MAIN.Name = "TP_MAIN"
+ TP_MAIN.RowCount = 4
+ TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
+ TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
+ TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
+ TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
+ TP_MAIN.Size = New System.Drawing.Size(304, 84)
+ TP_MAIN.TabIndex = 0
+ '
+ 'CH_DOWN_GIFS
+ '
+ Me.CH_DOWN_GIFS.AutoSize = True
+ Me.CH_DOWN_GIFS.Dock = System.Windows.Forms.DockStyle.Fill
+ Me.CH_DOWN_GIFS.Location = New System.Drawing.Point(4, 4)
+ Me.CH_DOWN_GIFS.Name = "CH_DOWN_GIFS"
+ Me.CH_DOWN_GIFS.Padding = New System.Windows.Forms.Padding(100, 0, 0, 0)
+ Me.CH_DOWN_GIFS.Size = New System.Drawing.Size(296, 19)
+ Me.CH_DOWN_GIFS.TabIndex = 0
+ Me.CH_DOWN_GIFS.Text = "Download GIFs"
+ Me.CH_DOWN_GIFS.UseVisualStyleBackColor = True
+ '
+ 'TXT_GIF_FOLDER
+ '
+ ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
+ ActionButton1.Name = "Clear"
+ ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
+ Me.TXT_GIF_FOLDER.Buttons.Add(ActionButton1)
+ Me.TXT_GIF_FOLDER.CaptionText = "GIFs special folder"
+ Me.TXT_GIF_FOLDER.CaptionToolTipText = "Put the GIFs in a special folder"
+ Me.TXT_GIF_FOLDER.Dock = System.Windows.Forms.DockStyle.Fill
+ Me.TXT_GIF_FOLDER.Location = New System.Drawing.Point(4, 30)
+ Me.TXT_GIF_FOLDER.Name = "TXT_GIF_FOLDER"
+ Me.TXT_GIF_FOLDER.Size = New System.Drawing.Size(296, 22)
+ Me.TXT_GIF_FOLDER.TabIndex = 1
+ '
+ 'TXT_GIF_PREFIX
+ '
+ ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
+ ActionButton2.Name = "Clear"
+ ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
+ Me.TXT_GIF_PREFIX.Buttons.Add(ActionButton2)
+ Me.TXT_GIF_PREFIX.CaptionText = "GIF prefix"
+ Me.TXT_GIF_PREFIX.CaptionToolTipText = "This prefix will be added to the beginning of the filename"
+ Me.TXT_GIF_PREFIX.Dock = System.Windows.Forms.DockStyle.Fill
+ Me.TXT_GIF_PREFIX.Location = New System.Drawing.Point(4, 59)
+ Me.TXT_GIF_PREFIX.Name = "TXT_GIF_PREFIX"
+ Me.TXT_GIF_PREFIX.Size = New System.Drawing.Size(296, 22)
+ Me.TXT_GIF_PREFIX.TabIndex = 2
+ '
+ 'OptionsForm
+ '
+ Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
+ Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
+ Me.ClientSize = New System.Drawing.Size(304, 109)
+ Me.Controls.Add(CONTAINER_MAIN)
+ Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
+ Me.Icon = Global.SCrawler.My.Resources.SiteResources.TwitterIcon_32
+ Me.MaximizeBox = False
+ Me.MaximumSize = New System.Drawing.Size(320, 148)
+ Me.MinimizeBox = False
+ Me.MinimumSize = New System.Drawing.Size(320, 148)
+ Me.Name = "OptionsForm"
+ Me.ShowInTaskbar = False
+ Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
+ Me.Text = "Options"
+ CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
+ CONTAINER_MAIN.ResumeLayout(False)
+ CONTAINER_MAIN.PerformLayout()
+ TP_MAIN.ResumeLayout(False)
+ TP_MAIN.PerformLayout()
+ CType(Me.TXT_GIF_FOLDER, System.ComponentModel.ISupportInitialize).EndInit()
+ CType(Me.TXT_GIF_PREFIX, System.ComponentModel.ISupportInitialize).EndInit()
+ Me.ResumeLayout(False)
+
+ End Sub
+ Private WithEvents CH_DOWN_GIFS As CheckBox
+ Private WithEvents TXT_GIF_FOLDER As PersonalUtilities.Forms.Controls.TextBoxExtended
+ Private WithEvents TXT_GIF_PREFIX As PersonalUtilities.Forms.Controls.TextBoxExtended
+ End Class
+End Namespace
\ No newline at end of file
diff --git a/SCrawler/API/Twitter/OptionsForm.resx b/SCrawler/API/Twitter/OptionsForm.resx
new file mode 100644
index 0000000..27f385b
--- /dev/null
+++ b/SCrawler/API/Twitter/OptionsForm.resx
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ False
+
+
+ False
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
+ tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
+ AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
+ tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
+ AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
+
+
+
\ No newline at end of file
diff --git a/SCrawler/API/Twitter/OptionsForm.vb b/SCrawler/API/Twitter/OptionsForm.vb
new file mode 100644
index 0000000..e7f74be
--- /dev/null
+++ b/SCrawler/API/Twitter/OptionsForm.vb
@@ -0,0 +1,78 @@
+' 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.Reflection
+Imports SCrawler.Plugin.Attributes
+Imports PersonalUtilities.Forms
+Imports PersonalUtilities.Forms.Controls
+Namespace API.Twitter
+ Friend Class OptionsForm
+ Private WithEvents MyDefs As DefaultFormOptions
+ Private ReadOnly Property MyExchangeOptions As EditorExchangeOptions
+ Private ReadOnly MyGifTextProvider As SiteSettings.GifStringProvider
+ Friend Sub New(ByRef ExchangeOptions As EditorExchangeOptions)
+ InitializeComponent()
+ MyExchangeOptions = ExchangeOptions
+ MyGifTextProvider = New SiteSettings.GifStringProvider
+ MyDefs = New DefaultFormOptions(Me, Settings.Design)
+ End Sub
+ Private Sub OptionsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
+ With MyDefs
+ .MyViewInitialize(True)
+ .AddOkCancelToolbar()
+ With MyExchangeOptions
+ CH_DOWN_GIFS.Checked = .GifsDownload
+ TXT_GIF_FOLDER.Text = .GifsSpecialFolder
+ TXT_GIF_FOLDER.Tag = NameOf(SiteSettings.GifsSpecialFolder)
+ TXT_GIF_PREFIX.Text = .GifsPrefix
+ TXT_GIF_PREFIX.Tag = NameOf(SiteSettings.GifsPrefix)
+
+ Try
+ Dim p As PropertyOption
+ With Settings(TwitterSiteKey)
+ p = .PropList.Find(Function(pp) pp.Name = TXT_GIF_FOLDER.Tag).Options
+ If Not p Is Nothing Then
+ TXT_GIF_FOLDER.CaptionText = p.ControlText
+ TXT_GIF_FOLDER.CaptionToolTipText = p.ControlToolTip
+ TXT_GIF_FOLDER.CaptionToolTipEnabled = Not TXT_GIF_FOLDER.CaptionToolTipText.IsEmptyString
+ End If
+
+ p = .PropList.Find(Function(pp) pp.Name = TXT_GIF_PREFIX.Tag).Options
+ If Not p Is Nothing Then
+ TXT_GIF_PREFIX.CaptionText = p.ControlText
+ TXT_GIF_PREFIX.CaptionToolTipText = p.ControlToolTip
+ TXT_GIF_PREFIX.CaptionToolTipEnabled = Not TXT_GIF_PREFIX.CaptionToolTipText.IsEmptyString
+ End If
+ End With
+ Catch
+ End Try
+ End With
+ .EndLoaderOperations()
+ End With
+ End Sub
+ Private Sub MyDefs_ButtonOkClick(ByVal Sender As Object, ByVal e As KeyHandleEventArgs) Handles MyDefs.ButtonOkClick
+ With MyExchangeOptions
+ .GifsDownload = CH_DOWN_GIFS.Checked
+ .GifsSpecialFolder = TXT_GIF_FOLDER.Text
+ .GifsPrefix = TXT_GIF_PREFIX.Text
+ End With
+ MyDefs.CloseForm()
+ End Sub
+ Private Sub TXT_ActionOnTextChanged(ByVal Sender As TextBoxExtended, ByVal e As EventArgs) Handles TXT_GIF_FOLDER.ActionOnTextChanged,
+ TXT_GIF_PREFIX.ActionOnTextChanged
+ If Not MyDefs.Initializing Then
+ With Sender
+ MyGifTextProvider.PropertyName = .Tag
+ Dim s% = .SelectionStart
+ Dim t$ = AConvert(Of String)(.Text, String.Empty, MyGifTextProvider)
+ If Not .Text = t Then .Text = t : .Select(s, 0)
+ End With
+ End If
+ End Sub
+ End Class
+End Namespace
\ No newline at end of file
diff --git a/SCrawler/API/Twitter/SiteSettings.vb b/SCrawler/API/Twitter/SiteSettings.vb
index 66f2fb7..e34ca4b 100644
--- a/SCrawler/API/Twitter/SiteSettings.vb
+++ b/SCrawler/API/Twitter/SiteSettings.vb
@@ -13,10 +13,11 @@ Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools.Web.Cookies
Namespace API.Twitter
-
+
Friend Class SiteSettings : Inherits SiteSettingsBase
Friend Const Header_Authorization As String = "authorization"
Friend Const Header_Token As String = "x-csrf-token"
+#Region "Declarations"
Friend Overrides ReadOnly Property Icon As Icon
Get
Return My.Resources.SiteResources.TwitterIcon_32
@@ -27,14 +28,50 @@ Namespace API.Twitter
Return My.Resources.SiteResources.TwitterPic_400
End Get
End Property
-
Private ReadOnly Property Auth As PropertyValue
-
+
Private ReadOnly Property Token As PropertyValue
-
+
Friend ReadOnly Property SavedPostsUserName As PropertyValue
+#End Region
+#Region "Other properties"
+
+ Friend ReadOnly Property GifsDownload As PropertyValue
+
+ Friend ReadOnly Property GifsSpecialFolder As PropertyValue
+
+ Friend ReadOnly Property GifsPrefix As PropertyValue
+
+ Private ReadOnly Property GifStringChecker As IFormatProvider
+ Friend Class GifStringProvider : Implements ICustomProvider, IPropertyProvider
+ Friend Property PropertyName As String Implements IPropertyProvider.PropertyName
+ Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
+ Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
+ Dim v$ = AConvert(Of String)(Value, String.Empty)
+ If Not v.IsEmptyString Then
+ If PropertyName = NameOf(GifsPrefix) Then
+ v = v.StringRemoveWinForbiddenSymbols
+ Else
+ v = v.StringReplaceSymbols(GetWinForbiddenSymbols.ToList.ListWithRemove("\").ToArray, String.Empty, EDP.ReturnValue)
+ v = v.StringTrim("\")
+ End If
+ End If
+ Return v
+ End Function
+ Private Function GetFormat(ByVal FormatType As Type) As Object Implements IFormatProvider.GetFormat
+ Throw New NotImplementedException("[GetFormat] is not available in the context of [TimersChecker]")
+ End Function
+ End Class
+#End Region
Friend Overrides ReadOnly Property Responser As Responser
+#End Region
Friend Sub New()
MyBase.New(TwitterSite)
Responser = New Responser($"{SettingsFolderName}\Responser_{Site}.xml")
@@ -72,6 +109,11 @@ Namespace API.Twitter
Token = New PropertyValue(t, GetType(String), Sub(v) ChangeResponserFields(NameOf(Token), v))
SavedPostsUserName = New PropertyValue(String.Empty, GetType(String))
+ GifsDownload = New PropertyValue(True)
+ GifsSpecialFolder = New PropertyValue(String.Empty, GetType(String))
+ GifsPrefix = New PropertyValue("GIF_")
+ GifStringChecker = New GifStringProvider
+
UserRegex = RParams.DMS("[htps:/]{7,8}.*?twitter.com/([^/]+)", 1)
UrlPatternUser = "https://twitter.com/{0}"
ImageVideoContains = "twitter"
@@ -106,5 +148,11 @@ Namespace API.Twitter
Friend Overrides Function BaseAuthExists() As Boolean
Return If(Responser.Cookies?.Count, 0) > 0 And ACheck(Token.Value) And ACheck(Auth.Value)
End Function
+ Friend Overrides Sub UserOptions(ByRef Options As Object, ByVal OpenForm As Boolean)
+ If Options Is Nothing OrElse Not TypeOf Options Is EditorExchangeOptions Then Options = New EditorExchangeOptions(Me)
+ If OpenForm Then
+ Using f As New OptionsForm(Options) : f.ShowDialog() : End Using
+ End If
+ End Sub
End Class
End Namespace
\ No newline at end of file
diff --git a/SCrawler/API/Twitter/UserData.vb b/SCrawler/API/Twitter/UserData.vb
index f23319f..392ae7a 100644
--- a/SCrawler/API/Twitter/UserData.vb
+++ b/SCrawler/API/Twitter/UserData.vb
@@ -17,15 +17,50 @@ Imports UStates = SCrawler.API.Base.UserMedia.States
Namespace API.Twitter
Friend Class UserData : Inherits UserDataBase
Private Const SinglePostUrl As String = "https://api.twitter.com/1.1/statuses/show.json?id={0}&tweet_mode=extended"
+#Region "XML names"
+ Private Const Name_GifsDownload As String = "GifsDownload"
+ Private Const Name_GifsSpecialFolder As String = "GifsSpecialFolder"
+ Private Const Name_GifsPrefix As String = "GifsPrefix"
+#End Region
#Region "Declarations"
+ Friend Property GifsDownload As Boolean
+ Friend Property GifsSpecialFolder As String
+ Friend Property GifsPrefix As String
Private ReadOnly _DataNames As List(Of String)
- Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
+#End Region
+#Region "Exchange options"
+ Friend Overrides Function ExchangeOptionsGet() As Object
+ Return New EditorExchangeOptions(Me)
+ End Function
+ Friend Overrides Sub ExchangeOptionsSet(ByVal Obj As Object)
+ If Not Obj Is Nothing AndAlso TypeOf Obj Is EditorExchangeOptions Then
+ With DirectCast(Obj, EditorExchangeOptions)
+ GifsDownload = .GifsDownload
+ GifsSpecialFolder = .GifsSpecialFolder
+ GifsPrefix = .GifsPrefix
+ End With
+ End If
End Sub
#End Region
-#Region "Initializer"
+#Region "Initializer, loader"
Friend Sub New()
_DataNames = New List(Of String)
End Sub
+ Protected Overrides Sub LoadUserInformation_OptionalFields(ByRef Container As XmlFile, ByVal Loading As Boolean)
+ If Loading Then
+ GifsDownload = Container.Value(Name_GifsDownload).FromXML(Of Boolean)(True)
+ GifsSpecialFolder = Container.Value(Name_GifsSpecialFolder)
+ If Not Container.Contains(Name_GifsPrefix) Then
+ GifsPrefix = "GIF_"
+ Else
+ GifsPrefix = Container.Value(Name_GifsPrefix)
+ End If
+ Else
+ Container.Add(Name_GifsDownload, GifsDownload.BoolToInteger)
+ Container.Add(Name_GifsSpecialFolder, GifsSpecialFolder)
+ Container.Add(Name_GifsPrefix, GifsPrefix)
+ End If
+ End Sub
#End Region
#Region "Download functions"
Protected Overrides Sub DownloadDataF(ByVal Token As CancellationToken)
@@ -182,10 +217,11 @@ Namespace API.Twitter
url = .Value("url")
ff = UrlFile(url)
If Not ff.IsEmptyString Then
- If Not _DataNames.Contains(ff) Then
+ If GifsDownload And Not _DataNames.Contains(ff) Then
m = MediaFromData(url, PostID, PostDate,, State)
f = m.File
- If Not f.IsEmptyString Then f.Name = $"GIF_{f.Name}" : m.File = f
+ If Not f.IsEmptyString And Not GifsPrefix.IsEmptyString Then f.Name = $"{GifsPrefix}{f.Name}" : m.File = f
+ If Not GifsSpecialFolder.IsEmptyString Then m.SpecialFolder = $"{GifsSpecialFolder}*"
_TempMediaList.ListAddValue(m, LNC)
End If
Return True
diff --git a/SCrawler/Editors/UserCreatorForm.vb b/SCrawler/Editors/UserCreatorForm.vb
index 6260ae8..ae0d63a 100644
--- a/SCrawler/Editors/UserCreatorForm.vb
+++ b/SCrawler/Editors/UserCreatorForm.vb
@@ -397,6 +397,7 @@ CloseForm:
CMB_SITE.SelectedIndex = -1
CMB_SITE.Clear(ComboBoxExtended.ClearMode.Text)
CH_IS_CHANNEL.Checked = False
+ If Not UserIsCollection Then Icon = My.Resources.UsersIcon_32
End If
End If
_TextChangeInvoked = False
@@ -412,6 +413,9 @@ CloseForm:
MyExchangeOptions = Nothing
SetParamsBySite()
End Sub
+ Private Sub CMB_SITE_ActionOnTextChanged(sender As Object, e As EventArgs) Handles CMB_SITE.ActionOnTextChanged
+ If CMB_SITE.Text.IsEmptyString And Not UserIsCollection Then CMB_SITE.SelectedIndex = -1 : Icon = My.Resources.UsersIcon_32
+ End Sub
Private Sub BTT_OTHER_SETTINGS_Click(sender As Object, e As EventArgs) Handles BTT_OTHER_SETTINGS.Click
Dim s As SettingsHost = GetSiteByCheckers()
If Not s Is Nothing Then
@@ -604,9 +608,17 @@ CloseForm:
Else
BTT_OTHER_SETTINGS.Enabled = False
End If
+ If Not UserIsCollection Then
+ If Not s.Source.Icon Is Nothing Then
+ Icon = s.Source.Icon
+ ElseIf Not s.Source.Image Is Nothing Then
+ Icon = ImageRenderer.GetIcon(s.Source.Image, New ErrorsDescriber(False, False, False, My.Resources.UsersIcon_32))
+ End If
+ End If
End With
Else
BTT_OTHER_SETTINGS.Enabled = False
+ If Not UserIsCollection Then Icon = My.Resources.UsersIcon_32
End If
End Sub
Private Sub ChangeLabels()
diff --git a/SCrawler/My Project/AssemblyInfo.vb b/SCrawler/My Project/AssemblyInfo.vb
index c020c8e..43195ea 100644
--- a/SCrawler/My Project/AssemblyInfo.vb
+++ b/SCrawler/My Project/AssemblyInfo.vb
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below:
'
-
-
+
+
diff --git a/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb b/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb
index d4393c4..0fc4edc 100644
--- a/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb
+++ b/SCrawler/PluginsEnvironment/Hosts/PropertyValueHost.vb
@@ -76,6 +76,7 @@ Namespace Plugin.Hosts
.EndInit(True)
End With
AddHandler .ActionOnButtonClick, AddressOf TextBoxClick
+ If Not ProviderValue Is Nothing AndAlso ProviderValueInteraction Then AddHandler .ActionOnTextChanged, AddressOf TextBoxTextChanged
End With
End If
End If
@@ -98,6 +99,14 @@ Namespace Plugin.Hosts
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, $"Updating [{Name}] property")
End Try
End Sub
+ Private Sub TextBoxTextChanged(ByVal Sender As Object, ByVal e As EventArgs)
+ UpdateProviderPropertyName()
+ With DirectCast(Sender, TextBoxExtended)
+ Dim s% = .SelectionStart
+ Dim t$ = AConvert(Of String)(.Text, ProviderValue, String.Empty)
+ If Not t = .Text Then .Text = t : .Select(s, 0)
+ End With
+ End Sub
Friend Sub UpdateValueByControl()
If Not Control Is Nothing AndAlso Not TypeOf Control Is Label Then
If TypeOf Control Is CheckBox Then
@@ -105,6 +114,7 @@ Namespace Plugin.Hosts
If Options.ThreeStates Then Value = CInt(.CheckState) Else Value = .Checked
End With
Else
+ UpdateProviderPropertyName()
Value = AConvert(DirectCast(Control, TextBoxExtended).Text, AModes.Var, [Type],,,, ProviderValue)
End If
End If
@@ -116,12 +126,16 @@ Namespace Plugin.Hosts
If Options.ThreeStates Then Return CInt(.CheckState) Else Return .Checked
End With
Else
+ UpdateProviderPropertyName()
Return AConvert(DirectCast(Control, TextBoxExtended).Text, AModes.Var, [Type],,,, ProviderValue)
End If
Else
Return Nothing
End If
End Function
+ Private Sub UpdateProviderPropertyName()
+ If ProviderValueIsPropertyProvider Then DirectCast(ProviderValue, IPropertyProvider).PropertyName = Name
+ End Sub
#End Region
#Region "Compatibility"
Private ReadOnly Source As Object
@@ -143,9 +157,17 @@ Namespace Plugin.Hosts
End Property
#Region "Providers"
Friend Property ProviderFieldsChecker As IFormatProvider
- Friend Property ProviderValue As IFormatProvider
- Friend Sub SetProvider(ByVal Provider As IFormatProvider, ByVal FC As Boolean)
- If FC Then ProviderFieldsChecker = Provider Else ProviderValue = Provider
+ Private Property ProviderValue As IFormatProvider
+ Private Property ProviderValueInteraction As Boolean = False
+ Private Property ProviderValueIsPropertyProvider As Boolean = False
+ Friend Sub SetProvider(ByVal Provider As IFormatProvider, ByVal Instance As Provider)
+ If Instance.FieldsChecker Then
+ ProviderFieldsChecker = Provider
+ Else
+ ProviderValue = Provider
+ ProviderValueIsPropertyProvider = TypeOf ProviderValue Is IPropertyProvider
+ ProviderValueInteraction = Instance.Interaction
+ End If
End Sub
#End Region
Friend PropertiesChecking As String()
diff --git a/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb b/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb
index f0dec10..0bd7ce8 100644
--- a/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb
+++ b/SCrawler/PluginsEnvironment/Hosts/SettingsHost.vb
@@ -204,7 +204,7 @@ Namespace Plugin.Hosts
End If
Next
ElseIf m.MemberType = MemberTypes.Property Then
- If Not m.GetCustomAttribute(Of Provider)() Is Nothing Then Providers.Add(m)
+ If m.GetCustomAttributes(Of Provider)().ListExists Then Providers.Add(m)
End If
End If
End With
@@ -220,13 +220,15 @@ Namespace Plugin.Hosts
Updaters.Clear()
End If
If Providers.Count > 0 Then
- Dim prov As Provider
+ Dim prov As IEnumerable(Of Provider)
+ Dim _prov As Provider
For Each m In Providers
- prov = m.GetCustomAttribute(Of Provider)()
- i = PropList.FindIndex(Function(p) p.Name = prov.Name)
- If i >= 0 Then
- PropList(i).SetProvider(DirectCast(DirectCast(m, PropertyInfo).GetValue(Source), IFormatProvider),
- m.GetCustomAttribute(Of Provider)().FieldsChecker)
+ prov = m.GetCustomAttributes(Of Provider)()
+ If prov.ListExists Then
+ For Each _prov In prov
+ i = PropList.FindIndex(Function(p) p.Name = _prov.Name)
+ If i >= 0 Then PropList(i).SetProvider(DirectCast(DirectCast(m, PropertyInfo).GetValue(Source), IFormatProvider), _prov)
+ Next
End If
Next
Providers.Clear()
diff --git a/SCrawler/SCrawler.vbproj b/SCrawler/SCrawler.vbproj
index 8859e76..f0fe311 100644
--- a/SCrawler/SCrawler.vbproj
+++ b/SCrawler/SCrawler.vbproj
@@ -196,6 +196,13 @@
+
+
+ OptionsForm.vb
+
+
+ Form
+
@@ -416,6 +423,9 @@
RedditViewSettingsForm.vb
+
+ OptionsForm.vb
+
ChannelsStatsForm.vb
diff --git a/SCrawler/UserSearchForm.vb b/SCrawler/UserSearchForm.vb
index 00bc05a..3e6f935 100644
--- a/SCrawler/UserSearchForm.vb
+++ b/SCrawler/UserSearchForm.vb
@@ -94,56 +94,49 @@ Friend Class UserSearchForm
LIST_SEARCH.BeginUpdate()
ControlInvokeFast(LIST_SEARCH, Sub() LIST_SEARCH.Items.Clear())
Results.Clear()
- Dim t$ = TXT_SEARCH.Text.Trim
+ Dim t$ = TXT_SEARCH.Text.StringTrim.StringToLower
With Settings
If Not t.IsEmptyString And .Users.Count > 0 Then
Dim i%
Dim s As Plugin.ExchangeOptions = Nothing
- Dim cu As Boolean = False
Dim __descr As Boolean = CH_SEARCH_IN_DESCR.Checked
Dim __name As Boolean = CH_SEARCH_IN_NAME.Checked
Dim __lbl As Boolean = CH_SEARCH_IN_LABEL.Checked
- Dim _CheckUrl As Action(Of IUserData) = Sub(ByVal u As IUserData)
- If cu AndAlso ((u.Site = s.SiteName Or u.HOST.Key = s.HostKey) And u.Name.ToLower = s.UserName) Then _
- Results.ListAddValue(New SearchResult(u, SearchResult.Modes.URL), RLP)
- End Sub
- Dim _CheckDescr As Action(Of IUserData) = Sub(ByVal u As IUserData)
- If __descr AndAlso Not u.Description.IsEmptyString AndAlso
- u.Description.Contains(t) Then _
- Results.ListAddValue(New SearchResult(u, SearchResult.Modes.Description), RLP)
- End Sub
- Dim _LabelPredicate As Predicate(Of String) = Function(l) l.ToLower.Contains(t)
- Dim _CheckLabels As Action(Of IUserData) = Sub(ByVal u As IUserData)
- If __lbl AndAlso u.Labels.ListExists AndAlso u.Labels.Exists(_LabelPredicate) Then _
- Results.ListAddValue(New SearchResult(u, SearchResult.Modes.Label), RLP)
- End Sub
+ Dim __isUrl As Boolean = t.StartsWith("http")
+ Dim __urlFound As Boolean = False
+ Dim _p_url As Predicate(Of IUserData) = Function(u) __urlFound AndAlso ((u.Site = s.SiteName Or u.HOST.Key = s.HostKey) And u.Name.ToLower = s.UserName.ToLower)
+ Dim _p_descr As Predicate(Of IUserData) = Function(u) __descr AndAlso Not u.Description.IsEmptyString AndAlso u.Description.ToLower.Contains(t)
+ Dim _p_labels_p As Predicate(Of String) = Function(l) l.ToLower.Contains(t)
+ Dim _p_labels As Predicate(Of IUserData) = Function(u) __lbl AndAlso u.Labels.ListExists AndAlso u.Labels.Exists(_p_labels_p)
+ Dim _addValue As Action(Of IUserData, SearchResult.Modes, Predicate(Of IUserData)) = Sub(u, m, p) If p.Invoke(u) Then Results.ListAddValue(New SearchResult(u, m), RLP)
- If t.Length >= 4 AndAlso t.StartsWith("http") Then
+ If __isUrl Then
For Each p In Settings.Plugins
s = p.Settings.IsMyUser(t)
If Not s.UserName.IsEmptyString Then Exit For
Next
+ __urlFound = Not s.UserName.IsEmptyString
End If
- cu = Not s.UserName.IsEmptyString
- t = t.ToLower
For Each user As IUserData In .Users
- If __name AndAlso user.Name.ToLower.Contains(t) Then Results.ListAddValue(New SearchResult(user, SearchResult.Modes.Name), RLP)
+ If Not __isUrl AndAlso __name AndAlso user.Name.ToLower.Contains(t) Then Results.ListAddValue(New SearchResult(user, SearchResult.Modes.Name), RLP)
If user.IsCollection Then
With DirectCast(user, UserDataBind)
If .Count > 0 Then
For i = 0 To .Count - 1
- If __name AndAlso .Item(i).Name.ToLower = t Then Results.ListAddValue(New SearchResult(.Item(i), SearchResult.Modes.Name), RLP)
- _CheckUrl(.Item(i))
- _CheckDescr(.Item(i))
- _CheckLabels(.Item(i))
+ With .Item(i)
+ If Not __isUrl AndAlso __name AndAlso .Self.Name.ToLower = t Then Results.ListAddValue(New SearchResult(.Self, SearchResult.Modes.Name), RLP)
+ _addValue(.Self, SearchResult.Modes.URL, _p_url)
+ _addValue(.Self, SearchResult.Modes.Description, _p_descr)
+ _addValue(.Self, SearchResult.Modes.Label, _p_labels)
+ End With
Next
End If
End With
Else
- _CheckUrl(user)
- _CheckDescr(user)
- _CheckLabels(user)
+ _addValue(user, SearchResult.Modes.URL, _p_url)
+ _addValue(user, SearchResult.Modes.Description, _p_descr)
+ _addValue(user, SearchResult.Modes.Label, _p_labels)
End If
Next
If Results.Count > 0 Then