mirror of
https://github.com/AAndyProgram/SCrawler.git
synced 2026-03-15 00:02:17 +00:00
Compare commits
7 Commits
2023.11.24
...
2023.12.7.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a0837a1b0 | ||
|
|
0657f3d195 | ||
|
|
c92314d8e8 | ||
|
|
d99243ce46 | ||
|
|
3dae40b696 | ||
|
|
ee0c773c37 | ||
|
|
ebe5f0ca01 |
23
Changelog.md
23
Changelog.md
@@ -1,3 +1,26 @@
|
|||||||
|
# 2023.12.7.0
|
||||||
|
|
||||||
|
*2023-12-07*
|
||||||
|
|
||||||
|
- Added
|
||||||
|
- Saved posts: add downloaded saved posts to the feed
|
||||||
|
- **YouTube (SCrawler): the ability to download YouTube user community feeds**
|
||||||
|
- Main window: add `Alt+A` hotkey to show scheduler
|
||||||
|
- Main window: add `Alt+P` hotkey to show progress form
|
||||||
|
- YouTube: check of adding a URL if it has already been downloaded
|
||||||
|
- YouTube: ability to check for a new version at start
|
||||||
|
- **Updater**
|
||||||
|
- Fixed
|
||||||
|
- Standalone downloader: URL files are not deleted along with the file
|
||||||
|
- Minor bugs
|
||||||
|
|
||||||
|
# 2023.11.25.0
|
||||||
|
|
||||||
|
*2023-11-25*
|
||||||
|
|
||||||
|
- Fixed
|
||||||
|
- Reddit: missing refresh token button in the settings form
|
||||||
|
|
||||||
# 2023.11.24.0
|
# 2023.11.24.0
|
||||||
|
|
||||||
*2023-11-24*
|
*2023-11-24*
|
||||||
|
|||||||
6
FAQ.md
6
FAQ.md
@@ -113,4 +113,8 @@ A: I can only [suggest](#q-you-lost-me-your-program-is-too-complicated) you find
|
|||||||
|
|
||||||
#### Q: **Can you add a step-by-step guide or video on how to use the program?**
|
#### Q: **Can you add a step-by-step guide or video on how to use the program?**
|
||||||
|
|
||||||
A: **NO! NEVER!** The guide fully covers all the functionality of SCrawler! If you don't respect my work, I don't waste my time. If you want, you can create a video tutorial and send it to me. Then I add it. All options and what each option does described on the wiki. The wiki also contains a description of all settings and how-to configure them. For complex settings, there is a steep-by-steep guide. Read the [main](README.md) information and [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) and you won't have any problems. I have developed a program with an intuitive interface. There is a Settings button, download buttons, a context menu that drops down when a user is clicked, and other controls. Anyone can use it.
|
A: **NO! NEVER!** The guide fully covers all the functionality of SCrawler! If you don't respect my work, I don't waste my time. If you want, you can create a video tutorial and send it to me. Then I add it. All options and what each option does described on the wiki. The wiki also contains a description of all settings and how-to configure them. For complex settings, there is a steep-by-steep guide. Read the [main](README.md) information and [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) and you won't have any problems. I have developed a program with an intuitive interface. There is a Settings button, download buttons, a context menu that drops down when a user is clicked, and other controls. Anyone can use it.
|
||||||
|
|
||||||
|
**The following video shows how to add credentials:**
|
||||||
|
|
||||||
|
[](https://www.youtube.com/watch?v=XDn7zG4I700)
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
You can create a plugin for any site you want. **To create a plugin, read [this guide](https://github.com/AAndyProgram/SCrawler/wiki/Plugins).**
|
||||||
|
|
||||||
|
If you've created a plugin, you can create a [new issue](https://github.com/AAndyProgram/SCrawler/issues/new?assignees=&labels=New+Plugin&projects=&template=plugin_add.md&title=%5BNEW+PLUGIN%5D) and I'll add your plugin to the list below.
|
||||||
|
|
||||||
List of available plugins:
|
List of available plugins:
|
||||||
|
|
||||||
Tools:
|
Tools:
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 20 KiB |
@@ -30,7 +30,7 @@ A program to download photo and video from [any site](#supported-sites) (e.g. Yo
|
|||||||
|
|
||||||
# What can program do:
|
# What can program do:
|
||||||
- Download pictures and videos from users' profiles and subreddits:
|
- Download pictures and videos from users' profiles and subreddits:
|
||||||
- YouTube videos, shorts, users, artists, playlists, music, tracks;
|
- YouTube videos, shorts, community feeds, users, artists, playlists, music, tracks;
|
||||||
- Reddit images, galleries of images, videos, saved posts;
|
- Reddit images, galleries of images, videos, saved posts;
|
||||||
- Redgifs videos (https://www.redgifs.com/);
|
- Redgifs videos (https://www.redgifs.com/);
|
||||||
- Twitter images and videos, saved (bookmarked) posts;
|
- Twitter images and videos, saved (bookmarked) posts;
|
||||||
@@ -145,6 +145,10 @@ First, the program downloads the full profile. After the program downloads only
|
|||||||
|
|
||||||
**Full guide you can find [here](https://github.com/AAndyProgram/SCrawler/wiki)**
|
**Full guide you can find [here](https://github.com/AAndyProgram/SCrawler/wiki)**
|
||||||
|
|
||||||
|
**Video on how to configure**
|
||||||
|
|
||||||
|
[](https://www.youtube.com/watch?v=XDn7zG4I700)
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
**Just download the [latest release](https://github.com/AAndyProgram/SCrawler/releases/latest), unzip the program archive to any folder and enjoy.** :blush:
|
**Just download the [latest release](https://github.com/AAndyProgram/SCrawler/releases/latest), unzip the program archive to any folder and enjoy.** :blush:
|
||||||
@@ -167,6 +171,8 @@ The program has an intuitive interface.
|
|||||||
|
|
||||||
**[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
|
**[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
|
||||||
|
|
||||||
|
[](https://www.youtube.com/watch?v=XDn7zG4I700)
|
||||||
|
|
||||||
Just add a user profile and **click the ```Download``` button**.
|
Just add a user profile and **click the ```Download``` button**.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
|||||||
3
SCrawler.Shared/.editorconfig
Normal file
3
SCrawler.Shared/.editorconfig
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[*.vb]
|
||||||
|
# Modifier preferences
|
||||||
|
file_header_template = Copyright (C) Andy https://github.com/AAndyProgram\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
33
SCrawler.Shared/Functions.vb
Normal file
33
SCrawler.Shared/Functions.vb
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
' Copyright (C) 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 [Shared]
|
||||||
|
Public Module Functions
|
||||||
|
Public Const NewReleaseFolderName As String = "__NewRelease"
|
||||||
|
Public Function GetCurrentMaxVer(Optional ByVal Path As SFile = Nothing) As Version
|
||||||
|
Try
|
||||||
|
If Path.IsEmptyString Then Path = Application.StartupPath.CSFileP
|
||||||
|
If Path.Exists(SFO.Path, False) Then
|
||||||
|
Dim versions As New List(Of Version)
|
||||||
|
Dim v As FileVersionInfo
|
||||||
|
With SFile.GetFiles(Path, "*.exe",, EDP.ReturnValue).ListIfNothing.Where(Function(f) f.Name = "SCrawler" Or f.Name = "YouTubeDownloader")
|
||||||
|
If .ListExists Then
|
||||||
|
For Each f As SFile In .Self
|
||||||
|
v = FileVersionInfo.GetVersionInfo(f)
|
||||||
|
versions.Add(New Version(v.ProductVersion))
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
If versions.Count > 0 Then Return versions.LastOrDefault
|
||||||
|
End If
|
||||||
|
Catch
|
||||||
|
End Try
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
End Module
|
||||||
|
End Namespace
|
||||||
13
SCrawler.Shared/My Project/Application.Designer.vb
generated
Normal file
13
SCrawler.Shared/My Project/Application.Designer.vb
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
'------------------------------------------------------------------------------
|
||||||
|
' <auto-generated>
|
||||||
|
' This code was generated by a tool.
|
||||||
|
' Runtime Version:4.0.30319.42000
|
||||||
|
'
|
||||||
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
' the code is regenerated.
|
||||||
|
' </auto-generated>
|
||||||
|
'------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Option Strict On
|
||||||
|
Option Explicit On
|
||||||
|
|
||||||
10
SCrawler.Shared/My Project/Application.myapp
Normal file
10
SCrawler.Shared/My Project/Application.myapp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<MySubMain>false</MySubMain>
|
||||||
|
<SingleInstance>false</SingleInstance>
|
||||||
|
<ShutdownMode>0</ShutdownMode>
|
||||||
|
<EnableVisualStyles>true</EnableVisualStyles>
|
||||||
|
<AuthenticationMode>0</AuthenticationMode>
|
||||||
|
<ApplicationType>1</ApplicationType>
|
||||||
|
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
|
||||||
|
</MyApplicationData>
|
||||||
37
SCrawler.Shared/My Project/AssemblyInfo.vb
Normal file
37
SCrawler.Shared/My Project/AssemblyInfo.vb
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
Imports System.Resources
|
||||||
|
Imports System
|
||||||
|
Imports System.Reflection
|
||||||
|
Imports System.Runtime.InteropServices
|
||||||
|
|
||||||
|
' General Information about an assembly is controlled through the following
|
||||||
|
' set of attributes. Change these attribute values to modify the information
|
||||||
|
' associated with an assembly.
|
||||||
|
|
||||||
|
' Review the values of the assembly attributes
|
||||||
|
|
||||||
|
<Assembly: AssemblyTitle("SCrawler.Shared")>
|
||||||
|
<Assembly: AssemblyDescription("SCrawler shared functions")>
|
||||||
|
<Assembly: AssemblyCompany("AndyProgram")>
|
||||||
|
<Assembly: AssemblyProduct("SCrawler.Shared")>
|
||||||
|
<Assembly: AssemblyCopyright("Copyright © 2024")>
|
||||||
|
<Assembly: AssemblyTrademark("AndyProgram")>
|
||||||
|
|
||||||
|
<Assembly: ComVisible(False)>
|
||||||
|
|
||||||
|
'The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
<Assembly: Guid("75a22c7c-6f90-49cb-852b-078ea0b8f2b6")>
|
||||||
|
|
||||||
|
' Version information for an assembly consists of the following four values:
|
||||||
|
'
|
||||||
|
' Major Version
|
||||||
|
' Minor Version
|
||||||
|
' Build Number
|
||||||
|
' Revision
|
||||||
|
'
|
||||||
|
' You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
' by using the '*' as shown below:
|
||||||
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
|
<Assembly: AssemblyVersion("2023.12.7.0")>
|
||||||
|
<Assembly: AssemblyFileVersion("2023.12.7.0")>
|
||||||
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
63
SCrawler.Shared/My Project/Resources.Designer.vb
generated
Normal file
63
SCrawler.Shared/My Project/Resources.Designer.vb
generated
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
'------------------------------------------------------------------------------
|
||||||
|
' <auto-generated>
|
||||||
|
' This code was generated by a tool.
|
||||||
|
' Runtime Version:4.0.30319.42000
|
||||||
|
'
|
||||||
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
' the code is regenerated.
|
||||||
|
' </auto-generated>
|
||||||
|
'------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Option Strict On
|
||||||
|
Option Explicit On
|
||||||
|
|
||||||
|
Imports System
|
||||||
|
|
||||||
|
Namespace My.Resources
|
||||||
|
|
||||||
|
'This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
'class via a tool like ResGen or Visual Studio.
|
||||||
|
'To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
'with the /str option, or rebuild your VS project.
|
||||||
|
'''<summary>
|
||||||
|
''' A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
'''</summary>
|
||||||
|
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0"), _
|
||||||
|
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||||
|
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||||
|
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||||
|
Friend Module Resources
|
||||||
|
|
||||||
|
Private resourceMan As Global.System.Resources.ResourceManager
|
||||||
|
|
||||||
|
Private resourceCulture As Global.System.Globalization.CultureInfo
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Returns the cached ResourceManager instance used by this class.
|
||||||
|
'''</summary>
|
||||||
|
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||||
|
Get
|
||||||
|
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||||
|
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("SCrawler.Resources", GetType(Resources).Assembly)
|
||||||
|
resourceMan = temp
|
||||||
|
End If
|
||||||
|
Return resourceMan
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Overrides the current thread's CurrentUICulture property for all
|
||||||
|
''' resource lookups using this strongly typed resource class.
|
||||||
|
'''</summary>
|
||||||
|
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
||||||
|
Get
|
||||||
|
Return resourceCulture
|
||||||
|
End Get
|
||||||
|
Set
|
||||||
|
resourceCulture = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
End Module
|
||||||
|
End Namespace
|
||||||
117
SCrawler.Shared/My Project/Resources.resx
Normal file
117
SCrawler.Shared/My Project/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?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.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: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" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</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" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
73
SCrawler.Shared/My Project/Settings.Designer.vb
generated
Normal file
73
SCrawler.Shared/My Project/Settings.Designer.vb
generated
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
'------------------------------------------------------------------------------
|
||||||
|
' <auto-generated>
|
||||||
|
' This code was generated by a tool.
|
||||||
|
' Runtime Version:4.0.30319.42000
|
||||||
|
'
|
||||||
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
' the code is regenerated.
|
||||||
|
' </auto-generated>
|
||||||
|
'------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Option Strict On
|
||||||
|
Option Explicit On
|
||||||
|
|
||||||
|
|
||||||
|
Namespace My
|
||||||
|
|
||||||
|
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||||
|
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0"), _
|
||||||
|
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Partial Friend NotInheritable Class MySettings
|
||||||
|
Inherits Global.System.Configuration.ApplicationSettingsBase
|
||||||
|
|
||||||
|
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
|
||||||
|
|
||||||
|
#Region "My.Settings Auto-Save Functionality"
|
||||||
|
#If _MyType = "WindowsForms" Then
|
||||||
|
Private Shared addedHandler As Boolean
|
||||||
|
|
||||||
|
Private Shared addedHandlerLockObject As New Object
|
||||||
|
|
||||||
|
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
|
||||||
|
If My.Application.SaveMySettingsOnExit Then
|
||||||
|
My.Settings.Save()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
#End If
|
||||||
|
#End Region
|
||||||
|
|
||||||
|
Public Shared ReadOnly Property [Default]() As MySettings
|
||||||
|
Get
|
||||||
|
|
||||||
|
#If _MyType = "WindowsForms" Then
|
||||||
|
If Not addedHandler Then
|
||||||
|
SyncLock addedHandlerLockObject
|
||||||
|
If Not addedHandler Then
|
||||||
|
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
|
||||||
|
addedHandler = True
|
||||||
|
End If
|
||||||
|
End SyncLock
|
||||||
|
End If
|
||||||
|
#End If
|
||||||
|
Return defaultInstance
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
|
|
||||||
|
Namespace My
|
||||||
|
|
||||||
|
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
|
||||||
|
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||||
|
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
|
||||||
|
Friend Module MySettingsProperty
|
||||||
|
|
||||||
|
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
|
||||||
|
Friend ReadOnly Property Settings() As Global.SCrawler.My.MySettings
|
||||||
|
Get
|
||||||
|
Return Global.SCrawler.My.MySettings.Default
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
End Module
|
||||||
|
End Namespace
|
||||||
7
SCrawler.Shared/My Project/Settings.settings
Normal file
7
SCrawler.Shared/My Project/Settings.settings
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
<Settings />
|
||||||
|
</SettingsFile>
|
||||||
151
SCrawler.Shared/SCrawler.Shared.vbproj
Normal file
151
SCrawler.Shared/SCrawler.Shared.vbproj
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{DC634700-24C7-42DD-BF8F-87E6CC54E625}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<RootNamespace>SCrawler</RootNamespace>
|
||||||
|
<AssemblyName>SCrawler.Shared</AssemblyName>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<MyType>Windows</MyType>
|
||||||
|
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<DefineDebug>false</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionExplicit>On</OptionExplicit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionCompare>Binary</OptionCompare>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionStrict>Off</OptionStrict>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionInfer>On</OptionInfer>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x86\Release\</OutputPath>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Import Include="Microsoft.VisualBasic" />
|
||||||
|
<Import Include="PersonalUtilities.Functions" />
|
||||||
|
<Import Include="System" />
|
||||||
|
<Import Include="System.Collections" />
|
||||||
|
<Import Include="System.Collections.Generic" />
|
||||||
|
<Import Include="System.Data" />
|
||||||
|
<Import Include="System.Diagnostics" />
|
||||||
|
<Import Include="System.Linq" />
|
||||||
|
<Import Include="System.Windows.Forms" />
|
||||||
|
<Import Include="System.Xml.Linq" />
|
||||||
|
<Import Include="System.Threading.Tasks" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Functions.vb" />
|
||||||
|
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||||
|
<Compile Include="My Project\Application.Designer.vb">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Application.myapp</DependentUpon>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="My Project\Resources.Designer.vb">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="My Project\Settings.Designer.vb">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="My Project\Resources.resx">
|
||||||
|
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||||
|
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include=".editorconfig" />
|
||||||
|
<None Include="My Project\Application.myapp">
|
||||||
|
<Generator>MyApplicationCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<None Include="My Project\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<CustomToolNamespace>My</CustomToolNamespace>
|
||||||
|
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\MyUtilities\PersonalUtilities\PersonalUtilities.vbproj">
|
||||||
|
<Project>{8405896b-2685-4916-bc93-1fb514c323a9}</Project>
|
||||||
|
<Name>PersonalUtilities</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||||
|
</Project>
|
||||||
3
SCrawler.Updater/.editorconfig
Normal file
3
SCrawler.Updater/.editorconfig
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[*.vb]
|
||||||
|
# Modifier preferences
|
||||||
|
file_header_template = Copyright (C) Andy https://github.com/AAndyProgram\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
6
SCrawler.Updater/App.config
Normal file
6
SCrawler.Updater/App.config
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
||||||
BIN
SCrawler.Updater/Content/Icons/RainbowIcon_48.ico
Normal file
BIN
SCrawler.Updater/Content/Icons/RainbowIcon_48.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
229
SCrawler.Updater/MainMod.vb
Normal file
229
SCrawler.Updater/MainMod.vb
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
' Copyright (C) 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.Net
|
||||||
|
Imports System.IO.Compression
|
||||||
|
Imports PersonalUtilities.Functions
|
||||||
|
Imports PersonalUtilities.Functions.XML
|
||||||
|
Imports PersonalUtilities.Tools.Web.Clients
|
||||||
|
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||||
|
Imports SCrawler.Shared
|
||||||
|
Public Module MainMod
|
||||||
|
Private MyProcessID As Integer = -1
|
||||||
|
Private MyWorkingPath As SFile = Nothing
|
||||||
|
Private ReadOnly ProcessNames As String() = {"SCrawler", "YouTubeDownloader", "Updater"}
|
||||||
|
Private Silent As Boolean = False
|
||||||
|
Private Function GetConsoleResponse(ByVal Request As String) As String
|
||||||
|
Console.Write(Request)
|
||||||
|
Return Console.ReadLine
|
||||||
|
End Function
|
||||||
|
Private Function DownloadFile(ByVal URL As String, ByVal Destination As SFile) As Boolean
|
||||||
|
Try
|
||||||
|
Dim lastPerc% = -1
|
||||||
|
Dim currentCursor% = Console.CursorTop
|
||||||
|
Using w As New RWebClient With {.AsyncMode = True}
|
||||||
|
AddHandler w.DownloadProgressChanged,
|
||||||
|
New DownloadProgressChangedEventHandler(Sub(ByVal Sender As Object, ByVal e As DownloadProgressChangedEventArgs)
|
||||||
|
If lastPerc < e.ProgressPercentage Then
|
||||||
|
lastPerc = e.ProgressPercentage
|
||||||
|
Console.SetCursorPosition(0, currentCursor)
|
||||||
|
Console.Write("{0}% completed", e.ProgressPercentage)
|
||||||
|
End If
|
||||||
|
End Sub)
|
||||||
|
Return w.DownloadFile(URL, Destination, EDP.ReturnValue)
|
||||||
|
End Using
|
||||||
|
Catch ex As Exception
|
||||||
|
Return False
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Public Sub Main()
|
||||||
|
Try
|
||||||
|
MyWorkingPath = AppDomain.CurrentDomain.BaseDirectory.CSFileP
|
||||||
|
MyProcessID = Process.GetCurrentProcess.Id
|
||||||
|
Console.Title = "SCrawler updater"
|
||||||
|
With Environment.GetCommandLineArgs
|
||||||
|
If .ListExists(2) Then Silent = .Self()(1).FromXML(Of Boolean)(False)
|
||||||
|
End With
|
||||||
|
|
||||||
|
Dim currentDir As SFile = MyWorkingPath.CutPath
|
||||||
|
Dim extractionDir As SFile = $"{currentDir.CSFilePS}{NewReleaseFolderName}\"
|
||||||
|
If extractionDir.Exists(SFO.Path, False) Then extractionDir.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.None)
|
||||||
|
|
||||||
|
Dim currVer As Version = GetCurrentMaxVer(currentDir)
|
||||||
|
If currVer Is Nothing Then
|
||||||
|
Console.WriteLine("The current version of the program cannot be determined")
|
||||||
|
Else
|
||||||
|
Console.WriteLine($"The current version is {currVer} (x{IIf(Environment.Is64BitProcess, 64, 86)})")
|
||||||
|
Dim release As GitRelease = GetGitRelease()
|
||||||
|
If Not release.URL.IsEmptyString And Not release.Version Is Nothing Then
|
||||||
|
If release.Version > currVer Then
|
||||||
|
Console.WriteLine($"The new version is {release.Version} ({release.Name})")
|
||||||
|
|
||||||
|
If Not Silent AndAlso GetConsoleResponse("Do you want to update the program? (y/n): ").IfNullOrEmpty("n") = "n" Then Exit Sub
|
||||||
|
|
||||||
|
If ActiveProcessesExist() Then
|
||||||
|
Console.WriteLine("One of the SCrawler programs is still running. Waiting for all SCrawler programs to close.")
|
||||||
|
While ActiveProcessesExist() : Threading.Thread.Sleep(100) : End While
|
||||||
|
Console.WriteLine("All SCrawler programs are closed.")
|
||||||
|
End If
|
||||||
|
|
||||||
|
If extractionDir.Exists(SFO.Path, True) Then
|
||||||
|
Dim destFile As SFile = $"{extractionDir.CSFilePS}{New SFile(release.URL).File}"
|
||||||
|
Console.WriteLine("Downloading new version...")
|
||||||
|
If DownloadFile(release.URL, destFile) Then
|
||||||
|
Console.WriteLine("")
|
||||||
|
Console.WriteLine("New version downloaded!")
|
||||||
|
Console.WriteLine("Extracting files...")
|
||||||
|
ZipFile.ExtractToDirectory(destFile, extractionDir)
|
||||||
|
Console.WriteLine("Files extracted!")
|
||||||
|
destFile.Delete(SFO.File, SFODelete.DeletePermanently, EDP.None)
|
||||||
|
If Not MoveFiles(extractionDir, currentDir) Then GetConsoleResponse("Unable to update the program. Press Enter to exit") : Exit Sub
|
||||||
|
Else
|
||||||
|
extractionDir.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.None)
|
||||||
|
Console.WriteLine("Unable to download new version")
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
Console.WriteLine("Unable to create temp directory")
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
Console.WriteLine("The program is up to date")
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
Console.WriteLine("Unable to get information about new version")
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
Console.WriteLine("An error occurred during update")
|
||||||
|
Console.WriteLine(ex.Message)
|
||||||
|
Finally
|
||||||
|
GetConsoleResponse("Press Enter to exit")
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Function MoveFiles(ByVal Source As SFile, ByVal Destination As SFile) As Boolean
|
||||||
|
Console.WriteLine("Updating files")
|
||||||
|
Try
|
||||||
|
|
||||||
|
Dim oldFiles As List(Of SFile) = SFile.GetFiles(Destination,,, EDP.ReturnValue)
|
||||||
|
Dim oldFolders As List(Of SFile) = SFile.GetDirectories(Destination,,, EDP.ReturnValue)
|
||||||
|
|
||||||
|
Dim newFiles As List(Of SFile) = SFile.GetFiles(Source,,, EDP.ReturnValue)
|
||||||
|
Dim newFolders As List(Of SFile) = SFile.GetDirectories(Source,,, EDP.ReturnValue)
|
||||||
|
|
||||||
|
Dim obj As SFile = Nothing
|
||||||
|
Dim wSegment As String = MyWorkingPath.Segments.Last
|
||||||
|
Dim filesPredicate As Predicate(Of SFile) = Function(ByVal f As SFile) As Boolean
|
||||||
|
If obj = f Or obj.Name = f.Name Then
|
||||||
|
f.Delete(SFO.File, SFODelete.DeleteToRecycleBin, EDP.None)
|
||||||
|
Return True
|
||||||
|
Else
|
||||||
|
Return False
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
Dim foldersPredicate As Predicate(Of SFile) = Function(ByVal f As SFile) As Boolean
|
||||||
|
Dim ls$ = f.Segments.Last
|
||||||
|
If ls = obj.Segments.Last And Not ls = NewReleaseFolderName And Not ls = wSegment Then
|
||||||
|
f.Delete(SFO.Path, SFODelete.DeleteToRecycleBin, EDP.None)
|
||||||
|
Return True
|
||||||
|
Else
|
||||||
|
Return False
|
||||||
|
End If
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Dim getDestFile As Func(Of SFile, Boolean, SFile) = Function(ByVal f As SFile, ByVal isFolder As Boolean) As SFile
|
||||||
|
Dim ff As SFile = f
|
||||||
|
If isFolder Then
|
||||||
|
ff = $"{Destination.PathWithSeparator}{f.Segments.Last}\"
|
||||||
|
Else
|
||||||
|
ff.Path = Destination.Path
|
||||||
|
End If
|
||||||
|
Console.WriteLine(ff)
|
||||||
|
Return ff
|
||||||
|
End Function
|
||||||
|
If newFiles.ListExists Then
|
||||||
|
If oldFiles.ListExists Then
|
||||||
|
For Each obj In newFiles : oldFiles.RemoveAll(filesPredicate) : Next
|
||||||
|
End If
|
||||||
|
newFiles.ForEach(Sub(ff) SFile.Move(ff, getDestFile(ff, False), SFO.File, True, SFODelete.DeleteToRecycleBin, EDP.None))
|
||||||
|
End If
|
||||||
|
|
||||||
|
If newFolders.ListExists Then
|
||||||
|
If oldFolders.ListExists Then
|
||||||
|
For Each obj In newFolders : oldFolders.RemoveAll(foldersPredicate) : Next
|
||||||
|
End If
|
||||||
|
newFolders.ForEach(Sub(ff) If Not ff.Segments.Last = wSegment Then _
|
||||||
|
SFile.Move(ff, getDestFile(ff, True), SFO.Path, True, SFODelete.DeleteToRecycleBin, EDP.None))
|
||||||
|
End If
|
||||||
|
|
||||||
|
Console.WriteLine("Files updated")
|
||||||
|
Return True
|
||||||
|
Catch
|
||||||
|
Return False
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Private Function ActiveProcessesExist() As Boolean
|
||||||
|
Try
|
||||||
|
Return Process.GetProcesses.Any(Function(p) ProcessNames.Contains(p.ProcessName) And Not p.Id = MyProcessID)
|
||||||
|
Catch
|
||||||
|
Return True
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
Private Structure GitRelease
|
||||||
|
Friend URL As String
|
||||||
|
Friend Name As String
|
||||||
|
Friend Version As Version
|
||||||
|
End Structure
|
||||||
|
Private Function GetGitRelease() As GitRelease
|
||||||
|
Try
|
||||||
|
Dim nameEnd$ = $"_x{IIf(Environment.Is64BitProcess, 64, 86)}.zip"
|
||||||
|
Dim name$, relName$, relTag$
|
||||||
|
|
||||||
|
Using resp As New Responser With {.Accept = "application/vnd.github.v3+json"}
|
||||||
|
Dim r$ = resp.GetResponse("https://api.github.com/repos/AAndyProgram/SCrawler/releases",, EDP.ReturnValue)
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
Dim getver As Func(Of String, Version) = Function(ByVal input As String) As Version
|
||||||
|
Try
|
||||||
|
If Not input.IsEmptyString Then
|
||||||
|
If input.ToLower.StartsWith("scrawler") Then
|
||||||
|
Return New Version(input.Split("_")(1))
|
||||||
|
Else
|
||||||
|
Return New Version(input)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Catch
|
||||||
|
End Try
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
Using j As EContainer = JsonDocument.Parse(r, EDP.ReturnValue)
|
||||||
|
If j.ListExists Then
|
||||||
|
With j.FirstOrDefault(Function(e) Not e.Value("draft").FromXML(Of Boolean) And Not e.Value("prerelease").FromXML(Of Boolean))
|
||||||
|
If .ListExists Then
|
||||||
|
relName = .Value("name")
|
||||||
|
relTag = .Value("tag_name")
|
||||||
|
With .Item("assets")
|
||||||
|
If .ListExists Then
|
||||||
|
For Each asset As EContainer In .Self
|
||||||
|
name = asset.Value("name")
|
||||||
|
If Not name.IsEmptyString AndAlso name.EndsWith(nameEnd) Then _
|
||||||
|
Return New GitRelease With {
|
||||||
|
.Name = name,
|
||||||
|
.URL = asset.Value("browser_download_url"),
|
||||||
|
.Version = getver(name).IfNullOrEmpty(getver(relName).IfNullOrEmpty(getver(relTag)))}
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
Catch
|
||||||
|
End Try
|
||||||
|
Return Nothing
|
||||||
|
End Function
|
||||||
|
End Module
|
||||||
13
SCrawler.Updater/My Project/Application.Designer.vb
generated
Normal file
13
SCrawler.Updater/My Project/Application.Designer.vb
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
'------------------------------------------------------------------------------
|
||||||
|
' <auto-generated>
|
||||||
|
' This code was generated by a tool.
|
||||||
|
' Runtime Version:4.0.30319.42000
|
||||||
|
'
|
||||||
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
' the code is regenerated.
|
||||||
|
' </auto-generated>
|
||||||
|
'------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Option Strict On
|
||||||
|
Option Explicit On
|
||||||
|
|
||||||
10
SCrawler.Updater/My Project/Application.myapp
Normal file
10
SCrawler.Updater/My Project/Application.myapp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<MySubMain>false</MySubMain>
|
||||||
|
<SingleInstance>false</SingleInstance>
|
||||||
|
<ShutdownMode>0</ShutdownMode>
|
||||||
|
<EnableVisualStyles>true</EnableVisualStyles>
|
||||||
|
<AuthenticationMode>0</AuthenticationMode>
|
||||||
|
<ApplicationType>2</ApplicationType>
|
||||||
|
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
|
||||||
|
</MyApplicationData>
|
||||||
37
SCrawler.Updater/My Project/AssemblyInfo.vb
Normal file
37
SCrawler.Updater/My Project/AssemblyInfo.vb
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
Imports System.Resources
|
||||||
|
Imports System
|
||||||
|
Imports System.Reflection
|
||||||
|
Imports System.Runtime.InteropServices
|
||||||
|
|
||||||
|
' General Information about an assembly is controlled through the following
|
||||||
|
' set of attributes. Change these attribute values to modify the information
|
||||||
|
' associated with an assembly.
|
||||||
|
|
||||||
|
' Review the values of the assembly attributes
|
||||||
|
|
||||||
|
<Assembly: AssemblyTitle("SCrawler updater")>
|
||||||
|
<Assembly: AssemblyDescription("SCrawler updater")>
|
||||||
|
<Assembly: AssemblyCompany("AndyProgram")>
|
||||||
|
<Assembly: AssemblyProduct("SCrawler.Updater")>
|
||||||
|
<Assembly: AssemblyCopyright("Copyright © 2024")>
|
||||||
|
<Assembly: AssemblyTrademark("AndyProgram")>
|
||||||
|
|
||||||
|
<Assembly: ComVisible(False)>
|
||||||
|
|
||||||
|
'The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
<Assembly: Guid("df008b29-ad5e-4271-acfe-650396d15c40")>
|
||||||
|
|
||||||
|
' Version information for an assembly consists of the following four values:
|
||||||
|
'
|
||||||
|
' Major Version
|
||||||
|
' Minor Version
|
||||||
|
' Build Number
|
||||||
|
' Revision
|
||||||
|
'
|
||||||
|
' You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
' by using the '*' as shown below:
|
||||||
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
|
<Assembly: AssemblyVersion("2023.12.7.0")>
|
||||||
|
<Assembly: AssemblyFileVersion("2023.12.7.0")>
|
||||||
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
73
SCrawler.Updater/My Project/Resources.Designer.vb
generated
Normal file
73
SCrawler.Updater/My Project/Resources.Designer.vb
generated
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
'------------------------------------------------------------------------------
|
||||||
|
' <auto-generated>
|
||||||
|
' This code was generated by a tool.
|
||||||
|
' Runtime Version:4.0.30319.42000
|
||||||
|
'
|
||||||
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
' the code is regenerated.
|
||||||
|
' </auto-generated>
|
||||||
|
'------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Option Strict On
|
||||||
|
Option Explicit On
|
||||||
|
|
||||||
|
Imports System
|
||||||
|
|
||||||
|
Namespace My.Resources
|
||||||
|
|
||||||
|
'This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
'class via a tool like ResGen or Visual Studio.
|
||||||
|
'To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
'with the /str option, or rebuild your VS project.
|
||||||
|
'''<summary>
|
||||||
|
''' A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
'''</summary>
|
||||||
|
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0"), _
|
||||||
|
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||||
|
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||||
|
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||||
|
Friend Module Resources
|
||||||
|
|
||||||
|
Private resourceMan As Global.System.Resources.ResourceManager
|
||||||
|
|
||||||
|
Private resourceCulture As Global.System.Globalization.CultureInfo
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Returns the cached ResourceManager instance used by this class.
|
||||||
|
'''</summary>
|
||||||
|
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||||
|
Get
|
||||||
|
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||||
|
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("SCrawler.Resources", GetType(Resources).Assembly)
|
||||||
|
resourceMan = temp
|
||||||
|
End If
|
||||||
|
Return resourceMan
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Overrides the current thread's CurrentUICulture property for all
|
||||||
|
''' resource lookups using this strongly typed resource class.
|
||||||
|
'''</summary>
|
||||||
|
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
||||||
|
Get
|
||||||
|
Return resourceCulture
|
||||||
|
End Get
|
||||||
|
Set
|
||||||
|
resourceCulture = value
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
|
||||||
|
'''<summary>
|
||||||
|
''' Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||||
|
'''</summary>
|
||||||
|
Friend ReadOnly Property RainbowIcon_48() As System.Drawing.Icon
|
||||||
|
Get
|
||||||
|
Dim obj As Object = ResourceManager.GetObject("RainbowIcon_48", resourceCulture)
|
||||||
|
Return CType(obj,System.Drawing.Icon)
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
End Module
|
||||||
|
End Namespace
|
||||||
124
SCrawler.Updater/My Project/Resources.resx
Normal file
124
SCrawler.Updater/My Project/Resources.resx
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<?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>
|
||||||
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<data name="RainbowIcon_48" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Content\Icons\RainbowIcon_48.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
73
SCrawler.Updater/My Project/Settings.Designer.vb
generated
Normal file
73
SCrawler.Updater/My Project/Settings.Designer.vb
generated
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
'------------------------------------------------------------------------------
|
||||||
|
' <auto-generated>
|
||||||
|
' This code was generated by a tool.
|
||||||
|
' Runtime Version:4.0.30319.42000
|
||||||
|
'
|
||||||
|
' Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
' the code is regenerated.
|
||||||
|
' </auto-generated>
|
||||||
|
'------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Option Strict On
|
||||||
|
Option Explicit On
|
||||||
|
|
||||||
|
|
||||||
|
Namespace My
|
||||||
|
|
||||||
|
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||||
|
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0"), _
|
||||||
|
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Partial Friend NotInheritable Class MySettings
|
||||||
|
Inherits Global.System.Configuration.ApplicationSettingsBase
|
||||||
|
|
||||||
|
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
|
||||||
|
|
||||||
|
#Region "My.Settings Auto-Save Functionality"
|
||||||
|
#If _MyType = "WindowsForms" Then
|
||||||
|
Private Shared addedHandler As Boolean
|
||||||
|
|
||||||
|
Private Shared addedHandlerLockObject As New Object
|
||||||
|
|
||||||
|
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||||
|
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
|
||||||
|
If My.Application.SaveMySettingsOnExit Then
|
||||||
|
My.Settings.Save()
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
#End If
|
||||||
|
#End Region
|
||||||
|
|
||||||
|
Public Shared ReadOnly Property [Default]() As MySettings
|
||||||
|
Get
|
||||||
|
|
||||||
|
#If _MyType = "WindowsForms" Then
|
||||||
|
If Not addedHandler Then
|
||||||
|
SyncLock addedHandlerLockObject
|
||||||
|
If Not addedHandler Then
|
||||||
|
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
|
||||||
|
addedHandler = True
|
||||||
|
End If
|
||||||
|
End SyncLock
|
||||||
|
End If
|
||||||
|
#End If
|
||||||
|
Return defaultInstance
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
End Class
|
||||||
|
End Namespace
|
||||||
|
|
||||||
|
Namespace My
|
||||||
|
|
||||||
|
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
|
||||||
|
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||||
|
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
|
||||||
|
Friend Module MySettingsProperty
|
||||||
|
|
||||||
|
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
|
||||||
|
Friend ReadOnly Property Settings() As Global.SCrawler.My.MySettings
|
||||||
|
Get
|
||||||
|
Return Global.SCrawler.My.MySettings.Default
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
End Module
|
||||||
|
End Namespace
|
||||||
7
SCrawler.Updater/My Project/Settings.settings
Normal file
7
SCrawler.Updater/My Project/Settings.settings
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
<Settings />
|
||||||
|
</SettingsFile>
|
||||||
79
SCrawler.Updater/My Project/app.manifest
Normal file
79
SCrawler.Updater/My Project/app.manifest
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||||
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||||
|
<security>
|
||||||
|
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<!-- UAC Manifest Options
|
||||||
|
If you want to change the Windows User Account Control level replace the
|
||||||
|
requestedExecutionLevel node with one of the following.
|
||||||
|
|
||||||
|
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||||
|
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||||
|
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||||
|
|
||||||
|
Specifying requestedExecutionLevel element will disable file and registry virtualization.
|
||||||
|
Remove this element if your application requires this virtualization for backwards
|
||||||
|
compatibility.
|
||||||
|
-->
|
||||||
|
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||||
|
</requestedPrivileges>
|
||||||
|
</security>
|
||||||
|
</trustInfo>
|
||||||
|
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<!-- A list of the Windows versions that this application has been tested on
|
||||||
|
and is designed to work with. Uncomment the appropriate elements
|
||||||
|
and Windows will automatically select the most compatible environment. -->
|
||||||
|
|
||||||
|
<!-- Windows Vista -->
|
||||||
|
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||||
|
|
||||||
|
<!-- Windows 7 -->
|
||||||
|
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
|
||||||
|
|
||||||
|
<!-- Windows 8 -->
|
||||||
|
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
|
||||||
|
|
||||||
|
<!-- Windows 8.1 -->
|
||||||
|
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
|
||||||
|
|
||||||
|
<!-- Windows 10 -->
|
||||||
|
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
|
||||||
|
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
|
||||||
|
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
|
||||||
|
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
|
||||||
|
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config.
|
||||||
|
|
||||||
|
Makes the application long-path aware. See https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
|
||||||
|
<!--
|
||||||
|
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<windowsSettings>
|
||||||
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||||
|
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
|
||||||
|
</windowsSettings>
|
||||||
|
</application>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||||
|
<!--
|
||||||
|
<dependency>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity
|
||||||
|
type="win32"
|
||||||
|
name="Microsoft.Windows.Common-Controls"
|
||||||
|
version="6.0.0.0"
|
||||||
|
processorArchitecture="*"
|
||||||
|
publicKeyToken="6595b64144ccf1df"
|
||||||
|
language="*"
|
||||||
|
/>
|
||||||
|
</dependentAssembly>
|
||||||
|
</dependency>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</assembly>
|
||||||
173
SCrawler.Updater/SCrawler.Updater.vbproj
Normal file
173
SCrawler.Updater/SCrawler.Updater.vbproj
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}</ProjectGuid>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<StartupObject>Sub Main</StartupObject>
|
||||||
|
<RootNamespace>SCrawler</RootNamespace>
|
||||||
|
<AssemblyName>Updater</AssemblyName>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<MyType>Console</MyType>
|
||||||
|
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\Debug\Updater\</OutputPath>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<DefineDebug>false</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\Updater\</OutputPath>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionExplicit>On</OptionExplicit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionCompare>Binary</OptionCompare>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionStrict>Off</OptionStrict>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<OptionInfer>On</OptionInfer>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationIcon>Content\Icons\RainbowIcon_48.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationManifest>My Project\app.manifest</ApplicationManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x64\Debug\Updater\</OutputPath>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x64\Release\Updater\</OutputPath>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DefineDebug>true</DefineDebug>
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x86\Debug\Updater\</OutputPath>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<DefineTrace>true</DefineTrace>
|
||||||
|
<OutputPath>bin\x86\Release\Updater\</OutputPath>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Deployment" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.IO.Compression" />
|
||||||
|
<Reference Include="System.IO.Compression.FileSystem" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Import Include="Microsoft.VisualBasic" />
|
||||||
|
<Import Include="System" />
|
||||||
|
<Import Include="System.Collections" />
|
||||||
|
<Import Include="System.Collections.Generic" />
|
||||||
|
<Import Include="System.Data" />
|
||||||
|
<Import Include="System.Diagnostics" />
|
||||||
|
<Import Include="System.Linq" />
|
||||||
|
<Import Include="System.Xml.Linq" />
|
||||||
|
<Import Include="System.Threading.Tasks" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="MainMod.vb" />
|
||||||
|
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||||
|
<Compile Include="My Project\Application.Designer.vb">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Application.myapp</DependentUpon>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="My Project\Resources.Designer.vb">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="My Project\Settings.Designer.vb">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="My Project\Resources.resx">
|
||||||
|
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||||
|
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include=".editorconfig" />
|
||||||
|
<None Include="My Project\app.manifest" />
|
||||||
|
<None Include="My Project\Application.myapp">
|
||||||
|
<Generator>MyApplicationCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<None Include="My Project\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<CustomToolNamespace>My</CustomToolNamespace>
|
||||||
|
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Content\Icons\RainbowIcon_48.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\MyUtilities\PersonalUtilities\PersonalUtilities.vbproj">
|
||||||
|
<Project>{8405896b-2685-4916-bc93-1fb514c323a9}</Project>
|
||||||
|
<Name>PersonalUtilities</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\SCrawler.Shared\SCrawler.Shared.vbproj">
|
||||||
|
<Project>{dc634700-24c7-42dd-bf8f-87e6cc54e625}</Project>
|
||||||
|
<Name>SCrawler.Shared</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||||
|
</Project>
|
||||||
@@ -132,6 +132,8 @@ Namespace API.YouTube.Base
|
|||||||
OpenFolderInOtherProgram.Value = command
|
OpenFolderInOtherProgram.Value = command
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
<Browsable(True), GridVisible(False), XMLVN({"Environment"}, True), Category("Environment"), DisplayName("Check new version at start")>
|
||||||
|
Friend ReadOnly Property CheckUpdatesAtStart As XMLValue(Of Boolean)
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Info"
|
#Region "Info"
|
||||||
<Browsable(True), GridVisible, XMLVN({"Info"}), Category("Info"), DisplayName("Create URL files"),
|
<Browsable(True), GridVisible, XMLVN({"Info"}), Category("Info"), DisplayName("Create URL files"),
|
||||||
|
|||||||
@@ -108,5 +108,16 @@ Namespace API.YouTube
|
|||||||
Throw New NotImplementedException("'GetFormat' is not available in the 'DurationXmlConverter' context")
|
Throw New NotImplementedException("'GetFormat' is not available in the 'DurationXmlConverter' context")
|
||||||
End Function
|
End Function
|
||||||
End Class
|
End Class
|
||||||
|
Friend Sub CheckVersion(ByVal Force As Boolean)
|
||||||
|
If Not MyYouTubeSettings Is Nothing Then
|
||||||
|
With MyYouTubeSettings
|
||||||
|
If .CheckUpdatesAtStart Or Force Then
|
||||||
|
ShowProgramInfo(.ProgramText.Value.IfNullOrEmpty("YouTube Downloader"),
|
||||||
|
SCrawler.Shared.GetCurrentMaxVer(Application.StartupPath.CSFileP).IfNullOrEmpty(My.Application.Info.Version),
|
||||||
|
True, Force, .Self, True,, False, .ProgramDescription)
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
End Module
|
End Module
|
||||||
End Namespace
|
End Namespace
|
||||||
@@ -59,6 +59,8 @@ Namespace DownloadObjects.STDownloader
|
|||||||
MyDownloaderSettings = MyYouTubeSettings
|
MyDownloaderSettings = MyYouTubeSettings
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
CheckVersion(False)
|
||||||
|
|
||||||
With MyView : .Import() : .SetFormSize() : End With
|
With MyView : .Import() : .SetFormSize() : End With
|
||||||
BTT_DELETE.Enabled = False
|
BTT_DELETE.Enabled = False
|
||||||
If Not AppMode Then
|
If Not AppMode Then
|
||||||
@@ -326,7 +328,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
If Not f Is Nothing Then
|
If Not f Is Nothing Then
|
||||||
If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML
|
If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML
|
||||||
f.ShowDialog()
|
f.ShowDialog()
|
||||||
If f.DialogResult = DialogResult.OK Then ControlCreateAndAdd(c, disableDown)
|
If f.DialogResult = DialogResult.OK AndAlso ValidateContainerURL(c) Then ControlCreateAndAdd(c, disableDown)
|
||||||
f.Dispose()
|
f.Dispose()
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
@@ -340,6 +342,61 @@ Namespace DownloadObjects.STDownloader
|
|||||||
If Not pForm Is Nothing Then pForm.Dispose()
|
If Not pForm Is Nothing Then pForm.Dispose()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
Protected Function ValidateContainerURL(ByVal c As IYouTubeMediaContainer) As Boolean
|
||||||
|
Try
|
||||||
|
If Not c Is Nothing AndAlso Not c.IsMusic Then
|
||||||
|
Dim urls As List(Of String) = Nothing
|
||||||
|
Dim files As List(Of SFile) = Nothing
|
||||||
|
Dim msg As New MMessage("The media file to be added is already downloaded. Do you want to download it again?", "Download media file", {"Process", "Cancel"}, vbExclamation)
|
||||||
|
If TP_CONTROLS.Controls.Count > 0 Then
|
||||||
|
With TP_CONTROLS.Controls.Cast(Of MediaItem)
|
||||||
|
urls.ListAddList(.SelectMany(Function(ByVal m As MediaItem) As IEnumerable(Of String)
|
||||||
|
If Not m.MyContainer Is Nothing Then
|
||||||
|
Return DirectCast(m.MyContainer, YouTubeMediaContainerBase).GetUrls()
|
||||||
|
Else
|
||||||
|
Return New String() {}
|
||||||
|
End If
|
||||||
|
End Function), LAP.NotContainsOnly, EDP.ReturnValue)
|
||||||
|
files.ListAddList(.SelectMany(Function(ByVal m As MediaItem) As IEnumerable(Of SFile)
|
||||||
|
If Not m.MyContainer Is Nothing Then
|
||||||
|
Return DirectCast(m.MyContainer, YouTubeMediaContainerBase).GetFiles()
|
||||||
|
Else
|
||||||
|
Return New SFile() {}
|
||||||
|
End If
|
||||||
|
End Function), LAP.NotContainsOnly, EDP.ReturnValue)
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
If urls.ListExists Then
|
||||||
|
Dim cUrls As New List(Of String)
|
||||||
|
cUrls.ListAddList({c.URL, c.URL_BASE}, LAP.NotContainsOnly)
|
||||||
|
If urls.ListContains(cUrls) Then Return msg.Show = 0
|
||||||
|
End If
|
||||||
|
If files.ListExists And Not c.File.IsEmptyString Then Return Not files.Contains(c.File) OrElse msg.Show = 0
|
||||||
|
If c.ObjectType = YouTubeMediaType.Single AndAlso c.File.Exists Then
|
||||||
|
Dim callBack As MsgBoxButtonCallBack = Sub(r, m, b)
|
||||||
|
Dim __sfo As SFO = IIf(r.Button.CallBackObject = 0, SFO.File, SFO.Path)
|
||||||
|
If __sfo = SFO.File Then
|
||||||
|
c.File.Open(__sfo)
|
||||||
|
Else
|
||||||
|
GlobalOpenPath(c.File)
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
Return MsgBoxE(New MMessage("The following file already exists at the destination." & vbCr &
|
||||||
|
"Do you want to download it again?" & vbCr & vbCr &
|
||||||
|
$"File: {c.File}", "Download media file",
|
||||||
|
{"Process",
|
||||||
|
New MsgBoxButton("Open file") With {.IsDialogResultButton = False, .CallBackObject = 0, .CallBack = callBack},
|
||||||
|
New MsgBoxButton("Open folder") With {.IsDialogResultButton = False, .CallBackObject = 1, .CallBack = callBack},
|
||||||
|
"Cancel"}, vbExclamation) With {.ButtonsPerRow = 4}) = 0
|
||||||
|
End If
|
||||||
|
urls.ListClearDispose
|
||||||
|
files.ListClearDispose
|
||||||
|
End If
|
||||||
|
Return True
|
||||||
|
Catch ex As Exception
|
||||||
|
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex, "[VideoListForm.ValidateContainerURL]", True)
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
|
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
|
||||||
With TP_CONTROLS
|
With TP_CONTROLS
|
||||||
If .Controls.Count > 0 Then
|
If .Controls.Count > 0 Then
|
||||||
@@ -387,8 +444,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
Try : Process.Start("https://github.com/AAndyProgram/SCrawler/blob/main/HowToSupport.md") : Catch : End Try
|
Try : Process.Start("https://github.com/AAndyProgram/SCrawler/blob/main/HowToSupport.md") : Catch : End Try
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub BTT_INFO_Click(sender As Object, e As EventArgs) Handles BTT_INFO.Click
|
Private Sub BTT_INFO_Click(sender As Object, e As EventArgs) Handles BTT_INFO.Click
|
||||||
ShowProgramInfo(MyYouTubeSettings.ProgramText.Value.IfNullOrEmpty("YouTube Downloader"),
|
CheckVersion(True)
|
||||||
My.Application.Info.Version, False, True, MyYouTubeSettings, True,, False, MyYouTubeSettings.ProgramDescription)
|
|
||||||
End Sub
|
End Sub
|
||||||
Protected Overloads Sub RemoveControls(Optional ByVal Predicate As Predicate(Of MediaItem) = Nothing, Optional ByVal RemoveFiles As Boolean = False)
|
Protected Overloads Sub RemoveControls(Optional ByVal Predicate As Predicate(Of MediaItem) = Nothing, Optional ByVal RemoveFiles As Boolean = False)
|
||||||
ControlInvokeFast(TP_CONTROLS, Sub()
|
ControlInvokeFast(TP_CONTROLS, Sub()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
'
|
'
|
||||||
' This program is distributed in the hope that it will be useful,
|
' This program is distributed in the hope that it will be useful,
|
||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
|
Imports System.Threading
|
||||||
Imports PersonalUtilities.Tools
|
Imports PersonalUtilities.Tools
|
||||||
Imports PersonalUtilities.Tools.Web
|
Imports PersonalUtilities.Tools.Web
|
||||||
Imports PersonalUtilities.Functions.Messaging
|
Imports PersonalUtilities.Functions.Messaging
|
||||||
@@ -38,19 +39,54 @@ Public Module MainModShared
|
|||||||
End If
|
End If
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
Public Sub CheckNewReleaseFolder()
|
||||||
|
Try
|
||||||
|
Const updaterFolderName$ = "Updater\"
|
||||||
|
Dim f As SFile = SCrawler.Shared.NewReleaseFolderName.CSFileP
|
||||||
|
If f.Exists(SFO.Path, False) Then
|
||||||
|
Dim updater As SFile = updaterFolderName
|
||||||
|
Dim updaterNR As SFile = f.PathWithSeparator & updaterFolderName
|
||||||
|
If updaterNR.Exists(SFO.Path, False) Then
|
||||||
|
If updater.Exists(SFO.Path, False) Then updater.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.ReturnValue)
|
||||||
|
SFile.Move(updaterNR, updater, SFO.Path, True, SFODelete.DeletePermanently, EDP.ReturnValue)
|
||||||
|
End If
|
||||||
|
f.Delete(SFO.Path, SFODelete.DeletePermanently, EDP.None)
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
Public Sub ShowProgramInfo(ByVal ProgramText As String, ByVal CurrentVersion As Version, ByVal CheckForUpdate As Boolean, ByVal Force As Boolean,
|
Public Sub ShowProgramInfo(ByVal ProgramText As String, ByVal CurrentVersion As Version, ByVal CheckForUpdate As Boolean, ByVal Force As Boolean,
|
||||||
ByVal EnvirData As IDownloaderSettings, ByVal IsYouTube As Boolean,
|
ByVal EnvirData As IDownloaderSettings, ByVal IsYouTube As Boolean,
|
||||||
Optional ByRef NewVersionDestination As String = Nothing, Optional ByVal ShowNewVersionNotification As Boolean = True,
|
Optional ByRef NewVersionDestination As String = Nothing, Optional ByRef ShowNewVersionNotification As Boolean = True,
|
||||||
Optional ByVal AdditText As String = Nothing)
|
Optional ByVal AdditText As String = Nothing)
|
||||||
Try
|
Try
|
||||||
Dim GoToSite As New MsgBoxButton("Go to site") With {.CallBack = Sub(r, n, b) Process.Start("https://github.com/AAndyProgram/SCrawler/releases/latest")}
|
Dim GoToSite As New MsgBoxButton("Go to site") With {.CallBack = Sub(r, n, b) Process.Start("https://github.com/AAndyProgram/SCrawler/releases/latest")}
|
||||||
If CheckForUpdate AndAlso GitHub.NewVersionExists(CurrentVersion, "AAndyProgram", "SCrawler", NewVersionDestination) Then
|
If CheckForUpdate AndAlso GitHub.NewVersionExists(CurrentVersion, "AAndyProgram", "SCrawler", NewVersionDestination) Then
|
||||||
If ShowNewVersionNotification Or Force Then
|
If ShowNewVersionNotification Or Force Then
|
||||||
If MsgBoxE(New MMessage($"{ProgramText}: new version detected" & vbCr &
|
Dim b As New List(Of MsgBoxButton)
|
||||||
$"Current version: {CurrentVersion}" & vbCr &
|
Dim updaterFile As SFile = Nothing
|
||||||
$"New version: {NewVersionDestination}",
|
Dim updateBtt As New MsgBoxButton("Update", "Update the program using the updater") With {
|
||||||
"New version",
|
.CallBack = Sub(r, n, btt)
|
||||||
{"OK", GoToSite, "Disable notifications"})) = 2 Then ShowNewVersionNotification = False
|
Dim th As New Thread(Sub() Process.Start(New ProcessStartInfo(updaterFile, 1))) With {.IsBackground = True}
|
||||||
|
th.SetApartmentState(ApartmentState.MTA)
|
||||||
|
th.Start()
|
||||||
|
End Sub}
|
||||||
|
With SFile.GetFiles("Updater\", "*.exe",, EDP.ReturnValue).ListIfNothing
|
||||||
|
If .ListExists Then
|
||||||
|
With .FirstOrDefault(Function(f) f.Name = "Updater")
|
||||||
|
If Not .IsEmptyString Then updaterFile = .Self
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
b.AddRange({"OK", GoToSite})
|
||||||
|
If Not updaterFile.IsEmptyString Then b.Add(updateBtt)
|
||||||
|
b.Add(New MsgBoxButton("Disable notifications") With {.CallBackObject = 10})
|
||||||
|
If AConvert(Of Integer)(
|
||||||
|
MsgBoxE(New MMessage($"{ProgramText}: new version detected" & vbCr &
|
||||||
|
$"Current version: {CurrentVersion}" & vbCr &
|
||||||
|
$"New version: {NewVersionDestination}",
|
||||||
|
"New version", b) With {.ButtonsPerRow = 4}).Button.CallBackObject, -1) = 10 Then _
|
||||||
|
ShowNewVersionNotification = False
|
||||||
End If
|
End If
|
||||||
Else
|
Else
|
||||||
If Force Then
|
If Force Then
|
||||||
|
|||||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' by using the '*' as shown below:
|
' by using the '*' as shown below:
|
||||||
' <Assembly: AssemblyVersion("1.0.*")>
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2023.11.24.0")>
|
<Assembly: AssemblyVersion("2023.12.7.0")>
|
||||||
<Assembly: AssemblyFileVersion("2023.11.24.0")>
|
<Assembly: AssemblyFileVersion("2023.12.7.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
@@ -496,6 +496,12 @@ Namespace API.YouTube.Objects
|
|||||||
_IUserMedia_URL_BASE = u
|
_IUserMedia_URL_BASE = u
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
Friend Function GetUrls() As IEnumerable(Of String)
|
||||||
|
Dim urls As New List(Of String)
|
||||||
|
urls.ListAddList({URL, IUserMedia_URL_BASE}, LAP.NotContainsOnly)
|
||||||
|
If HasElements And Not IsMusic Then urls.ListAddList(Elements.SelectMany(Function(elem As YouTubeMediaContainerBase) elem.GetUrls()), LAP.NotContainsOnly)
|
||||||
|
Return urls
|
||||||
|
End Function
|
||||||
Protected Overridable Sub GenerateFileName()
|
Protected Overridable Sub GenerateFileName()
|
||||||
End Sub
|
End Sub
|
||||||
Protected Function GetPlayListTitle() As String
|
Protected Function GetPlayListTitle() As String
|
||||||
@@ -531,7 +537,7 @@ Namespace API.YouTube.Objects
|
|||||||
If ObjectType = YouTubeMediaType.Single AndAlso Not GetPlayListTitle.IsEmptyString Then _SpecialPath.StringAppend(GetPlayListTitle(), "\")
|
If ObjectType = YouTubeMediaType.Single AndAlso Not GetPlayListTitle.IsEmptyString Then _SpecialPath.StringAppend(GetPlayListTitle(), "\")
|
||||||
If Elements.Count > 0 Then Elements.ForEach(Sub(e) e.SpecialFolder = Path)
|
If Elements.Count > 0 Then Elements.ForEach(Sub(e) e.SpecialFolder = Path)
|
||||||
End Sub
|
End Sub
|
||||||
<XMLEC> Friend ReadOnly Property Files As List(Of SFile) Implements IYouTubeMediaContainer.Files
|
<XMLEC> Protected Friend ReadOnly Property Files As List(Of SFile) Implements IYouTubeMediaContainer.Files
|
||||||
<XMLEC> Protected _File As SFile
|
<XMLEC> Protected _File As SFile
|
||||||
<XMLEC> Protected Friend Property FileSetManually As Boolean = False
|
<XMLEC> Protected Friend Property FileSetManually As Boolean = False
|
||||||
Public Property FileIgnorePlaylist As Boolean = False
|
Public Property FileIgnorePlaylist As Boolean = False
|
||||||
@@ -591,6 +597,11 @@ Namespace API.YouTube.Objects
|
|||||||
File = f
|
File = f
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
|
Friend Function GetFiles() As IEnumerable(Of SFile)
|
||||||
|
Dim urls As New List(Of String)({File})
|
||||||
|
If HasElements And Not IsMusic Then urls.ListAddList(Elements.SelectMany(Function(elem As YouTubeMediaContainerBase) elem.GetFiles()), LAP.NotContainsOnly)
|
||||||
|
Return urls
|
||||||
|
End Function
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Command"
|
#Region "Command"
|
||||||
<XMLEC> Public Property UseCookies As Boolean = MyYouTubeSettings.DefaultUseCookies Implements IYouTubeMediaContainer.UseCookies
|
<XMLEC> Public Property UseCookies As Boolean = MyYouTubeSettings.DefaultUseCookies Implements IYouTubeMediaContainer.UseCookies
|
||||||
@@ -725,7 +736,7 @@ Namespace API.YouTube.Objects
|
|||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Download"
|
#Region "Download"
|
||||||
Protected Shared Sub CreateUrlFile(ByVal URL As String, ByVal File As SFile)
|
Protected Shared Function CreateUrlFile(ByVal URL As String, ByVal File As SFile) As SFile
|
||||||
Try
|
Try
|
||||||
File.Extension = "url"
|
File.Extension = "url"
|
||||||
Using t As New TextSaver(File)
|
Using t As New TextSaver(File)
|
||||||
@@ -735,9 +746,11 @@ Namespace API.YouTube.Objects
|
|||||||
t.AppendLine()
|
t.AppendLine()
|
||||||
t.Save(EDP.None)
|
t.Save(EDP.None)
|
||||||
End Using
|
End Using
|
||||||
|
Return File
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
|
Return Nothing
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Function
|
||||||
Private ReadOnly DownloadProgressPattern As RParams = RParams.DMS("\[download\]\s*([\d\.,]+)", 1, EDP.ReturnValue)
|
Private ReadOnly DownloadProgressPattern As RParams = RParams.DMS("\[download\]\s*([\d\.,]+)", 1, EDP.ReturnValue)
|
||||||
Public Property Progress As MyProgress Implements IYouTubeMediaContainer.Progress
|
Public Property Progress As MyProgress Implements IYouTubeMediaContainer.Progress
|
||||||
Private Property IDownloadableMedia_Progress As Object Implements IDownloadableMedia.Progress
|
Private Property IDownloadableMedia_Progress As Object Implements IDownloadableMedia.Progress
|
||||||
|
|||||||
@@ -273,6 +273,10 @@
|
|||||||
<Project>{d4650f6b-5a54-44b6-999b-6c675b7116b1}</Project>
|
<Project>{d4650f6b-5a54-44b6-999b-6c675b7116b1}</Project>
|
||||||
<Name>SCrawler.PluginProvider</Name>
|
<Name>SCrawler.PluginProvider</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\SCrawler.Shared\SCrawler.Shared.vbproj">
|
||||||
|
<Project>{dc634700-24c7-42dd-bf8f-87e6cc54e625}</Project>
|
||||||
|
<Name>SCrawler.Shared</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Content\Pictures\YouTubeMusicPic_96.png" />
|
<None Include="Content\Pictures\YouTubeMusicPic_96.png" />
|
||||||
|
|||||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' by using the '*' as shown below:
|
' by using the '*' as shown below:
|
||||||
' <Assembly: AssemblyVersion("1.0.*")>
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2023.11.24.0")>
|
<Assembly: AssemblyVersion("2023.12.7.0")>
|
||||||
<Assembly: AssemblyFileVersion("2023.11.24.0")>
|
<Assembly: AssemblyFileVersion("2023.12.7.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
31
SCrawler.sln
31
SCrawler.sln
@@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
VisualStudioVersion = 16.0.31515.178
|
VisualStudioVersion = 16.0.31515.178
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler", "SCrawler\SCrawler.vbproj", "{4A016FAD-9F07-4957-8BB2-AE86C88BA342}"
|
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler", "SCrawler\SCrawler.vbproj", "{4A016FAD-9F07-4957-8BB2-AE86C88BA342}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA} = {71263EEE-E25F-44DD-B0A9-F09047C0BEEA}
|
||||||
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PersonalUtilities", "..\..\MyUtilities\PersonalUtilities\PersonalUtilities.vbproj", "{8405896B-2685-4916-BC93-1FB514C323A9}"
|
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PersonalUtilities", "..\..\MyUtilities\PersonalUtilities\PersonalUtilities.vbproj", "{8405896B-2685-4916-BC93-1FB514C323A9}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -22,6 +25,10 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.YouTube", "SCrawle
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.YouTubeDownloader", "SCrawler.YouTubeDownloader\SCrawler.YouTubeDownloader.vbproj", "{3F2F2C29-4ADB-48B5-A66E-EE0F51D0DCEF}"
|
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.YouTubeDownloader", "SCrawler.YouTubeDownloader\SCrawler.YouTubeDownloader.vbproj", "{3F2F2C29-4ADB-48B5-A66E-EE0F51D0DCEF}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.Updater", "SCrawler.Updater\SCrawler.Updater.vbproj", "{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}"
|
||||||
|
EndProject
|
||||||
|
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "SCrawler.Shared", "SCrawler.Shared\SCrawler.Shared.vbproj", "{DC634700-24C7-42DD-BF8F-87E6CC54E625}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -104,6 +111,30 @@ Global
|
|||||||
{3F2F2C29-4ADB-48B5-A66E-EE0F51D0DCEF}.Release|x64.Build.0 = Release|x64
|
{3F2F2C29-4ADB-48B5-A66E-EE0F51D0DCEF}.Release|x64.Build.0 = Release|x64
|
||||||
{3F2F2C29-4ADB-48B5-A66E-EE0F51D0DCEF}.Release|x86.ActiveCfg = Release|x86
|
{3F2F2C29-4ADB-48B5-A66E-EE0F51D0DCEF}.Release|x86.ActiveCfg = Release|x86
|
||||||
{3F2F2C29-4ADB-48B5-A66E-EE0F51D0DCEF}.Release|x86.Build.0 = Release|x86
|
{3F2F2C29-4ADB-48B5-A66E-EE0F51D0DCEF}.Release|x86.Build.0 = Release|x86
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Release|x64.Build.0 = Release|x64
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{71263EEE-E25F-44DD-B0A9-F09047C0BEEA}.Release|x86.Build.0 = Release|x86
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|x64.Build.0 = Release|x64
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{DC634700-24C7-42DD-BF8F-87E6CC54E625}.Release|x86.Build.0 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -10,12 +10,21 @@ Imports System.Threading
|
|||||||
Imports SCrawler.Plugin.Hosts
|
Imports SCrawler.Plugin.Hosts
|
||||||
Imports PersonalUtilities.Forms.Toolbars
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
Imports PDownload = SCrawler.Plugin.ISiteSettings.Download
|
Imports PDownload = SCrawler.Plugin.ISiteSettings.Download
|
||||||
|
Imports UserMediaD = SCrawler.DownloadObjects.TDownloader.UserMediaD
|
||||||
Namespace API.Base
|
Namespace API.Base
|
||||||
Friend NotInheritable Class ProfileSaved
|
Friend NotInheritable Class ProfileSaved
|
||||||
Private ReadOnly Property HOST As SettingsHostCollection
|
Private ReadOnly Property HOST As SettingsHostCollection
|
||||||
Private ReadOnly Property Progress As MyProgress
|
Private ReadOnly Property Progress As MyProgress
|
||||||
Private _Unavailable As Integer, _NotReady As Integer, _ErrorCount As Integer
|
Private _Unavailable As Integer, _NotReady As Integer, _ErrorCount As Integer
|
||||||
Private _TotalImages As Integer, _TotalVideos As Integer
|
Private _TotalImages As Integer, _TotalVideos As Integer
|
||||||
|
Friend Property Session As Integer
|
||||||
|
Friend Property IncludeInTheFeed As Boolean = False
|
||||||
|
Private _FeedDataExists As Boolean = False
|
||||||
|
Friend ReadOnly Property FeedDataExists As Boolean
|
||||||
|
Get
|
||||||
|
Return _FeedDataExists
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
Friend Sub New(ByRef h As SettingsHostCollection, ByRef Bar As MyProgress)
|
Friend Sub New(ByRef h As SettingsHostCollection, ByRef Bar As MyProgress)
|
||||||
HOST = h
|
HOST = h
|
||||||
Progress = Bar
|
Progress = Bar
|
||||||
@@ -23,6 +32,7 @@ Namespace API.Base
|
|||||||
Friend Overloads Sub Download(ByVal Token As CancellationToken, ByVal Multiple As Boolean)
|
Friend Overloads Sub Download(ByVal Token As CancellationToken, ByVal Multiple As Boolean)
|
||||||
Dim n% = 0
|
Dim n% = 0
|
||||||
Dim c% = HOST.Sum(Function(h) IIf(h.DownloadSavedPosts, 1, 0))
|
Dim c% = HOST.Sum(Function(h) IIf(h.DownloadSavedPosts, 1, 0))
|
||||||
|
_FeedDataExists = False
|
||||||
_Unavailable = 0
|
_Unavailable = 0
|
||||||
_NotReady = 0
|
_NotReady = 0
|
||||||
_ErrorCount = 0
|
_ErrorCount = 0
|
||||||
@@ -30,7 +40,7 @@ Namespace API.Base
|
|||||||
_TotalVideos = 0
|
_TotalVideos = 0
|
||||||
If c > 0 Then
|
If c > 0 Then
|
||||||
For i% = 0 To HOST.Count - 1
|
For i% = 0 To HOST.Count - 1
|
||||||
If HOST(i).DownloadSavedPosts Then n += 1 : Download(HOST(i), n, c, Token, Multiple)
|
If Not Token.IsCancellationRequested And HOST(i).DownloadSavedPosts Then n += 1 : Download(HOST(i), n, c, Token, Multiple)
|
||||||
Next
|
Next
|
||||||
If c > 1 Then
|
If c > 1 Then
|
||||||
Dim s% = {_Unavailable, _NotReady, _ErrorCount}.Sum
|
Dim s% = {_Unavailable, _NotReady, _ErrorCount}.Sum
|
||||||
@@ -55,13 +65,19 @@ Namespace API.Base
|
|||||||
.LoadUserInformation()
|
.LoadUserInformation()
|
||||||
.Progress = Progress
|
.Progress = Progress
|
||||||
If Not .FileExists Then .UpdateUserInformation()
|
If Not .FileExists Then .UpdateUserInformation()
|
||||||
|
.IncludeInTheFeed = IncludeInTheFeed
|
||||||
|
|
||||||
|
Host.BeforeStartDownload(.Self, PDownload.SavedPosts)
|
||||||
|
.DownloadData(Token)
|
||||||
|
_TotalImages += .DownloadedPictures(False)
|
||||||
|
_TotalVideos += .DownloadedVideos(False)
|
||||||
|
If IncludeInTheFeed And .LatestData.Count > 0 Then
|
||||||
|
_FeedDataExists = True
|
||||||
|
Downloader.Files.AddRange(.LatestData.Select(Function(m) New UserMediaD(m, .Self, Session) With {.IsSavedPosts = True}))
|
||||||
|
End If
|
||||||
|
Progress.InformationTemporary = $"{Host.Name}{aStr} Images: { .DownloadedPictures(False)}; Videos: { .DownloadedVideos(False)}"
|
||||||
|
Host.AfterDownload(.Self, PDownload.SavedPosts)
|
||||||
End With
|
End With
|
||||||
Host.BeforeStartDownload(user, PDownload.SavedPosts)
|
|
||||||
user.DownloadData(Token)
|
|
||||||
_TotalImages += user.DownloadedPictures(False)
|
|
||||||
_TotalVideos += user.DownloadedVideos(False)
|
|
||||||
Progress.InformationTemporary = $"{Host.Name}{aStr} Images: {user.DownloadedPictures(False)}; Videos: {user.DownloadedVideos(False)}"
|
|
||||||
Host.AfterDownload(user, PDownload.SavedPosts)
|
|
||||||
End If
|
End If
|
||||||
End Using
|
End Using
|
||||||
Else
|
Else
|
||||||
@@ -72,6 +88,9 @@ Namespace API.Base
|
|||||||
_NotReady += 1
|
_NotReady += 1
|
||||||
Progress.InformationTemporary = $"Host [{Host.Name}{aStr}] is not ready"
|
Progress.InformationTemporary = $"Host [{Host.Name}{aStr}] is not ready"
|
||||||
End If
|
End If
|
||||||
|
Catch oex As OperationCanceledException When Token.IsCancellationRequested
|
||||||
|
_ErrorCount += 1
|
||||||
|
Progress.InformationTemporary = $"{Host.Name}{aStr} downloading canceled"
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
_ErrorCount += 1
|
_ErrorCount += 1
|
||||||
Progress.InformationTemporary = $"{Host.Name}{aStr} downloading error"
|
Progress.InformationTemporary = $"{Host.Name}{aStr} downloading error"
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ Namespace API.Base
|
|||||||
Set : End Set
|
Set : End Set
|
||||||
End Property
|
End Property
|
||||||
Protected Sub UpdateResponserFile()
|
Protected Sub UpdateResponserFile()
|
||||||
Dim acc$ = If(Not AccountName.IsEmptyString, $"_{AccountName}", String.Empty)
|
Dim acc$ = If(AccountName.IsEmptyString OrElse AccountName = Hosts.SettingsHost.NameAccountNameDefault, String.Empty, $"_{AccountName}")
|
||||||
Responser.File = $"{SettingsFolderName}\Responser_{Site}{acc}.xml"
|
Responser.File = $"{SettingsFolderName}\Responser_{Site}{acc}.xml"
|
||||||
_CookiesNetscapeFile = Responser.File
|
_CookiesNetscapeFile = Responser.File
|
||||||
_CookiesNetscapeFile.Name &= "_Cookies_Netscape"
|
_CookiesNetscapeFile.Name &= "_Cookies_Netscape"
|
||||||
@@ -280,12 +280,12 @@ Namespace API.Base
|
|||||||
#End Region
|
#End Region
|
||||||
Protected Sub CLONE_PROPERTIES(ByVal Source As ISiteSettings, ByVal Destination As ISiteSettings, ByVal IsUpdate As Boolean,
|
Protected Sub CLONE_PROPERTIES(ByVal Source As ISiteSettings, ByVal Destination As ISiteSettings, ByVal IsUpdate As Boolean,
|
||||||
Optional ByVal Full As Boolean = True)
|
Optional ByVal Full As Boolean = True)
|
||||||
Dim comparer As New MembersDistinctComparer
|
Dim comparer As New MembersDistinctComparerExtended
|
||||||
'0 = update
|
'0 = update
|
||||||
'1 = clone
|
'1 = clone
|
||||||
'2 = any
|
'2 = any
|
||||||
Dim filterUC As Func(Of MemberInfo, Byte, Boolean) = Function(ByVal m As MemberInfo, ByVal __mode As Byte) As Boolean
|
Dim filterUC As Func(Of MemberInfo, Byte, Boolean) = Function(ByVal m As MemberInfo, ByVal __mode As Byte) As Boolean
|
||||||
If m.GetCustomAttribute(Of DoNotUse) Is Nothing Then
|
If If(m.GetCustomAttribute(Of DoNotUse)?.Value, False) Then
|
||||||
Return False
|
Return False
|
||||||
Else
|
Else
|
||||||
With m.GetCustomAttribute(Of PClonableAttribute)
|
With m.GetCustomAttribute(Of PClonableAttribute)
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ Namespace API.Base
|
|||||||
End Get
|
End Get
|
||||||
Set(ByVal h As SettingsHost)
|
Set(ByVal h As SettingsHost)
|
||||||
_HOST = h
|
_HOST = h
|
||||||
_HostKey = h.Key
|
If Not h Is Nothing Then _HostKey = h.Key
|
||||||
End Set
|
End Set
|
||||||
End Property
|
End Property
|
||||||
Private Sub ResetHost()
|
Private Sub ResetHost()
|
||||||
@@ -1079,6 +1079,7 @@ BlockNullPicture:
|
|||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Friend Overridable Sub OpenFolder() Implements IUserData.OpenFolder
|
Friend Overridable Sub OpenFolder() Implements IUserData.OpenFolder
|
||||||
|
If MyFile.IsEmptyString And IsSavedPosts Then UpdateDataFiles()
|
||||||
GlobalOpenPath(MyFile.CutPath)
|
GlobalOpenPath(MyFile.CutPath)
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Namespace API.RedGifs
|
|||||||
t = .Headers.Value(TokenName)
|
t = .Headers.Value(TokenName)
|
||||||
End With
|
End With
|
||||||
Token = New PropertyValue(t, GetType(String), Sub(v) UpdateResponse(NameOf(Token), v))
|
Token = New PropertyValue(t, GetType(String), Sub(v) UpdateResponse(NameOf(Token), v))
|
||||||
UserAgent = New PropertyValue(Responser.UserAgent, GetType(String), Sub(v) UpdateResponse(NameOf(UserAgent), v))
|
UserAgent = New PropertyValue(If(Responser.UserAgentExists, Responser.UserAgent, String.Empty), GetType(String), Sub(v) UpdateResponse(NameOf(UserAgent), v))
|
||||||
TokenLastDateUpdated = New PropertyValue(Now.AddYears(-1), GetType(Date))
|
TokenLastDateUpdated = New PropertyValue(Now.AddYears(-1), GetType(Date))
|
||||||
TokenUpdateInterval = New PropertyValue(60 * 12, GetType(Integer))
|
TokenUpdateInterval = New PropertyValue(60 * 12, GetType(Integer))
|
||||||
TokenUpdateIntervalProvider = New TokenRefreshIntervalProvider
|
TokenUpdateIntervalProvider = New TokenRefreshIntervalProvider
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ Namespace API.YouTube
|
|||||||
Friend ReadOnly Property DownloadShorts As PropertyValue
|
Friend ReadOnly Property DownloadShorts As PropertyValue
|
||||||
<PXML, PropertyOption(ControlText:="Download user playlists"), PClonable>
|
<PXML, PropertyOption(ControlText:="Download user playlists"), PClonable>
|
||||||
Friend ReadOnly Property DownloadPlaylists As PropertyValue
|
Friend ReadOnly Property DownloadPlaylists As PropertyValue
|
||||||
|
<PXML, PropertyOption(ControlText:="Download user community: images"), PClonable>
|
||||||
|
Friend ReadOnly Property DownloadCommunityImages As PropertyValue
|
||||||
|
<PXML, PropertyOption(ControlText:="Download user community: videos"), PClonable>
|
||||||
|
Friend ReadOnly Property DownloadCommunityVideos As PropertyValue
|
||||||
<PXML, PropertyOption(ControlText:="Use cookies", ControlToolTip:="Default value for new users." & vbCr & "Use cookies when downloading data."), PClonable>
|
<PXML, PropertyOption(ControlText:="Use cookies", ControlToolTip:="Default value for new users." & vbCr & "Use cookies when downloading data."), PClonable>
|
||||||
Friend ReadOnly Property UseCookies As PropertyValue
|
Friend ReadOnly Property UseCookies As PropertyValue
|
||||||
#End Region
|
#End Region
|
||||||
@@ -30,6 +34,8 @@ Namespace API.YouTube
|
|||||||
DownloadVideos = New PropertyValue(True)
|
DownloadVideos = New PropertyValue(True)
|
||||||
DownloadShorts = New PropertyValue(False)
|
DownloadShorts = New PropertyValue(False)
|
||||||
DownloadPlaylists = New PropertyValue(False)
|
DownloadPlaylists = New PropertyValue(False)
|
||||||
|
DownloadCommunityImages = New PropertyValue(False)
|
||||||
|
DownloadCommunityVideos = New PropertyValue(False)
|
||||||
UseCookies = New PropertyValue(False)
|
UseCookies = New PropertyValue(False)
|
||||||
_SubscriptionsAllowed = True
|
_SubscriptionsAllowed = True
|
||||||
UseNetscapeCookies = True
|
UseNetscapeCookies = True
|
||||||
|
|||||||
@@ -11,16 +11,23 @@ Imports SCrawler.API.Base
|
|||||||
Imports SCrawler.API.YouTube.Base
|
Imports SCrawler.API.YouTube.Base
|
||||||
Imports SCrawler.API.YouTube.Objects
|
Imports SCrawler.API.YouTube.Objects
|
||||||
Imports PersonalUtilities.Functions.XML
|
Imports PersonalUtilities.Functions.XML
|
||||||
|
Imports PersonalUtilities.Functions.RegularExpressions
|
||||||
|
Imports PersonalUtilities.Tools.Web.Clients
|
||||||
|
Imports PersonalUtilities.Tools.Web.Documents.JSON
|
||||||
|
Imports UTypes = SCrawler.API.Base.UserMedia.Types
|
||||||
Namespace API.YouTube
|
Namespace API.YouTube
|
||||||
Friend Class UserData : Inherits UserDataBase
|
Friend Class UserData : Inherits UserDataBase
|
||||||
#Region "XML names"
|
#Region "XML names"
|
||||||
Private Const Name_DownloadYTVideos As String = "YTDownloadVideos"
|
Private Const Name_DownloadYTVideos As String = "YTDownloadVideos"
|
||||||
Private Const Name_DownloadYTShorts As String = "YTDownloadShorts"
|
Private Const Name_DownloadYTShorts As String = "YTDownloadShorts"
|
||||||
Private Const Name_DownloadYTPlaylists As String = "YTDownloadPlaylists"
|
Private Const Name_DownloadYTPlaylists As String = "YTDownloadPlaylists"
|
||||||
|
Private Const Name_DownloadYTCommunityImages As String = "YTDownloadCommunityImages"
|
||||||
|
Private Const Name_DownloadYTCommunityVideos As String = "YTDownloadCommunityVideos"
|
||||||
Private Const Name_YTUseCookies As String = "YTUseCookies"
|
Private Const Name_YTUseCookies As String = "YTUseCookies"
|
||||||
Private Const Name_IsMusic As String = "YTIsMusic"
|
Private Const Name_IsMusic As String = "YTIsMusic"
|
||||||
Private Const Name_IsChannelUser As String = "YTIsChannelUser"
|
Private Const Name_IsChannelUser As String = "YTIsChannelUser"
|
||||||
Private Const Name_YTMediaType As String = "YTMediaType"
|
Private Const Name_YTMediaType As String = "YTMediaType"
|
||||||
|
Private Const Name_ChannelID As String = "ChannelID"
|
||||||
Private Const Name_LastDownloadDateVideos As String = "YTLastDownloadDateVideos"
|
Private Const Name_LastDownloadDateVideos As String = "YTLastDownloadDateVideos"
|
||||||
Private Const Name_LastDownloadDateShorts As String = "YTLastDownloadDateShorts"
|
Private Const Name_LastDownloadDateShorts As String = "YTLastDownloadDateShorts"
|
||||||
Private Const Name_LastDownloadDatePlaylist As String = "YTLastDownloadDatePlaylist"
|
Private Const Name_LastDownloadDatePlaylist As String = "YTLastDownloadDatePlaylist"
|
||||||
@@ -29,6 +36,9 @@ Namespace API.YouTube
|
|||||||
Friend Property DownloadYTVideos As Boolean = True
|
Friend Property DownloadYTVideos As Boolean = True
|
||||||
Friend Property DownloadYTShorts As Boolean = False
|
Friend Property DownloadYTShorts As Boolean = False
|
||||||
Friend Property DownloadYTPlaylists As Boolean = False
|
Friend Property DownloadYTPlaylists As Boolean = False
|
||||||
|
Friend Property DownloadYTCommunityImages As Boolean = False
|
||||||
|
Friend Property DownloadYTCommunityVideos As Boolean = False
|
||||||
|
Friend Property ChannelID As String = String.Empty
|
||||||
Friend Property YTUseCookies As Boolean = False
|
Friend Property YTUseCookies As Boolean = False
|
||||||
Friend Property IsMusic As Boolean = False
|
Friend Property IsMusic As Boolean = False
|
||||||
Friend Property IsChannelUser As Boolean = False
|
Friend Property IsChannelUser As Boolean = False
|
||||||
@@ -70,6 +80,9 @@ Namespace API.YouTube
|
|||||||
DownloadYTVideos = .Value(Name_DownloadYTVideos).FromXML(Of Boolean)(True)
|
DownloadYTVideos = .Value(Name_DownloadYTVideos).FromXML(Of Boolean)(True)
|
||||||
DownloadYTShorts = .Value(Name_DownloadYTShorts).FromXML(Of Boolean)(False)
|
DownloadYTShorts = .Value(Name_DownloadYTShorts).FromXML(Of Boolean)(False)
|
||||||
DownloadYTPlaylists = .Value(Name_DownloadYTPlaylists).FromXML(Of Boolean)(False)
|
DownloadYTPlaylists = .Value(Name_DownloadYTPlaylists).FromXML(Of Boolean)(False)
|
||||||
|
DownloadYTCommunityImages = .Value(Name_DownloadYTCommunityImages).FromXML(Of Boolean)(False)
|
||||||
|
DownloadYTCommunityVideos = .Value(Name_DownloadYTCommunityVideos).FromXML(Of Boolean)(False)
|
||||||
|
ChannelID = .Value(Name_ChannelID)
|
||||||
IsMusic = .Value(Name_IsMusic).FromXML(Of Boolean)(False)
|
IsMusic = .Value(Name_IsMusic).FromXML(Of Boolean)(False)
|
||||||
IsChannelUser = .Value(Name_IsChannelUser).FromXML(Of Boolean)(False)
|
IsChannelUser = .Value(Name_IsChannelUser).FromXML(Of Boolean)(False)
|
||||||
YTMediaType = .Value(Name_YTMediaType).FromXML(Of Integer)(YouTubeMediaType.Undefined)
|
YTMediaType = .Value(Name_YTMediaType).FromXML(Of Integer)(YouTubeMediaType.Undefined)
|
||||||
@@ -83,6 +96,9 @@ Namespace API.YouTube
|
|||||||
.Add(Name_DownloadYTVideos, DownloadYTVideos.BoolToInteger)
|
.Add(Name_DownloadYTVideos, DownloadYTVideos.BoolToInteger)
|
||||||
.Add(Name_DownloadYTShorts, DownloadYTShorts.BoolToInteger)
|
.Add(Name_DownloadYTShorts, DownloadYTShorts.BoolToInteger)
|
||||||
.Add(Name_DownloadYTPlaylists, DownloadYTPlaylists.BoolToInteger)
|
.Add(Name_DownloadYTPlaylists, DownloadYTPlaylists.BoolToInteger)
|
||||||
|
.Add(Name_DownloadYTCommunityImages, DownloadYTCommunityImages.BoolToInteger)
|
||||||
|
.Add(Name_DownloadYTCommunityVideos, DownloadYTCommunityVideos.BoolToInteger)
|
||||||
|
.Add(Name_ChannelID, ChannelID)
|
||||||
.Add(Name_IsMusic, IsMusic.BoolToInteger)
|
.Add(Name_IsMusic, IsMusic.BoolToInteger)
|
||||||
.Add(Name_IsChannelUser, IsChannelUser.BoolToInteger)
|
.Add(Name_IsChannelUser, IsChannelUser.BoolToInteger)
|
||||||
.Add(Name_YTMediaType, CInt(YTMediaType))
|
.Add(Name_YTMediaType, CInt(YTMediaType))
|
||||||
@@ -103,7 +119,10 @@ Namespace API.YouTube
|
|||||||
DownloadYTVideos = .DownloadVideos
|
DownloadYTVideos = .DownloadVideos
|
||||||
DownloadYTShorts = .DownloadShorts
|
DownloadYTShorts = .DownloadShorts
|
||||||
DownloadYTPlaylists = .DownloadPlaylists
|
DownloadYTPlaylists = .DownloadPlaylists
|
||||||
|
DownloadYTCommunityImages = .DownloadCommunityImages
|
||||||
|
DownloadYTCommunityVideos = .DownloadCommunityVideos
|
||||||
YTUseCookies = .UseCookies
|
YTUseCookies = .UseCookies
|
||||||
|
ChannelID = .ChannelID
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
@@ -184,6 +203,7 @@ Namespace API.YouTube
|
|||||||
applySpecFolder.Invoke("Playlists", True)
|
applySpecFolder.Invoke("Playlists", True)
|
||||||
If fillList.Invoke(LastDownloadDatePlaylist) Then LastDownloadDatePlaylist = If(maxDate, Now)
|
If fillList.Invoke(LastDownloadDatePlaylist) Then LastDownloadDatePlaylist = If(maxDate, Now)
|
||||||
End If
|
End If
|
||||||
|
If Not IsMusic And (DownloadYTCommunityImages Or DownloadYTCommunityVideos) Then DownloadCommunity(String.Empty, Token)
|
||||||
Else
|
Else
|
||||||
Throw New InvalidOperationException($"Media type {YTMediaType} not implemented")
|
Throw New InvalidOperationException($"Media type {YTMediaType} not implemented")
|
||||||
End If
|
End If
|
||||||
@@ -203,10 +223,201 @@ Namespace API.YouTube
|
|||||||
pr.Dispose()
|
pr.Dispose()
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Sub DownloadCommunity(ByVal Cursor As String, ByVal Token As CancellationToken, Optional ByVal Round As Integer = 0)
|
||||||
|
Dim URL$ = String.Empty
|
||||||
|
Try
|
||||||
|
Const postIdTemp$ = "Community_{0}"
|
||||||
|
Const specFolder$ = "Community"
|
||||||
|
Dim nextToken$ = String.Empty
|
||||||
|
Dim postId$ = String.Empty, videoId$ = String.Empty
|
||||||
|
Dim tmpPID$
|
||||||
|
Dim imgCount%, imgNum%
|
||||||
|
Dim postUrl As Func(Of String) = Function() $"https://www.youtube.com/post/{postId}"
|
||||||
|
Dim image As EContainer, thumb As EContainer
|
||||||
|
Dim sl As New List(Of Sizes)
|
||||||
|
Dim m As UserMedia
|
||||||
|
Dim v As IYouTubeMediaContainer
|
||||||
|
|
||||||
|
If ChannelID.IsEmptyString Then GetChannelID()
|
||||||
|
If ChannelID.IsEmptyString Then Throw New ArgumentNullException("ChannelID", "Channel ID cannot be null")
|
||||||
|
|
||||||
|
URL = $"https://yt.lemnoslife.com/channels?part=community&id={ChannelID}"
|
||||||
|
If Not Cursor.IsEmptyString Then URL &= $"&pageToken={Cursor}"
|
||||||
|
|
||||||
|
ProgressPre.ChangeMax(1)
|
||||||
|
|
||||||
|
Using resp As New Responser
|
||||||
|
Dim r$ = resp.GetResponse(URL,, EDP.ReturnValue)
|
||||||
|
ProgressPre.Perform()
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
Using j As EContainer = JsonDocument.Parse(r)
|
||||||
|
If j.ListExists Then
|
||||||
|
With j.ItemF({"items", 0})
|
||||||
|
If .ListExists Then
|
||||||
|
nextToken = .Value("nextPageToken")
|
||||||
|
With .Item("community")
|
||||||
|
If .ListExists Then
|
||||||
|
ProgressPre.ChangeMax(.Count)
|
||||||
|
For Each jj As EContainer In .Self
|
||||||
|
With jj
|
||||||
|
postId = .Value("id")
|
||||||
|
videoId = .Value("videoId")
|
||||||
|
tmpPID = String.Format(postIdTemp, postId)
|
||||||
|
If Not _TempPostsList.Contains(tmpPID) Then _TempPostsList.Add(tmpPID) Else Exit Sub
|
||||||
|
|
||||||
|
If Not videoId.IsEmptyString Then
|
||||||
|
If DownloadYTCommunityVideos Then
|
||||||
|
v = Nothing
|
||||||
|
Try : v = YouTubeFunctions.Parse($"https://www.youtube.com/watch?v={videoId}", YTUseCookies, Token) : Catch : End Try
|
||||||
|
If Not v Is Nothing Then
|
||||||
|
With DirectCast(v, YouTubeMediaContainerBase)
|
||||||
|
.SpecialPath = specFolder & "\Videos"
|
||||||
|
.SpecialPathDisabled = False
|
||||||
|
End With
|
||||||
|
_TempMediaList.ListAddValue(New UserMedia(v) With {.Post = postId}, LNC)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
ElseIf DownloadYTCommunityImages Then
|
||||||
|
With .Item("images")
|
||||||
|
If .ListExists Then
|
||||||
|
imgCount = .Count
|
||||||
|
imgNum = 0
|
||||||
|
For Each image In .Self
|
||||||
|
imgNum += 1
|
||||||
|
sl.Clear()
|
||||||
|
With image("thumbnails")
|
||||||
|
If .ListExists Then
|
||||||
|
For Each thumb In .Self : sl.Add(New Sizes(thumb.Value("width"), thumb.Value("url"))) : Next
|
||||||
|
If sl.Count > 0 Then sl.RemoveAll(Function(s) s.HasError Or s.Data.IsEmptyString)
|
||||||
|
If sl.Count > 0 Then
|
||||||
|
sl.Sort()
|
||||||
|
m = New UserMedia(sl(0).Data, UTypes.Picture) With {
|
||||||
|
.URL_BASE = postUrl.Invoke,
|
||||||
|
.Post = postId,
|
||||||
|
.SpecialFolder = specFolder,
|
||||||
|
.File = $"{postId}{IIf(imgCount > 1, $"_{imgNum}", String.Empty)}.jpg"
|
||||||
|
}
|
||||||
|
_TempMediaList.Add(m)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
|
||||||
|
ProgressPre.Perform()
|
||||||
|
End With
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
ElseIf resp.HasError Then
|
||||||
|
If resp.Status = Net.WebExceptionStatus.ConnectFailure And Round < 2 Then
|
||||||
|
Thread.Sleep(1000)
|
||||||
|
DownloadCommunity(Cursor, Token, Round + 1)
|
||||||
|
Else
|
||||||
|
Throw resp.ErrorException
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Using
|
||||||
|
|
||||||
|
If Not nextToken.IsEmptyString Then DownloadCommunity(nextToken, Token)
|
||||||
|
Catch ex As Exception
|
||||||
|
ProcessException(ex, Token, "community data downloading error")
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
Private Sub GetChannelID()
|
||||||
|
Try
|
||||||
|
Dim r$ = GetWebString(GetUserUrl,, EDP.ThrowException)
|
||||||
|
If Not r.IsEmptyString Then
|
||||||
|
Dim newUrl$ = RegexReplace(r, RParams.DMS("meta property=.og:url..content=.([^""]+)", 1, EDP.ReturnValue))
|
||||||
|
If Not newUrl.IsEmptyString Then
|
||||||
|
Dim newID$ = String.Empty
|
||||||
|
YouTubeFunctions.Info_GetUrlType(newUrl,,,, newID)
|
||||||
|
If Not newID.IsEmptyString And Not ChannelID = newID Then ChannelID = newID : _ForceSaveUserInfo = True
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Catch ex As Exception
|
||||||
|
ProcessException(ex, Nothing, "error getting channel ID")
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
Protected Overrides Sub DownloadContent(ByVal Token As CancellationToken)
|
||||||
SeparateVideoFolder = False
|
SeparateVideoFolder = False
|
||||||
DownloadContentDefault(Token)
|
DownloadContentDefault(Token)
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Class YTPreProgressContainer : Inherits PersonalUtilities.Forms.Toolbars.MyProgress
|
||||||
|
Private ReadOnly MyPreProgress As PreProgress
|
||||||
|
Friend Sub New(ByVal PR As PreProgress)
|
||||||
|
MyBase.New(PR.Progress.MyControls)
|
||||||
|
MyPreProgress = PR
|
||||||
|
End Sub
|
||||||
|
Private _MaxChanged As Boolean = False
|
||||||
|
Public Overrides Property Maximum As Double
|
||||||
|
Get
|
||||||
|
Return MyPreProgress.Progress.Maximum0
|
||||||
|
End Get
|
||||||
|
Set(ByVal max As Double)
|
||||||
|
MyPreProgress.Progress.Maximum0 += max
|
||||||
|
_MaxChanged = True
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Private _LastValue As Double = -1
|
||||||
|
Private _FirstAdded As Boolean = False
|
||||||
|
Public Overrides Property Value As Double
|
||||||
|
Get
|
||||||
|
Return MyPreProgress.Progress.Value0
|
||||||
|
End Get
|
||||||
|
Set(ByVal v As Double)
|
||||||
|
If _MaxChanged Then
|
||||||
|
If Not _FirstAdded Then
|
||||||
|
_FirstAdded = True
|
||||||
|
ElseIf v > 0 Then
|
||||||
|
Dim newValue#
|
||||||
|
If _LastValue = -1 Then
|
||||||
|
newValue = v
|
||||||
|
ElseIf _LastValue > v Then
|
||||||
|
newValue = v
|
||||||
|
Else
|
||||||
|
newValue = v - _LastValue
|
||||||
|
End If
|
||||||
|
_LastValue = v
|
||||||
|
MyPreProgress.Progress.Value0 += newValue
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
|
Public Overrides Sub Perform(Optional ByVal Value As Double = 1)
|
||||||
|
MyPreProgress.Perform(Value)
|
||||||
|
End Sub
|
||||||
|
Public Overrides Sub Reset()
|
||||||
|
MyPreProgress.Reset()
|
||||||
|
End Sub
|
||||||
|
Public Overrides Sub Done()
|
||||||
|
MyPreProgress.Done()
|
||||||
|
End Sub
|
||||||
|
Public Overrides Property Information As String
|
||||||
|
Get
|
||||||
|
Return String.Empty
|
||||||
|
End Get
|
||||||
|
Set : End Set
|
||||||
|
End Property
|
||||||
|
Public Overrides WriteOnly Property InformationTemporary(Optional ByVal AddPercentage As Boolean = False) As String
|
||||||
|
Set : End Set
|
||||||
|
End Property
|
||||||
|
Public Overrides Function GetLabelText() As String
|
||||||
|
Return String.Empty
|
||||||
|
End Function
|
||||||
|
Public Overrides Property Visible(Optional ByVal ProgressBar As Boolean = True, Optional ByVal Label As Boolean = True) As Boolean
|
||||||
|
Get
|
||||||
|
Return True
|
||||||
|
End Get
|
||||||
|
Set : End Set
|
||||||
|
End Property
|
||||||
|
End Class
|
||||||
Protected Overrides Function DownloadFile(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile,
|
Protected Overrides Function DownloadFile(ByVal URL As String, ByVal Media As UserMedia, ByVal DestinationFile As SFile,
|
||||||
ByVal Token As CancellationToken) As SFile
|
ByVal Token As CancellationToken) As SFile
|
||||||
If Not Media.Object Is Nothing AndAlso TypeOf Media.Object Is IYouTubeMediaContainer Then
|
If Not Media.Object Is Nothing AndAlso TypeOf Media.Object Is IYouTubeMediaContainer Then
|
||||||
@@ -215,13 +426,17 @@ Namespace API.YouTube
|
|||||||
f.Path = DestinationFile.Path
|
f.Path = DestinationFile.Path
|
||||||
If Not IsSingleObjectDownload And Not .FileIsPlaylistObject Then .FileIgnorePlaylist = True
|
If Not IsSingleObjectDownload And Not .FileIsPlaylistObject Then .FileIgnorePlaylist = True
|
||||||
.File = f
|
.File = f
|
||||||
If IsSingleObjectDownload Then .Progress = Progress
|
If IsSingleObjectDownload Then .Progress = Progress Else .Progress = New YTPreProgressContainer(ProgressPre)
|
||||||
.Download(YTUseCookies, Token)
|
.Download(YTUseCookies, Token)
|
||||||
|
If Not .Progress Is Nothing AndAlso TypeOf .Progress Is YTPreProgressContainer Then .Progress.Dispose()
|
||||||
If .File.Exists Then Return .File
|
If .File.Exists Then Return .File
|
||||||
End With
|
End With
|
||||||
End If
|
End If
|
||||||
Return Nothing
|
Return Nothing
|
||||||
End Function
|
End Function
|
||||||
|
Protected Overrides Function ValidateDownloadFile(ByVal URL As String, ByVal Media As UserMedia, ByRef Interrupt As Boolean) As Boolean
|
||||||
|
Return Not Media.Type = UTypes.Picture
|
||||||
|
End Function
|
||||||
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
|
Protected Overrides Sub DownloadSingleObject_GetPosts(ByVal Data As IYouTubeMediaContainer, ByVal Token As CancellationToken)
|
||||||
_TempMediaList.Add(New UserMedia(Data))
|
_TempMediaList.Add(New UserMedia(Data))
|
||||||
End Sub
|
End Sub
|
||||||
|
|||||||
@@ -15,18 +15,29 @@ Namespace API.YouTube
|
|||||||
Friend Property DownloadShorts As Boolean
|
Friend Property DownloadShorts As Boolean
|
||||||
<PSetting(Caption:="Download playlists")>
|
<PSetting(Caption:="Download playlists")>
|
||||||
Friend Property DownloadPlaylists As Boolean
|
Friend Property DownloadPlaylists As Boolean
|
||||||
|
<PSetting(Caption:="Download community images")>
|
||||||
|
Friend Property DownloadCommunityImages As Boolean
|
||||||
|
<PSetting(Caption:="Download community videos")>
|
||||||
|
Friend Property DownloadCommunityVideos As Boolean
|
||||||
<PSetting(Caption:="Use cookies", ToolTip:="Use cookies when downloading data.")>
|
<PSetting(Caption:="Use cookies", ToolTip:="Use cookies when downloading data.")>
|
||||||
Friend Property UseCookies As Boolean
|
Friend Property UseCookies As Boolean
|
||||||
|
<PSetting(Caption:="Channel ID", Address:=SettingAddress.User)>
|
||||||
|
Friend Property ChannelID As String
|
||||||
Friend Sub New(ByVal u As UserData)
|
Friend Sub New(ByVal u As UserData)
|
||||||
DownloadVideos = u.DownloadYTVideos
|
DownloadVideos = u.DownloadYTVideos
|
||||||
DownloadShorts = u.DownloadYTShorts
|
DownloadShorts = u.DownloadYTShorts
|
||||||
DownloadPlaylists = u.DownloadYTPlaylists
|
DownloadPlaylists = u.DownloadYTPlaylists
|
||||||
|
DownloadCommunityImages = u.DownloadYTCommunityImages
|
||||||
|
DownloadCommunityVideos = u.DownloadYTCommunityVideos
|
||||||
UseCookies = u.YTUseCookies
|
UseCookies = u.YTUseCookies
|
||||||
|
ChannelID = u.ChannelID
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub New(ByVal s As SiteSettings)
|
Friend Sub New(ByVal s As SiteSettings)
|
||||||
DownloadVideos = s.DownloadVideos.Value
|
DownloadVideos = s.DownloadVideos.Value
|
||||||
DownloadShorts = s.DownloadShorts.Value
|
DownloadShorts = s.DownloadShorts.Value
|
||||||
DownloadPlaylists = s.DownloadPlaylists.Value
|
DownloadPlaylists = s.DownloadPlaylists.Value
|
||||||
|
DownloadCommunityImages = s.DownloadCommunityImages.Value
|
||||||
|
DownloadCommunityVideos = s.DownloadCommunityVideos.Value
|
||||||
UseCookies = s.UseCookies.Value
|
UseCookies = s.UseCookies.Value
|
||||||
End Sub
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
|
|||||||
@@ -339,6 +339,7 @@ Namespace DownloadObjects
|
|||||||
.Name = String.Empty
|
.Name = String.Empty
|
||||||
._Mode = _Mode
|
._Mode = _Mode
|
||||||
.Groups.ListAddList(Groups, LAP.ClearBeforeAdd)
|
.Groups.ListAddList(Groups, LAP.ClearBeforeAdd)
|
||||||
|
.IsManual = IsManual
|
||||||
.Timer = Timer
|
.Timer = Timer
|
||||||
.StartupDelay = StartupDelay
|
.StartupDelay = StartupDelay
|
||||||
.ShowNotifications = ShowNotifications
|
.ShowNotifications = ShowNotifications
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
' This program is distributed in the hope that it will be useful,
|
' This program is distributed in the hope that it will be useful,
|
||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
Imports PersonalUtilities.Forms.Toolbars
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
|
Imports PersonalUtilities.Forms.Controls.KeyClick
|
||||||
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
Imports Download = SCrawler.Plugin.ISiteSettings.Download
|
||||||
Imports TDJob = SCrawler.DownloadObjects.TDownloader.Job
|
Imports TDJob = SCrawler.DownloadObjects.TDownloader.Job
|
||||||
Namespace DownloadObjects
|
Namespace DownloadObjects
|
||||||
@@ -14,6 +15,7 @@ Namespace DownloadObjects
|
|||||||
#Region "Events"
|
#Region "Events"
|
||||||
Friend Event DownloadDone As NotificationEventHandler
|
Friend Event DownloadDone As NotificationEventHandler
|
||||||
Friend Event ProgressChanged(ByVal Main As Boolean, ByVal IsMaxValue As Boolean, ByVal IsDone As Boolean)
|
Friend Event ProgressChanged(ByVal Main As Boolean, ByVal IsMaxValue As Boolean, ByVal IsDone As Boolean)
|
||||||
|
Friend Event FeedFilesChanged As TDownloader.FeedFilesChangedEventHandler
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Declarations"
|
#Region "Declarations"
|
||||||
#Region "Controls"
|
#Region "Controls"
|
||||||
@@ -26,14 +28,18 @@ Namespace DownloadObjects
|
|||||||
Private ReadOnly PR_PRE As ProgressBar
|
Private ReadOnly PR_PRE As ProgressBar
|
||||||
Private ReadOnly LBL_INFO As Label
|
Private ReadOnly LBL_INFO As Label
|
||||||
Private ReadOnly Icon As PictureBox
|
Private ReadOnly Icon As PictureBox
|
||||||
|
Private ReadOnly TT_MAIN As ToolTip
|
||||||
#End Region
|
#End Region
|
||||||
Private ReadOnly Property Instance As API.Base.ProfileSaved
|
Private ReadOnly Property Instance As API.Base.ProfileSaved
|
||||||
Friend ReadOnly Property Job As TDJob
|
Friend ReadOnly Property Job As TDJob
|
||||||
|
Private ReadOnly InternalArgs As KeyClickEventArgs
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Initializer"
|
#Region "Initializer"
|
||||||
Friend Sub New(ByVal _Job As TDJob)
|
Friend Sub New(ByVal _Job As TDJob)
|
||||||
Job = _Job
|
Job = _Job
|
||||||
|
InternalArgs = New KeyClickEventArgs
|
||||||
|
|
||||||
|
TT_MAIN = New ToolTip
|
||||||
TP_MAIN = New TableLayoutPanel With {.Margin = New Padding(0), .Dock = DockStyle.Fill}
|
TP_MAIN = New TableLayoutPanel With {.Margin = New Padding(0), .Dock = DockStyle.Fill}
|
||||||
TP_MAIN.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100))
|
TP_MAIN.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100))
|
||||||
TP_MAIN.ColumnCount = 1
|
TP_MAIN.ColumnCount = 1
|
||||||
@@ -86,6 +92,7 @@ Namespace DownloadObjects
|
|||||||
LBL_INFO.Padding = New Padding(3, 0, 3, 0)
|
LBL_INFO.Padding = New Padding(3, 0, 3, 0)
|
||||||
LBL_INFO.TextAlign = ContentAlignment.TopCenter
|
LBL_INFO.TextAlign = ContentAlignment.TopCenter
|
||||||
CreateButton(BTT_START, My.Resources.StartPic_Green_16)
|
CreateButton(BTT_START, My.Resources.StartPic_Green_16)
|
||||||
|
TT_MAIN.SetToolTip(BTT_START, "Ctrl+Click: download, exclude from feed.")
|
||||||
CreateButton(BTT_OPEN, PersonalUtilities.My.Resources.FolderOpenPic_Black_16)
|
CreateButton(BTT_OPEN, PersonalUtilities.My.Resources.FolderOpenPic_Black_16)
|
||||||
With TP_CONTROLS
|
With TP_CONTROLS
|
||||||
With .ColumnStyles
|
With .ColumnStyles
|
||||||
@@ -148,7 +155,8 @@ Namespace DownloadObjects
|
|||||||
End Function
|
End Function
|
||||||
#Region "Buttons"
|
#Region "Buttons"
|
||||||
Private Sub BTT_START_Click(sender As Object, e As EventArgs) Handles BTT_START.Click
|
Private Sub BTT_START_Click(sender As Object, e As EventArgs) Handles BTT_START.Click
|
||||||
Start()
|
InternalArgs.Reset()
|
||||||
|
Start(, Downloader.SessionSavedPosts, Not InternalArgs.Control)
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub BTT_STOP_Click(sender As Object, e As EventArgs) Handles BTT_STOP.Click
|
Private Sub BTT_STOP_Click(sender As Object, e As EventArgs) Handles BTT_STOP.Click
|
||||||
[Stop]()
|
[Stop]()
|
||||||
@@ -159,8 +167,13 @@ Namespace DownloadObjects
|
|||||||
#End Region
|
#End Region
|
||||||
#Region "Start, Stop"
|
#Region "Start, Stop"
|
||||||
Private _IsMultiple As Boolean = False
|
Private _IsMultiple As Boolean = False
|
||||||
Friend Sub Start(Optional ByVal Multiple As Boolean = False)
|
Private _Session As Integer = 0
|
||||||
|
Private _IncludeInTheFeed As Boolean = True
|
||||||
|
Friend Sub Start(Optional ByVal Multiple As Boolean = False, Optional ByVal Session As Integer = -1,
|
||||||
|
Optional ByVal IncludeInTheFeed As Boolean = True)
|
||||||
_IsMultiple = Multiple
|
_IsMultiple = Multiple
|
||||||
|
_Session = Session
|
||||||
|
_IncludeInTheFeed = IncludeInTheFeed
|
||||||
Job.StartThread(AddressOf DownloadData)
|
Job.StartThread(AddressOf DownloadData)
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub [Stop]()
|
Friend Sub [Stop]()
|
||||||
@@ -175,7 +188,10 @@ Namespace DownloadObjects
|
|||||||
btte.Invoke(BTT_STOP, True)
|
btte.Invoke(BTT_STOP, True)
|
||||||
Job.Progress.InformationTemporary = $"{Job.HostCollection.Name} downloading started"
|
Job.Progress.InformationTemporary = $"{Job.HostCollection.Name} downloading started"
|
||||||
Job.Start()
|
Job.Start()
|
||||||
|
Instance.Session = _Session
|
||||||
|
Instance.IncludeInTheFeed = _IncludeInTheFeed
|
||||||
Instance.Download(Job.Token, _IsMultiple)
|
Instance.Download(Job.Token, _IsMultiple)
|
||||||
|
If _IncludeInTheFeed And Instance.FeedDataExists Then RaiseEvent FeedFilesChanged(True)
|
||||||
RaiseEvent DownloadDone(SettingsCLS.NotificationObjects.SavedPosts, $"Downloading saved {Job.HostCollection.Name} posts is completed")
|
RaiseEvent DownloadDone(SettingsCLS.NotificationObjects.SavedPosts, $"Downloading saved {Job.HostCollection.Name} posts is completed")
|
||||||
Catch ex As Exception
|
Catch ex As Exception
|
||||||
Job.Progress.InformationTemporary = $"{Job.HostCollection.Name} downloading error"
|
Job.Progress.InformationTemporary = $"{Job.HostCollection.Name} downloading error"
|
||||||
@@ -220,6 +236,7 @@ Namespace DownloadObjects
|
|||||||
If Not Icon Is Nothing Then Icon.Dispose()
|
If Not Icon Is Nothing Then Icon.Dispose()
|
||||||
PR_MAIN.DisposeIfReady()
|
PR_MAIN.DisposeIfReady()
|
||||||
LBL_INFO.DisposeIfReady()
|
LBL_INFO.DisposeIfReady()
|
||||||
|
If Not TT_MAIN Is Nothing Then TT_MAIN.Dispose()
|
||||||
If Not TP_CONTROLS Is Nothing Then
|
If Not TP_CONTROLS Is Nothing Then
|
||||||
TP_CONTROLS.Controls.Clear()
|
TP_CONTROLS.Controls.Clear()
|
||||||
TP_CONTROLS.Dispose()
|
TP_CONTROLS.Dispose()
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ Partial Friend Class DownloadSavedPostsForm : Inherits System.Windows.Forms.Form
|
|||||||
Me.components = New System.ComponentModel.Container()
|
Me.components = New System.ComponentModel.Container()
|
||||||
Dim TP_BUTTONS As System.Windows.Forms.TableLayoutPanel
|
Dim TP_BUTTONS As System.Windows.Forms.TableLayoutPanel
|
||||||
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
Dim TT_MAIN As System.Windows.Forms.ToolTip
|
||||||
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(DownloadSavedPostsForm))
|
|
||||||
Me.BTT_DOWN_ALL = New System.Windows.Forms.Button()
|
Me.BTT_DOWN_ALL = New System.Windows.Forms.Button()
|
||||||
Me.BTT_STOP_ALL = New System.Windows.Forms.Button()
|
Me.BTT_STOP_ALL = New System.Windows.Forms.Button()
|
||||||
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
|
||||||
@@ -59,6 +58,7 @@ Partial Friend Class DownloadSavedPostsForm : Inherits System.Windows.Forms.Form
|
|||||||
Me.BTT_DOWN_ALL.Size = New System.Drawing.Size(234, 31)
|
Me.BTT_DOWN_ALL.Size = New System.Drawing.Size(234, 31)
|
||||||
Me.BTT_DOWN_ALL.TabIndex = 0
|
Me.BTT_DOWN_ALL.TabIndex = 0
|
||||||
Me.BTT_DOWN_ALL.Text = "Download ALL"
|
Me.BTT_DOWN_ALL.Text = "Download ALL"
|
||||||
|
TT_MAIN.SetToolTip(Me.BTT_DOWN_ALL, "Ctrl+Click: download, exclude from feed.")
|
||||||
Me.BTT_DOWN_ALL.UseVisualStyleBackColor = True
|
Me.BTT_DOWN_ALL.UseVisualStyleBackColor = True
|
||||||
'
|
'
|
||||||
'BTT_STOP_ALL
|
'BTT_STOP_ALL
|
||||||
@@ -92,7 +92,7 @@ Partial Friend Class DownloadSavedPostsForm : Inherits System.Windows.Forms.Form
|
|||||||
Me.ClientSize = New System.Drawing.Size(484, 41)
|
Me.ClientSize = New System.Drawing.Size(484, 41)
|
||||||
Me.Controls.Add(Me.TP_MAIN)
|
Me.Controls.Add(Me.TP_MAIN)
|
||||||
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
|
||||||
Me.Icon = Global.SCrawler.My.Resources.BookmarkIcon_32
|
Me.Icon = Global.SCrawler.My.Resources.Resources.BookmarkIcon_32
|
||||||
Me.MaximizeBox = False
|
Me.MaximizeBox = False
|
||||||
Me.MaximumSize = New System.Drawing.Size(500, 80)
|
Me.MaximumSize = New System.Drawing.Size(500, 80)
|
||||||
Me.MinimumSize = New System.Drawing.Size(500, 80)
|
Me.MinimumSize = New System.Drawing.Size(500, 80)
|
||||||
|
|||||||
@@ -117,15 +117,13 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
<metadata name="TP_BUTTONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<data name="TP_BUTTONS.GenerateMember" type="System.Boolean, mscorlib">
|
|
||||||
<value>False</value>
|
<value>False</value>
|
||||||
</data>
|
</metadata>
|
||||||
<data name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib">
|
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>False</value>
|
<value>False</value>
|
||||||
</data>
|
</metadata>
|
||||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<data name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing">
|
|
||||||
<value>17, 17</value>
|
<value>17, 17</value>
|
||||||
</data>
|
</metadata>
|
||||||
</root>
|
</root>
|
||||||
@@ -10,8 +10,10 @@ Imports System.ComponentModel
|
|||||||
Imports SCrawler.DownloadObjects
|
Imports SCrawler.DownloadObjects
|
||||||
Imports SCrawler.Plugin.Hosts
|
Imports SCrawler.Plugin.Hosts
|
||||||
Imports PersonalUtilities.Forms
|
Imports PersonalUtilities.Forms
|
||||||
|
Imports PersonalUtilities.Forms.Controls.KeyClick
|
||||||
Friend Class DownloadSavedPostsForm
|
Friend Class DownloadSavedPostsForm
|
||||||
Friend Event DownloadDone As NotificationEventHandler
|
Friend Event DownloadDone As NotificationEventHandler
|
||||||
|
Friend Event FeedFilesChanged As TDownloader.FeedFilesChangedEventHandler
|
||||||
Private MyView As FormView
|
Private MyView As FormView
|
||||||
Private ReadOnly JobsList As List(Of DownloadProgress)
|
Private ReadOnly JobsList As List(Of DownloadProgress)
|
||||||
Friend ReadOnly Property Working As Boolean
|
Friend ReadOnly Property Working As Boolean
|
||||||
@@ -40,6 +42,7 @@ Friend Class DownloadSavedPostsForm
|
|||||||
If JobsList.Count > 0 Then
|
If JobsList.Count > 0 Then
|
||||||
For Each j As DownloadProgress In JobsList
|
For Each j As DownloadProgress In JobsList
|
||||||
AddHandler j.DownloadDone, AddressOf Jobs_DownloadDone
|
AddHandler j.DownloadDone, AddressOf Jobs_DownloadDone
|
||||||
|
AddHandler j.FeedFilesChanged, AddressOf Jobs_FeedFilesChanged
|
||||||
TP_MAIN.RowStyles.Add(New RowStyle(SizeType.Absolute, 60))
|
TP_MAIN.RowStyles.Add(New RowStyle(SizeType.Absolute, 60))
|
||||||
TP_MAIN.RowCount += 1
|
TP_MAIN.RowCount += 1
|
||||||
TP_MAIN.Controls.Add(j.Get, 0, TP_MAIN.RowStyles.Count - 1)
|
TP_MAIN.Controls.Add(j.Get, 0, TP_MAIN.RowStyles.Count - 1)
|
||||||
@@ -60,7 +63,16 @@ Friend Class DownloadSavedPostsForm
|
|||||||
MyView.Dispose(Settings.Design)
|
MyView.Dispose(Settings.Design)
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub [Start]() Handles BTT_DOWN_ALL.Click
|
Private Sub [Start]() Handles BTT_DOWN_ALL.Click
|
||||||
If JobsList.Count > 0 Then JobsList.ForEach(Sub(j) j.Start(True))
|
If JobsList.Count > 0 Then
|
||||||
|
Dim ses% = Downloader.SessionSavedPosts
|
||||||
|
Dim args As New KeyClickEventArgs
|
||||||
|
args.Reset()
|
||||||
|
JobsList.ForEach(Sub(ByVal j As DownloadProgress)
|
||||||
|
ses += 1
|
||||||
|
j.Start(True, ses, Not args.Control)
|
||||||
|
End Sub)
|
||||||
|
Downloader.SessionSavedPosts = ses
|
||||||
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
Friend Sub [Stop]() Handles BTT_STOP_ALL.Click
|
Friend Sub [Stop]() Handles BTT_STOP_ALL.Click
|
||||||
If JobsList.Count > 0 Then JobsList.ForEach(Sub(j) j.Stop())
|
If JobsList.Count > 0 Then JobsList.ForEach(Sub(j) j.Stop())
|
||||||
@@ -68,4 +80,7 @@ Friend Class DownloadSavedPostsForm
|
|||||||
Private Sub Jobs_DownloadDone(ByVal Obj As SettingsCLS.NotificationObjects, ByVal Message As String)
|
Private Sub Jobs_DownloadDone(ByVal Obj As SettingsCLS.NotificationObjects, ByVal Message As String)
|
||||||
RaiseEvent DownloadDone(SettingsCLS.NotificationObjects.SavedPosts, Message)
|
RaiseEvent DownloadDone(SettingsCLS.NotificationObjects.SavedPosts, Message)
|
||||||
End Sub
|
End Sub
|
||||||
|
Private Sub Jobs_FeedFilesChanged(ByVal Added As Boolean)
|
||||||
|
RaiseEvent FeedFilesChanged(Added)
|
||||||
|
End Sub
|
||||||
End Class
|
End Class
|
||||||
@@ -300,6 +300,11 @@ Namespace DownloadObjects
|
|||||||
Throw New ArgumentNullException With {.HelpLink = 1}
|
Throw New ArgumentNullException With {.HelpLink = 1}
|
||||||
End If
|
End If
|
||||||
|
|
||||||
|
If Media.IsSavedPosts Then
|
||||||
|
BTT_CONTEXT_OPEN_USER_URL.Visible = False
|
||||||
|
BTT_CONTEXT_FIND_USER.Visible = False
|
||||||
|
End If
|
||||||
|
|
||||||
If Settings.Feeds.FavoriteExists AndAlso Settings.Feeds.Favorite.Contains(Media) Then BTT_FEED_ADD_FAV.ControlChangeColor(True, False)
|
If Settings.Feeds.FavoriteExists AndAlso Settings.Feeds.Favorite.Contains(Media) Then BTT_FEED_ADD_FAV.ControlChangeColor(True, False)
|
||||||
If Settings.FeedShowSpecialFeedsMediaItem Then
|
If Settings.FeedShowSpecialFeedsMediaItem Then
|
||||||
With Settings.Feeds
|
With Settings.Feeds
|
||||||
@@ -392,14 +397,31 @@ Namespace DownloadObjects
|
|||||||
End Sub
|
End Sub
|
||||||
Private Sub BTT_CONTEXT_OPEN_USER_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_USER.Click
|
Private Sub BTT_CONTEXT_OPEN_USER_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_USER.Click
|
||||||
If Not UserKey.IsEmptyString Then
|
If Not UserKey.IsEmptyString Then
|
||||||
Dim u As IUserData = Settings.GetUser(UserKey)
|
Dim u As IUserData = Nothing
|
||||||
If Not u Is Nothing Then u.OpenFolder()
|
If Not Media.IsSavedPosts Then
|
||||||
|
u = Settings.GetUser(UserKey)
|
||||||
|
Else
|
||||||
|
If Not Media.UserInfo.Plugin.IsEmptyString Then
|
||||||
|
Dim host As Plugin.Hosts.SettingsHost = Settings(Media.UserInfo.Plugin, Media.UserInfo.AccountName)
|
||||||
|
If Not host Is Nothing Then
|
||||||
|
u = host.GetInstance(Plugin.ISiteSettings.Download.SavedPosts, Media.UserInfo, False, False)
|
||||||
|
With DirectCast(u, UserDataBase)
|
||||||
|
.IsSavedPosts = True
|
||||||
|
.HostStatic = True
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
If Not u Is Nothing Then
|
||||||
|
u.OpenFolder()
|
||||||
|
If Media.IsSavedPosts Then u.Dispose()
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
#Region "Open URL"
|
#Region "Open URL"
|
||||||
Private Sub BTT_CONTEXT_OPEN_USER_URL_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_USER_URL.Click
|
Private Sub BTT_CONTEXT_OPEN_USER_URL_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_OPEN_USER_URL.Click
|
||||||
If Not UserKey.IsEmptyString Then
|
If Not UserKey.IsEmptyString And Not Media.IsSavedPosts Then
|
||||||
Dim u As IUserData = Settings.GetUser(UserKey)
|
Dim u As IUserData = Settings.GetUser(UserKey)
|
||||||
If Not u Is Nothing Then u.OpenSite()
|
If Not u Is Nothing Then u.OpenSite()
|
||||||
End If
|
End If
|
||||||
@@ -411,8 +433,26 @@ Namespace DownloadObjects
|
|||||||
url = Post.URL_BASE
|
url = Post.URL_BASE
|
||||||
Else
|
Else
|
||||||
If Not UserKey.IsEmptyString And Not Post.Post.ID.IsEmptyString Then
|
If Not UserKey.IsEmptyString And Not Post.Post.ID.IsEmptyString Then
|
||||||
Dim u As IUserData = Settings.GetUser(UserKey)
|
Dim u As IUserData
|
||||||
If Not u Is Nothing Then url = UserDataBase.GetPostUrl(u, Post)
|
If Media.IsSavedPosts Then
|
||||||
|
If Not Media.UserInfo.Plugin.IsEmptyString Then
|
||||||
|
Dim host As Plugin.Hosts.SettingsHostCollection = Settings(Media.UserInfo.Plugin)
|
||||||
|
If Not host Is Nothing Then
|
||||||
|
u = host.Default.GetInstance(Plugin.ISiteSettings.Download.SavedPosts, Media.UserInfo, False, False)
|
||||||
|
If Not u Is Nothing AndAlso Not u.HOST Is Nothing Then
|
||||||
|
With DirectCast(u, UserDataBase)
|
||||||
|
.IsSavedPosts = True
|
||||||
|
.HostStatic = True
|
||||||
|
End With
|
||||||
|
Try : url = u.HOST.Source.GetUserPostUrl(u, Post) : Catch : End Try
|
||||||
|
u.Dispose()
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
Else
|
||||||
|
u = Settings.GetUser(UserKey)
|
||||||
|
If Not u Is Nothing Then url = UserDataBase.GetPostUrl(u, Post)
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
If Not url.IsEmptyString Then
|
If Not url.IsEmptyString Then
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
'
|
'
|
||||||
' This program is distributed in the hope that it will be useful,
|
' This program is distributed in the hope that it will be useful,
|
||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
Imports LibVLCSharp
|
Imports LibVLCSharp.Shared
|
||||||
Imports System.Threading
|
Imports System.Threading
|
||||||
Imports System.ComponentModel
|
Imports System.ComponentModel
|
||||||
Imports PersonalUtilities.Tools
|
Imports PersonalUtilities.Tools
|
||||||
@@ -15,7 +15,7 @@ Imports VLCState = LibVLCSharp.Shared.VLCState
|
|||||||
Namespace DownloadObjects
|
Namespace DownloadObjects
|
||||||
<ToolboxItem(False), DesignTimeVisible(False)>
|
<ToolboxItem(False), DesignTimeVisible(False)>
|
||||||
Public Class FeedVideo
|
Public Class FeedVideo
|
||||||
Private WithEvents MediaPlayer As [Shared].MediaPlayer
|
Private WithEvents MediaPlayer As MediaPlayer
|
||||||
Private ReadOnly TimeChange As Action = Sub()
|
Private ReadOnly TimeChange As Action = Sub()
|
||||||
If _Disposed Then Exit Sub
|
If _Disposed Then Exit Sub
|
||||||
Dim v# = DivideWithZeroChecking(MediaPlayer.Time, MediaPlayer.Length) * 10
|
Dim v# = DivideWithZeroChecking(MediaPlayer.Time, MediaPlayer.Length) * 10
|
||||||
@@ -50,7 +50,7 @@ Namespace DownloadObjects
|
|||||||
'#If DEBUG Then
|
'#If DEBUG Then
|
||||||
' debugLogs = True
|
' debugLogs = True
|
||||||
'#End If
|
'#End If
|
||||||
MediaPlayer = New [Shared].MediaPlayer(New [Shared].Media(New [Shared].LibVLC(enableDebugLogs:=debugLogs), New Uri(File.ToString)))
|
MediaPlayer = New MediaPlayer(New Media(New LibVLC(enableDebugLogs:=debugLogs), New Uri(File.ToString)))
|
||||||
MyVideo.MediaPlayer = MediaPlayer
|
MyVideo.MediaPlayer = MediaPlayer
|
||||||
TR_VOLUME.Value = MediaPlayer.Volume / 10
|
TR_VOLUME.Value = MediaPlayer.Volume / 10
|
||||||
If Settings.UseM3U8 Then
|
If Settings.UseM3U8 Then
|
||||||
@@ -111,7 +111,7 @@ Namespace DownloadObjects
|
|||||||
End Sub, "Stop")
|
End Sub, "Stop")
|
||||||
UpdateButtons()
|
UpdateButtons()
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub MediaPlayer_TimeChanged(sender As Object, e As [Shared].MediaPlayerTimeChangedEventArgs) Handles MediaPlayer.TimeChanged
|
Private Sub MediaPlayer_TimeChanged(sender As Object, e As MediaPlayerTimeChangedEventArgs) Handles MediaPlayer.TimeChanged
|
||||||
If _Disposed Then Exit Sub
|
If _Disposed Then Exit Sub
|
||||||
If TR_POSITION.InvokeRequired Then TR_POSITION.Invoke(TimeChange) Else TimeChange.Invoke
|
If TR_POSITION.InvokeRequired Then TR_POSITION.Invoke(TimeChange) Else TimeChange.Invoke
|
||||||
If LBL_TIME.InvokeRequired Then LBL_TIME.Invoke(TimeChangeLabel) Else TimeChangeLabel.Invoke
|
If LBL_TIME.InvokeRequired Then LBL_TIME.Invoke(TimeChangeLabel) Else TimeChangeLabel.Invoke
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
For Each url In urls
|
For Each url In urls
|
||||||
If Not TryYouTube.Invoke Then
|
If Not TryYouTube.Invoke Then
|
||||||
media = FindSource(url, output)
|
media = FindSource(url, output)
|
||||||
If Not media Is Nothing Then media.AccountName = acc : ControlCreateAndAdd(media, disableDown)
|
If Not media Is Nothing AndAlso ValidateContainerURL(media) Then media.AccountName = acc : ControlCreateAndAdd(media, disableDown)
|
||||||
End If
|
End If
|
||||||
Next
|
Next
|
||||||
urls.Clear()
|
urls.Clear()
|
||||||
@@ -175,7 +175,7 @@ Namespace DownloadObjects.STDownloader
|
|||||||
End If
|
End If
|
||||||
If media Is Nothing Then
|
If media Is Nothing Then
|
||||||
MsgBoxE({$"The URL you entered is not recognized by existing plugins.{vbCr}{url}", "Download video"}, vbCritical)
|
MsgBoxE({$"The URL you entered is not recognized by existing plugins.{vbCr}{url}", "Download video"}, vbCritical)
|
||||||
Else
|
ElseIf ValidateContainerURL(media) Then
|
||||||
media.AccountName = acc
|
media.AccountName = acc
|
||||||
output.Exists(SFO.Path, True)
|
output.Exists(SFO.Path, True)
|
||||||
ControlCreateAndAdd(media, disableDown)
|
ControlCreateAndAdd(media, disableDown)
|
||||||
|
|||||||
@@ -34,12 +34,14 @@ Namespace DownloadObjects
|
|||||||
Private Const Name_Date As String = "Date"
|
Private Const Name_Date As String = "Date"
|
||||||
Private Const Name_Session As String = "Session"
|
Private Const Name_Session As String = "Session"
|
||||||
Private Const Name_File As String = "File"
|
Private Const Name_File As String = "File"
|
||||||
|
Private Const Name_IsSavedPosts As String = "IsSavedPosts"
|
||||||
#End Region
|
#End Region
|
||||||
Friend ReadOnly User As IUserData
|
Friend ReadOnly User As IUserData
|
||||||
Friend ReadOnly Data As UserMedia
|
Friend ReadOnly Data As UserMedia
|
||||||
Friend ReadOnly UserInfo As UserInfo
|
Friend ReadOnly UserInfo As UserInfo
|
||||||
Friend ReadOnly [Date] As Date
|
Friend ReadOnly [Date] As Date
|
||||||
Friend ReadOnly Session As Integer
|
Friend ReadOnly Session As Integer
|
||||||
|
Friend IsSavedPosts As Boolean
|
||||||
Friend Sub New(ByVal Data As UserMedia, ByVal User As IUserData, ByVal Session As Integer)
|
Friend Sub New(ByVal Data As UserMedia, ByVal User As IUserData, ByVal Session As Integer)
|
||||||
Me.Data = Data
|
Me.Data = Data
|
||||||
Me.User = User
|
Me.User = User
|
||||||
@@ -54,10 +56,22 @@ Namespace DownloadObjects
|
|||||||
Private Sub New(ByVal e As EContainer)
|
Private Sub New(ByVal e As EContainer)
|
||||||
If Not e Is Nothing Then
|
If Not e Is Nothing Then
|
||||||
If e.Contains(Name_User) Then
|
If e.Contains(Name_User) Then
|
||||||
|
IsSavedPosts = e.Value(Name_IsSavedPosts).FromXML(Of Boolean)(False)
|
||||||
Dim u As UserInfo = e(Name_User)
|
Dim u As UserInfo = e(Name_User)
|
||||||
If Not u.Name.IsEmptyString And Not u.Site.IsEmptyString Then
|
If Not u.Name.IsEmptyString And Not u.Site.IsEmptyString Then
|
||||||
User = Settings.GetUser(u)
|
If Not IsSavedPosts Then
|
||||||
If Not User Is Nothing Then UserInfo = DirectCast(User, UserDataBase).User
|
User = Settings.GetUser(u)
|
||||||
|
If Not User Is Nothing Then UserInfo = DirectCast(User, UserDataBase).User Else UserInfo = u
|
||||||
|
ElseIf Not u.Plugin.IsEmptyString Then
|
||||||
|
UserInfo = u
|
||||||
|
User = Settings(u.Plugin).Default.GetInstance(Download.SavedPosts, u, False, False)
|
||||||
|
If Not User Is Nothing Then
|
||||||
|
With DirectCast(User, UserDataBase)
|
||||||
|
.HostStatic = True
|
||||||
|
.IsSavedPosts = True
|
||||||
|
End With
|
||||||
|
End If
|
||||||
|
End If
|
||||||
End If
|
End If
|
||||||
End If
|
End If
|
||||||
Data = New UserMedia(e(Name_Media), User)
|
Data = New UserMedia(e(Name_Media), User)
|
||||||
@@ -90,8 +104,9 @@ Namespace DownloadObjects
|
|||||||
Data.ToEContainer,
|
Data.ToEContainer,
|
||||||
New EContainer(Name_Date, AConvert(Of String)([Date], DateTimeDefaultProvider, String.Empty)),
|
New EContainer(Name_Date, AConvert(Of String)([Date], DateTimeDefaultProvider, String.Empty)),
|
||||||
New EContainer(Name_Session, Session),
|
New EContainer(Name_Session, Session),
|
||||||
New EContainer(Name_File, Data.File)},
|
New EContainer(Name_File, Data.File),
|
||||||
If(Not User Is Nothing, DirectCast(User, UserDataBase).User.ToEContainer, Nothing), LAP.IgnoreICopier)
|
New EContainer(Name_IsSavedPosts, IsSavedPosts.BoolToInteger)},
|
||||||
|
If(IsSavedPosts, UserInfo.ToEContainer, If(Not User Is Nothing, DirectCast(User, UserDataBase).User.ToEContainer, Nothing)), LAP.IgnoreICopier)
|
||||||
End Function
|
End Function
|
||||||
End Structure
|
End Structure
|
||||||
Friend ReadOnly Property Files As List(Of UserMediaD)
|
Friend ReadOnly Property Files As List(Of UserMediaD)
|
||||||
@@ -415,6 +430,28 @@ Namespace DownloadObjects
|
|||||||
#Region "Thread"
|
#Region "Thread"
|
||||||
Private CheckerThread As Thread
|
Private CheckerThread As Thread
|
||||||
Private MissingPostsDetected As Boolean = False
|
Private MissingPostsDetected As Boolean = False
|
||||||
|
Private _SessionSavedPosts As Integer = -1
|
||||||
|
Friend Property SessionSavedPosts As Integer
|
||||||
|
Get
|
||||||
|
If Not Working Then
|
||||||
|
Session += 1
|
||||||
|
Return Session
|
||||||
|
ElseIf _SessionSavedPosts >= 0 Then
|
||||||
|
_SessionSavedPosts += 1
|
||||||
|
Return _SessionSavedPosts
|
||||||
|
Else
|
||||||
|
_SessionSavedPosts = Session + 1
|
||||||
|
Return _SessionSavedPosts
|
||||||
|
End If
|
||||||
|
End Get
|
||||||
|
Set(ByVal NewSessionValue As Integer)
|
||||||
|
If Not Working Then
|
||||||
|
Session = NewSessionValue
|
||||||
|
Else
|
||||||
|
_SessionSavedPosts = NewSessionValue
|
||||||
|
End If
|
||||||
|
End Set
|
||||||
|
End Property
|
||||||
Private Session As Integer = 0
|
Private Session As Integer = 0
|
||||||
Private Sub [Start]()
|
Private Sub [Start]()
|
||||||
If Not AutoDownloaderWorking AndAlso MyProgressForm.ReadyToOpen AndAlso Pool.LongCount(Function(p) p.Count > 0) > 1 Then MyProgressForm.Show() : MainFrameObj.Focus()
|
If Not AutoDownloaderWorking AndAlso MyProgressForm.ReadyToOpen AndAlso Pool.LongCount(Function(p) p.Count > 0) > 1 Then MyProgressForm.Show() : MainFrameObj.Focus()
|
||||||
@@ -462,6 +499,7 @@ Namespace DownloadObjects
|
|||||||
RaiseEvent Downloading(False)
|
RaiseEvent Downloading(False)
|
||||||
FilesUpdatePendingUsers()
|
FilesUpdatePendingUsers()
|
||||||
If FilesChanged Then FilesSave() : RaiseEvent FeedFilesChanged(True)
|
If FilesChanged Then FilesSave() : RaiseEvent FeedFilesChanged(True)
|
||||||
|
If _SessionSavedPosts <> -1 Then Session = _SessionSavedPosts : _SessionSavedPosts = -1
|
||||||
End Try
|
End Try
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub StartDownloading(ByRef _Job As Job)
|
Private Sub StartDownloading(ByRef _Job As Job)
|
||||||
|
|||||||
@@ -239,7 +239,20 @@ CloseResume:
|
|||||||
Case Keys.F6 : BTT_DOWN_ALL_FULL_KeyClick(Nothing, New MyKeyEventArgs(e))
|
Case Keys.F6 : BTT_DOWN_ALL_FULL_KeyClick(Nothing, New MyKeyEventArgs(e))
|
||||||
Case Else : b = NumGroup(e)
|
Case Else : b = NumGroup(e)
|
||||||
End Select
|
End Select
|
||||||
If Not b And e.Control And e.KeyCode = Keys.F Then MySearch.FormShow() : b = True
|
|
||||||
|
If Not b Then
|
||||||
|
b = True
|
||||||
|
If e.Control And e.KeyCode = Keys.F Then
|
||||||
|
MySearch.FormShow()
|
||||||
|
ElseIf e.Alt And e.KeyCode = Keys.A Then
|
||||||
|
BTT_DOWN_AUTOMATION.PerformClick()
|
||||||
|
ElseIf e.Alt And e.KeyCode = Keys.P Then
|
||||||
|
BTT_PR_INFO.PerformClick()
|
||||||
|
Else
|
||||||
|
b = False
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
If b Then e.Handled = True
|
If b Then e.Handled = True
|
||||||
End Sub
|
End Sub
|
||||||
Private Function NumGroup(ByVal e As KeyEventArgs) As Boolean
|
Private Function NumGroup(ByVal e As KeyEventArgs) As Boolean
|
||||||
@@ -472,7 +485,11 @@ CloseResume:
|
|||||||
End Sub
|
End Sub
|
||||||
#End Region
|
#End Region
|
||||||
Private Sub ShowFeed() Handles BTT_FEED.Click, BTT_TRAY_FEED_SHOW.Click
|
Private Sub ShowFeed() Handles BTT_FEED.Click, BTT_TRAY_FEED_SHOW.Click
|
||||||
If MyFeed Is Nothing Then MyFeed = New DownloadFeedForm : AddHandler Downloader.FeedFilesChanged, AddressOf MyFeed.Downloader_FilesChanged
|
If MyFeed Is Nothing Then
|
||||||
|
MyFeed = New DownloadFeedForm
|
||||||
|
AddHandler Downloader.FeedFilesChanged, AddressOf MyFeed.Downloader_FilesChanged
|
||||||
|
If Not MySavedPosts Is Nothing Then AddHandler MySavedPosts.FeedFilesChanged, AddressOf MyFeed.Downloader_FilesChanged
|
||||||
|
End If
|
||||||
If MyFeed.Visible Then MyFeed.BringToFront() Else MyFeed.Show()
|
If MyFeed.Visible Then MyFeed.BringToFront() Else MyFeed.Show()
|
||||||
End Sub
|
End Sub
|
||||||
Private Sub BTT_CHANNELS_Click(sender As Object, e As EventArgs) Handles BTT_CHANNELS.Click, BTT_TRAY_CHANNELS.Click
|
Private Sub BTT_CHANNELS_Click(sender As Object, e As EventArgs) Handles BTT_CHANNELS.Click, BTT_TRAY_CHANNELS.Click
|
||||||
@@ -487,6 +504,7 @@ CloseResume:
|
|||||||
If MySavedPosts Is Nothing Then
|
If MySavedPosts Is Nothing Then
|
||||||
MySavedPosts = New DownloadSavedPostsForm
|
MySavedPosts = New DownloadSavedPostsForm
|
||||||
AddHandler MySavedPosts.DownloadDone, AddressOf MainFrameObj.ShowNotification
|
AddHandler MySavedPosts.DownloadDone, AddressOf MainFrameObj.ShowNotification
|
||||||
|
If Not MyFeed Is Nothing Then AddHandler MySavedPosts.FeedFilesChanged, AddressOf MyFeed.Downloader_FilesChanged
|
||||||
End If
|
End If
|
||||||
With MySavedPosts
|
With MySavedPosts
|
||||||
If .Visible Then .BringToFront() Else .Show()
|
If .Visible Then .BringToFront() Else .Show()
|
||||||
@@ -910,7 +928,7 @@ CloseResume:
|
|||||||
#Region "2 - user parameters"
|
#Region "2 - user parameters"
|
||||||
Private Sub BTT_CONTEXT_FAV_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_FAV.Click
|
Private Sub BTT_CONTEXT_FAV_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_FAV.Click
|
||||||
Dim users As List(Of IUserData) = GetSelectedUserArray()
|
Dim users As List(Of IUserData) = GetSelectedUserArray()
|
||||||
If AskForMassReplace(users, "Favorite") Then users.ForEach(Sub(u)
|
If AskForMassReplace(users, "Favorite") Then users.ForEach(Sub(ByVal u As IUserData)
|
||||||
u.Favorite = Not u.Favorite
|
u.Favorite = Not u.Favorite
|
||||||
u.UpdateUserInformation()
|
u.UpdateUserInformation()
|
||||||
UserListUpdate(u, False)
|
UserListUpdate(u, False)
|
||||||
@@ -918,7 +936,7 @@ CloseResume:
|
|||||||
End Sub
|
End Sub
|
||||||
Private Sub BTT_CONTEXT_TEMP_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_TEMP.Click
|
Private Sub BTT_CONTEXT_TEMP_Click(sender As Object, e As EventArgs) Handles BTT_CONTEXT_TEMP.Click
|
||||||
Dim users As List(Of IUserData) = GetSelectedUserArray()
|
Dim users As List(Of IUserData) = GetSelectedUserArray()
|
||||||
If AskForMassReplace(users, "Temporary") Then users.ForEach(Sub(u)
|
If AskForMassReplace(users, "Temporary") Then users.ForEach(Sub(ByVal u As IUserData)
|
||||||
u.Temporary = Not u.Temporary
|
u.Temporary = Not u.Temporary
|
||||||
u.UpdateUserInformation()
|
u.UpdateUserInformation()
|
||||||
UserListUpdate(u, False)
|
UserListUpdate(u, False)
|
||||||
@@ -928,7 +946,7 @@ CloseResume:
|
|||||||
Dim users As List(Of IUserData) = GetSelectedUserArray()
|
Dim users As List(Of IUserData) = GetSelectedUserArray()
|
||||||
If AskForMassReplace(users, "Ready for download") Then
|
If AskForMassReplace(users, "Ready for download") Then
|
||||||
Dim r As Boolean = MsgBoxE({"What state do you want to set for selected users", "Select ready state"}, vbQuestion,,, {"Not Ready", "Ready"}).Index
|
Dim r As Boolean = MsgBoxE({"What state do you want to set for selected users", "Select ready state"}, vbQuestion,,, {"Not Ready", "Ready"}).Index
|
||||||
users.ForEach(Sub(u)
|
users.ForEach(Sub(ByVal u As IUserData)
|
||||||
u.ReadyForDownload = r
|
u.ReadyForDownload = r
|
||||||
u.UpdateUserInformation()
|
u.UpdateUserInformation()
|
||||||
End Sub)
|
End Sub)
|
||||||
@@ -1549,7 +1567,7 @@ CloseResume:
|
|||||||
Friend Function GetUserListProvider(ByVal WithCollections As Boolean) As IFormatProvider
|
Friend Function GetUserListProvider(ByVal WithCollections As Boolean) As IFormatProvider
|
||||||
If WithCollections Then
|
If WithCollections Then
|
||||||
If OperationsUserListProviderCollections Is Nothing Then _
|
If OperationsUserListProviderCollections Is Nothing Then _
|
||||||
OperationsUserListProviderCollections = New CustomProvider(Function(v, d, p, n, ee)
|
OperationsUserListProviderCollections = New CustomProvider(Function(ByVal v As Object) As Object
|
||||||
Dim OutStr$
|
Dim OutStr$
|
||||||
With DirectCast(v, IUserData)
|
With DirectCast(v, IUserData)
|
||||||
If .IsCollection Then
|
If .IsCollection Then
|
||||||
@@ -1563,7 +1581,7 @@ CloseResume:
|
|||||||
Return OperationsUserListProviderCollections
|
Return OperationsUserListProviderCollections
|
||||||
Else
|
Else
|
||||||
If OperationsUserListProvider Is Nothing Then _
|
If OperationsUserListProvider Is Nothing Then _
|
||||||
OperationsUserListProvider = New CustomProvider(Function(v, d, p, n, ee) $"[{DirectCast(v, IUserData).Site}] {DirectCast(v, IUserData).Name}")
|
OperationsUserListProvider = New CustomProvider(Function(v) $"[{DirectCast(v, IUserData).Site}] {DirectCast(v, IUserData).Name}")
|
||||||
Return OperationsUserListProvider
|
Return OperationsUserListProvider
|
||||||
End If
|
End If
|
||||||
End Function
|
End Function
|
||||||
|
|||||||
@@ -151,7 +151,9 @@ Friend Module MainMod
|
|||||||
Friend Sub CheckVersion(ByVal Force As Boolean)
|
Friend Sub CheckVersion(ByVal Force As Boolean)
|
||||||
With Settings
|
With Settings
|
||||||
If .CheckUpdatesAtStart Or Force Then
|
If .CheckUpdatesAtStart Or Force Then
|
||||||
ShowProgramInfo(.ProgramText.Value.IfNullOrEmpty("SCrawler"), My.Application.Info.Version, True, Force, .Self, False,
|
ShowProgramInfo(.ProgramText.Value.IfNullOrEmpty("SCrawler"),
|
||||||
|
SCrawler.Shared.GetCurrentMaxVer(Application.StartupPath.CSFileP).IfNullOrEmpty(My.Application.Info.Version),
|
||||||
|
True, Force, .Self, False,
|
||||||
.LatestVersion.Value, .ShowNewVersionNotification.Value, .ProgramDescription)
|
.LatestVersion.Value, .ShowNewVersionNotification.Value, .ProgramDescription)
|
||||||
End If
|
End If
|
||||||
End With
|
End With
|
||||||
|
|||||||
@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
|
|||||||
' by using the '*' as shown below:
|
' by using the '*' as shown below:
|
||||||
' <Assembly: AssemblyVersion("1.0.*")>
|
' <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
<Assembly: AssemblyVersion("2023.11.24.0")>
|
<Assembly: AssemblyVersion("2023.12.7.0")>
|
||||||
<Assembly: AssemblyFileVersion("2023.11.24.0")>
|
<Assembly: AssemblyFileVersion("2023.12.7.0")>
|
||||||
<Assembly: NeutralResourcesLanguage("en")>
|
<Assembly: NeutralResourcesLanguage("en")>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
' but WITHOUT ANY WARRANTY
|
' but WITHOUT ANY WARRANTY
|
||||||
Imports PersonalUtilities.Forms.Toolbars
|
Imports PersonalUtilities.Forms.Toolbars
|
||||||
Friend Class PreProgress : Implements IDisposable
|
Friend Class PreProgress : Implements IDisposable
|
||||||
Private ReadOnly Progress As MyProgressExt = Nothing
|
Friend ReadOnly Progress As MyProgressExt = Nothing
|
||||||
Private ReadOnly ProgressExists As Boolean = False
|
Private ReadOnly ProgressExists As Boolean = False
|
||||||
Private ReadOnly Property Ready As Boolean
|
Private ReadOnly Property Ready As Boolean
|
||||||
Get
|
Get
|
||||||
|
|||||||
@@ -120,7 +120,10 @@ Namespace Plugin.Hosts
|
|||||||
Instance.DownloadSingleObject(If(ExternalSource, Me), Token)
|
Instance.DownloadSingleObject(If(ExternalSource, Me), Token)
|
||||||
ExchangeData(ExternalSource, Me)
|
ExchangeData(ExternalSource, Me)
|
||||||
Dim __url$ = DirectCast(Me, IDownloadableMedia).URL_BASE.IfNullOrEmpty(URL)
|
Dim __url$ = DirectCast(Me, IDownloadableMedia).URL_BASE.IfNullOrEmpty(URL)
|
||||||
If File.Exists And Not __url.IsEmptyString And MyDownloaderSettings.CreateUrlFiles Then CreateUrlFile(__url, File)
|
If File.Exists And Not __url.IsEmptyString And MyDownloaderSettings.CreateUrlFiles Then
|
||||||
|
Dim urlFile As SFile = CreateUrlFile(__url, File)
|
||||||
|
If urlFile.Exists Then Files.Add(urlFile)
|
||||||
|
End If
|
||||||
If Not ExternalSource Is Nothing Then
|
If Not ExternalSource Is Nothing Then
|
||||||
With ExternalSource : _HasError = .HasError : _Exists = .Exists : End With
|
With ExternalSource : _HasError = .HasError : _Exists = .Exists : End With
|
||||||
End If
|
End If
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ Namespace Plugin.Hosts
|
|||||||
|
|
||||||
Source.BeginInit()
|
Source.BeginInit()
|
||||||
|
|
||||||
Dim Members As IEnumerable(Of MemberInfo) = GetObjectMembers(Plugin,,, True, New MembersDistinctComparer) 'Plugin.GetType.GetTypeInfo.DeclaredMembers
|
Dim Members As IEnumerable(Of MemberInfo) = GetObjectMembers(Plugin,,, True, New MembersDistinctComparerExtended) 'Plugin.GetType.GetTypeInfo.DeclaredMembers
|
||||||
|
|
||||||
_ResponserIsContainer = TypeOf Plugin Is IResponserContainer
|
_ResponserIsContainer = TypeOf Plugin Is IResponserContainer
|
||||||
If Members.ListExists Then
|
If Members.ListExists Then
|
||||||
|
|||||||
@@ -636,6 +636,10 @@
|
|||||||
<Project>{d4650f6b-5a54-44b6-999b-6c675b7116b1}</Project>
|
<Project>{d4650f6b-5a54-44b6-999b-6c675b7116b1}</Project>
|
||||||
<Name>SCrawler.PluginProvider</Name>
|
<Name>SCrawler.PluginProvider</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\SCrawler.Shared\SCrawler.Shared.vbproj">
|
||||||
|
<Project>{dc634700-24c7-42dd-bf8f-87e6cc54e625}</Project>
|
||||||
|
<Name>SCrawler.Shared</Name>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\SCrawler.YouTube\SCrawler.YouTube.vbproj">
|
<ProjectReference Include="..\SCrawler.YouTube\SCrawler.YouTube.vbproj">
|
||||||
<Project>{7c764707-7fd1-469c-a365-94605c193607}</Project>
|
<Project>{7c764707-7fd1-469c-a365-94605c193607}</Project>
|
||||||
<Name>SCrawler.YouTube</Name>
|
<Name>SCrawler.YouTube</Name>
|
||||||
|
|||||||
@@ -136,6 +136,8 @@ Friend Class SettingsCLS : Implements IDownloaderSettings, IDisposable
|
|||||||
Private ReadOnly BlackListFile As SFile = $"{SettingsFolderName}\BlackList.txt"
|
Private ReadOnly BlackListFile As SFile = $"{SettingsFolderName}\BlackList.txt"
|
||||||
Private ReadOnly UsersSettingsFile As SFile = $"{SettingsFolderName}\Users.xml"
|
Private ReadOnly UsersSettingsFile As SFile = $"{SettingsFolderName}\Users.xml"
|
||||||
Friend Sub New()
|
Friend Sub New()
|
||||||
|
CheckNewReleaseFolder()
|
||||||
|
|
||||||
Cache = CacheKeeper.Default
|
Cache = CacheKeeper.Default
|
||||||
Cache.DisposeSuspended = True
|
Cache.DisposeSuspended = True
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user