2023.1.27.0

Plugins: added 'Interaction' to 'Provider' attribute; added 'IPropertyProvider' interface
Hosts: update classes to work with new options
Instagram: fixed pinned post reload
Twitter: advanced options for GIFs
UserCreatorForm: change icon based on the selected site
UserSearchForm: change search function
This commit is contained in:
Andy
2023-01-27 16:43:57 +03:00
parent fc226d549a
commit 1f1148020c
21 changed files with 617 additions and 62 deletions

View File

@@ -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*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -100,6 +100,8 @@ Namespace Plugin.Attributes
''' <see langword="False"/> - only for conversion
''' </summary>
Public FieldsChecker As Boolean = False
''' <summary>Interaction with changing text field. Default: <see langword="False"/></summary>
Public Interaction As Boolean = False
''' <summary>Initialize a new Provider attribute. <see cref="IFormatProvider"/> is only allowed</summary>
''' <param name="PropertyName">The name of the property for which this provider is used</param>
Public Sub New(ByVal PropertyName As String)

View File

@@ -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

View File

@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2022.12.26.0")>
<Assembly: AssemblyFileVersion("2022.12.26.0")>
<Assembly: AssemblyVersion("2023.1.27.0")>
<Assembly: AssemblyFileVersion("2023.1.27.0")>
<Assembly: NeutralResourcesLanguage("en")>

View File

@@ -102,6 +102,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Attributes\Attributes.vb" />
<Compile Include="Interfaces\IPropertyProvider.vb" />
<Compile Include="Objects\ExchangeOptions.vb" />
<Compile Include="ObjectInterfaces\ILogProvider.vb" />
<Compile Include="Interfaces\IPluginContentProvider.vb" />

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class OptionsForm : Inherits System.Windows.Forms.Form
<System.Diagnostics.DebuggerNonUserCode()>
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
<System.Diagnostics.DebuggerStepThrough()>
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

View File

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@@ -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

View File

@@ -13,10 +13,11 @@ Imports PersonalUtilities.Functions.RegularExpressions
Imports PersonalUtilities.Tools.Web.Clients
Imports PersonalUtilities.Tools.Web.Cookies
Namespace API.Twitter
<Manifest("AndyProgram_Twitter"), SavedPosts>
<Manifest(TwitterSiteKey), SavedPosts, SpecialForm(False)>
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
<PropertyOption(AllowNull:=False, ControlText:="Authorization",
#Region "Auth"
<PropertyOption(AllowNull:=False, IsAuth:=True, ControlText:="Authorization",
ControlToolTip:="Set authorization from [authorization] response header. This field must start from [Bearer] key word")>
Private ReadOnly Property Auth As PropertyValue
<PropertyOption(AllowNull:=False, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header")>
<PropertyOption(AllowNull:=False, IsAuth:=True, ControlText:="Token", ControlToolTip:="Set token from [x-csrf-token] response header")>
Private ReadOnly Property Token As PropertyValue
<PropertyOption(ControlText:="Saved posts user", ControlToolTip:="Personal profile username"), PXML>
<PropertyOption(IsAuth:=True, ControlText:="Saved posts user", ControlToolTip:="Personal profile username"), PXML>
Friend ReadOnly Property SavedPostsUserName As PropertyValue
#End Region
#Region "Other properties"
<PropertyOption(IsAuth:=False, ControlText:="Download GIFs"), PXML>
Friend ReadOnly Property GifsDownload As PropertyValue
<PropertyOption(IsAuth:=False, ControlText:="GIFs special folder",
ControlToolTip:="Put the GIFs in a special folder" & vbCr &
"This is a folder name, not an absolute path." & vbCr &
"This folder(s) will be created relative to the user's root folder." & vbCr &
"Examples:" & vbCr & "SomeFolderName" & vbCr & "SomeFolderName\SomeFolderName2"), PXML>
Friend ReadOnly Property GifsSpecialFolder As PropertyValue
<PropertyOption(IsAuth:=False, ControlText:="GIF prefix", ControlToolTip:="This prefix will be added to the beginning of the filename"), PXML>
Friend ReadOnly Property GifsPrefix As PropertyValue
<Provider(NameOf(GifsSpecialFolder), Interaction:=True), Provider(NameOf(GifsPrefix), Interaction:=True)>
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

View File

@@ -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

View File

@@ -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()

View File

@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2023.1.24.1")>
<Assembly: AssemblyFileVersion("2023.1.24.1")>
<Assembly: AssemblyVersion("2023.1.27.0")>
<Assembly: AssemblyFileVersion("2023.1.27.0")>
<Assembly: NeutralResourcesLanguage("en")>

View File

@@ -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()

View File

@@ -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()

View File

@@ -196,6 +196,13 @@
<Compile Include="API\TikTok\Declarations.vb" />
<Compile Include="API\TikTok\SiteSettings.vb" />
<Compile Include="API\TikTok\UserData.vb" />
<Compile Include="API\Twitter\EditorExchangeOptions.vb" />
<Compile Include="API\Twitter\OptionsForm.Designer.vb">
<DependentUpon>OptionsForm.vb</DependentUpon>
</Compile>
<Compile Include="API\Twitter\OptionsForm.vb">
<SubType>Form</SubType>
</Compile>
<Compile Include="API\Xhamster\Declarations.vb" />
<Compile Include="API\Xhamster\M3U8.vb" />
<Compile Include="API\Xhamster\SiteSettings.vb" />
@@ -416,6 +423,9 @@
<EmbeddedResource Include="API\Reddit\RedditViewSettingsForm.resx">
<DependentUpon>RedditViewSettingsForm.vb</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="API\Twitter\OptionsForm.resx">
<DependentUpon>OptionsForm.vb</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Channels\ChannelsStatsForm.resx">
<DependentUpon>ChannelsStatsForm.vb</DependentUpon>
</EmbeddedResource>

View File

@@ -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