diff --git a/Brotli.Core/Brotli.Core.csproj b/Brotli.Core/Brotli.Core.csproj
index e88d1ed..aafe0ea 100644
--- a/Brotli.Core/Brotli.Core.csproj
+++ b/Brotli.Core/Brotli.Core.csproj
@@ -17,6 +17,7 @@ The library use the native runtime and its performance should be better than Sys
For more document,please visit https://github.com/XieJJ99/brotli.net.
MIT
2.1.1.0
+ AnyCPU;x64;x86
diff --git a/DatabaseManager/DatabaseManager.csproj b/DatabaseManager/DatabaseManager.csproj
index da46220..343a04e 100644
--- a/DatabaseManager/DatabaseManager.csproj
+++ b/DatabaseManager/DatabaseManager.csproj
@@ -35,6 +35,22 @@
prompt
4
+
+ x64
+ bin\x64\Debug\
+
+
+ x64
+ bin\x64\Release\
+
+
+ x86
+ bin\x86\Debug\
+
+
+ x86
+ bin\x86\Release\
+
diff --git a/DownKyi.Core.Test/DownKyi.Core.Test.csproj b/DownKyi.Core.Test/DownKyi.Core.Test.csproj
index 85a7801..9a7c6c4 100644
--- a/DownKyi.Core.Test/DownKyi.Core.Test.csproj
+++ b/DownKyi.Core.Test/DownKyi.Core.Test.csproj
@@ -38,6 +38,22 @@
prompt
4
+
+ x64
+ bin\x64\Debug\
+
+
+ x64
+ bin\x64\Release\
+
+
+ x86
+ bin\x86\Debug\
+
+
+ x86
+ bin\x86\Release\
+
..\packages\MSTest.TestFramework.2.2.8\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll
diff --git a/DownKyi.Core/Aria2cNet/Client/Entity/AriaSendData.cs b/DownKyi.Core/Aria2cNet/Client/Entity/AriaSendData.cs
index ffbe89a..e11bb49 100644
--- a/DownKyi.Core/Aria2cNet/Client/Entity/AriaSendData.cs
+++ b/DownKyi.Core/Aria2cNet/Client/Entity/AriaSendData.cs
@@ -36,14 +36,14 @@ namespace DownKyi.Core.Aria2cNet.Client.Entity
[JsonProperty("dir")]
public string Dir { get; set; }
- //[JsonProperty("header")]
- //public string Header { get; set; }
+ [JsonProperty("header")]
+ public string Header { get; set; }
- //[JsonProperty("use-head")]
- //public string UseHead { get; set; }
+ [JsonProperty("use-head")]
+ public string UseHead { get; set; }
- //[JsonProperty("user-agent")]
- //public string UserAgent { get; set; }
+ [JsonProperty("user-agent")]
+ public string UserAgent { get; set; }
public override string ToString()
{
diff --git a/DownKyi.Core/Aria2cNet/Server/AriaConfigFileAllocation.cs b/DownKyi.Core/Aria2cNet/Server/AriaConfigFileAllocation.cs
index e00a9aa..38bf62f 100644
--- a/DownKyi.Core/Aria2cNet/Server/AriaConfigFileAllocation.cs
+++ b/DownKyi.Core/Aria2cNet/Server/AriaConfigFileAllocation.cs
@@ -5,6 +5,7 @@
///
public enum AriaConfigFileAllocation
{
+ NOT_SET = 0,
NONE = 1, // 没有预分配
PREALLOC, // 预分配,默认
FALLOC // NTFS建议使用
diff --git a/DownKyi.Core/Aria2cNet/Server/AriaConfigLogLevel.cs b/DownKyi.Core/Aria2cNet/Server/AriaConfigLogLevel.cs
index b1f4620..ac27188 100644
--- a/DownKyi.Core/Aria2cNet/Server/AriaConfigLogLevel.cs
+++ b/DownKyi.Core/Aria2cNet/Server/AriaConfigLogLevel.cs
@@ -5,6 +5,7 @@
///
public enum AriaConfigLogLevel
{
+ NOT_SET = 0,
DEBUG = 1,
INFO,
NOTICE,
diff --git a/DownKyi.Core/BiliApi/Users/Models/SpacePublicationListType.cs b/DownKyi.Core/BiliApi/Users/Models/SpacePublicationListType.cs
index 6e88c75..5a4d528 100644
--- a/DownKyi.Core/BiliApi/Users/Models/SpacePublicationListType.cs
+++ b/DownKyi.Core/BiliApi/Users/Models/SpacePublicationListType.cs
@@ -21,7 +21,7 @@ namespace DownKyi.Core.BiliApi.Users.Models
public SpacePublicationListTypeVideoZone Technology { get; set; }
[JsonProperty("188")]
public SpacePublicationListTypeVideoZone Digital { get; set; }
- [JsonProperty("224")]
+ [JsonProperty("234")]
public SpacePublicationListTypeVideoZone Sports { get; set; }
[JsonProperty("223")]
public SpacePublicationListTypeVideoZone Car { get; set; }
diff --git a/DownKyi.Core/DownKyi.Core.csproj b/DownKyi.Core/DownKyi.Core.csproj
index fb65dfc..5c3361b 100644
--- a/DownKyi.Core/DownKyi.Core.csproj
+++ b/DownKyi.Core/DownKyi.Core.csproj
@@ -32,6 +32,22 @@
prompt
4
+
+ x64
+ bin\x64\Debug\
+
+
+ x64
+ bin\x64\Release\
+
+
+ x86
+ bin\x86\Debug\
+
+
+ x86
+ bin\x86\Release\
+
..\packages\Brotli.NET.2.1.1\lib\net45\Brotli.Core.dll
@@ -78,6 +94,9 @@
+
+ ..\packages\WebPSharp.0.5.1\lib\net472\WebPSharp.dll
+
@@ -271,6 +290,8 @@
+
+
@@ -333,6 +354,20 @@
Designer
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
@@ -342,7 +377,9 @@
+
+
\ No newline at end of file
diff --git a/DownKyi.Core/FFmpeg/FFmpegHelper.cs b/DownKyi.Core/FFmpeg/FFmpegHelper.cs
index 31ae4d3..1eb34fb 100644
--- a/DownKyi.Core/FFmpeg/FFmpegHelper.cs
+++ b/DownKyi.Core/FFmpeg/FFmpegHelper.cs
@@ -9,6 +9,23 @@ namespace DownKyi.Core.FFmpeg
{
private const string Tag = "FFmpegHelper";
+ private static readonly bool is64Bit = false;
+ private static readonly string exec = "";
+
+ static FFmpegHelper()
+ {
+ is64Bit = IntPtr.Size == 8;
+
+ if (is64Bit)
+ {
+ exec = Path.Combine(Environment.CurrentDirectory, "ffmpeg.exe");
+ }
+ else
+ {
+ exec = Path.Combine(Environment.CurrentDirectory, "ffmpeg.exe");
+ }
+ }
+
///
/// 合并音频和视频
///
@@ -24,7 +41,7 @@ namespace DownKyi.Core.FFmpeg
}
if (video2 == null || !File.Exists(video2))
{
- param = $"-y -i \"{video1}\" -acodec copy -f aac \"{destVideo}\"";
+ param = $"-y -i \"{video1}\" -acodec copy \"{destVideo}\"";
}
if (!File.Exists(video1) && !File.Exists(video2)) { return false; }
@@ -37,7 +54,7 @@ namespace DownKyi.Core.FFmpeg
return false;
}
- ExcuteProcess("ffmpeg.exe", param, null, (s, e) => Console.WriteLine(e.Data));
+ ExcuteProcess(exec, param, null, (s, e) => Console.WriteLine(e.Data));
try
{
@@ -92,7 +109,7 @@ namespace DownKyi.Core.FFmpeg
// ffmpeg -y -f concat -safe 0 -i filelist.txt -c copy output.mkv
// 加上-y,表示如果有同名文件,则默认覆盖
string param = $"-y -f concat -safe 0 -i {concatFileName} -c copy \"{destVideo}\" -y";
- ExcuteProcess("ffmpeg.exe", param, workingDirectory, (s, e) => Console.WriteLine(e.Data));
+ ExcuteProcess(exec, param, workingDirectory, (s, e) => Console.WriteLine(e.Data));
// 删除临时文件
try
@@ -128,7 +145,7 @@ namespace DownKyi.Core.FFmpeg
{
// ffmpeg -y -i "video.mp4" -vf delogo=x=1670:y=50:w=180:h=70:show=1 "delogo.mp4"
string param = $"-y -i \"{video}\" -vf delogo=x={x}:y={y}:w={width}:h={height}:show=0 \"{destVideo}\" -hide_banner";
- ExcuteProcess("ffmpeg.exe", param, null, (s, e) =>
+ ExcuteProcess(exec, param, null, (s, e) =>
{
Console.WriteLine(e.Data);
action.Invoke(e.Data);
@@ -147,7 +164,7 @@ namespace DownKyi.Core.FFmpeg
// ffmpeg -i 3.mp4 -vn -y -acodec copy 3.aac
// ffmpeg -i 3.mp4 -vn -y -acodec copy 3.m4a
string param = $"-i \"{video}\" -vn -y -acodec copy \"{audio}\" -hide_banner";
- ExcuteProcess("ffmpeg.exe", param,
+ ExcuteProcess(exec, param,
null, (s, e) =>
{
Console.WriteLine(e.Data);
@@ -166,7 +183,7 @@ namespace DownKyi.Core.FFmpeg
// 提取视频 (Extract Video)
// ffmpeg -i Life.of.Pi.has.subtitles.mkv -vcodec copy –an videoNoAudioSubtitle.mp4
string param = $"-i \"{video}\" -y -vcodec copy -an \"{destVideo}\" -hide_banner";
- ExcuteProcess("ffmpeg.exe", param,
+ ExcuteProcess(exec, param,
null, (s, e) =>
{
Console.WriteLine(e.Data);
@@ -185,7 +202,7 @@ namespace DownKyi.Core.FFmpeg
// 提取帧
// ffmpeg -i caiyilin.wmv -vframes 1 wm.bmp
string param = $"-i \"{video}\" -y -vframes {number} \"{image}\"";
- ExcuteProcess("ffmpeg.exe", param, null, (s, e) => Console.WriteLine(e.Data));
+ ExcuteProcess(exec, param, null, (s, e) => Console.WriteLine(e.Data));
}
diff --git a/DownKyi.Core/FFmpeg_LICENSE.txt b/DownKyi.Core/FFmpeg_LICENSE.txt
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/DownKyi.Core/FFmpeg_LICENSE.txt
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ 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; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/DownKyi.Core/FileName/FileName.cs b/DownKyi.Core/FileName/FileName.cs
index 2e8684d..356a9e0 100644
--- a/DownKyi.Core/FileName/FileName.cs
+++ b/DownKyi.Core/FileName/FileName.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace DownKyi.Core.FileName
@@ -6,7 +7,7 @@ namespace DownKyi.Core.FileName
public class FileName
{
private readonly List nameParts;
- private int order = -1;
+ private string order = "ORDER";
private string section = "SECTION";
private string mainTitle = "MAIN_TITLE";
private string pageTitle = "PAGE_TITLE";
@@ -36,7 +37,15 @@ namespace DownKyi.Core.FileName
public FileName SetOrder(int order)
{
- this.order = order;
+ this.order = order.ToString();
+ return this;
+ }
+
+ public FileName SetOrder(int order, int count)
+ {
+ int length = Math.Abs(count).ToString().Length;
+ this.order = order.ToString("D" + length);
+
return this;
}
@@ -127,14 +136,7 @@ namespace DownKyi.Core.FileName
switch (part)
{
case FileNamePart.ORDER:
- if (order != -1)
- {
- path += order;
- }
- else
- {
- path += "ORDER";
- }
+ path += order;
break;
case FileNamePart.SECTION:
path += section;
diff --git a/DownKyi.Core/Properties/AssemblyInfo.cs b/DownKyi.Core/Properties/AssemblyInfo.cs
index 18b88bb..4061da8 100644
--- a/DownKyi.Core/Properties/AssemblyInfo.cs
+++ b/DownKyi.Core/Properties/AssemblyInfo.cs
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("DownKyi")]
[assembly: AssemblyProduct("DownKyi.Core")]
-[assembly: AssemblyCopyright("Copyright © Downkyi 2020-2021")]
+[assembly: AssemblyCopyright("Copyright © Downkyi 2020-2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.1.0.0")]
-[assembly: AssemblyFileVersion("2.1.0.0")]
+[assembly: AssemblyVersion("2.1.1.0")]
+[assembly: AssemblyFileVersion("2.1.1.0")]
diff --git a/DownKyi.Core/Settings/AfterDownloadOperation.cs b/DownKyi.Core/Settings/AfterDownloadOperation.cs
index 99ac8a1..d6ebdb1 100644
--- a/DownKyi.Core/Settings/AfterDownloadOperation.cs
+++ b/DownKyi.Core/Settings/AfterDownloadOperation.cs
@@ -2,6 +2,7 @@
{
public enum AfterDownloadOperation
{
+ NOT_SET = 0,
NONE = 1,
OPEN_FOLDER,
CLOSE_APP,
diff --git a/DownKyi.Core/Settings/DownloadFinishedSort.cs b/DownKyi.Core/Settings/DownloadFinishedSort.cs
index 6676737..9f1c773 100644
--- a/DownKyi.Core/Settings/DownloadFinishedSort.cs
+++ b/DownKyi.Core/Settings/DownloadFinishedSort.cs
@@ -2,7 +2,8 @@
{
public enum DownloadFinishedSort
{
- DOWNLOAD = 0,
+ NOT_SET = 0,
+ DOWNLOAD,
NUMBER
}
}
diff --git a/DownKyi.Core/Settings/Models/AboutSettings.cs b/DownKyi.Core/Settings/Models/AboutSettings.cs
index 7b6a1db..46e1543 100644
--- a/DownKyi.Core/Settings/Models/AboutSettings.cs
+++ b/DownKyi.Core/Settings/Models/AboutSettings.cs
@@ -5,7 +5,7 @@
///
public class AboutSettings
{
- public AllowStatus IsReceiveBetaVersion { get; set; }
- public AllowStatus AutoUpdateWhenLaunch { get; set; }
+ public AllowStatus IsReceiveBetaVersion { get; set; } = AllowStatus.NONE;
+ public AllowStatus AutoUpdateWhenLaunch { get; set; } = AllowStatus.NONE;
}
}
diff --git a/DownKyi.Core/Settings/Models/BasicSettings.cs b/DownKyi.Core/Settings/Models/BasicSettings.cs
index 46a53e0..43eea04 100644
--- a/DownKyi.Core/Settings/Models/BasicSettings.cs
+++ b/DownKyi.Core/Settings/Models/BasicSettings.cs
@@ -5,10 +5,11 @@
///
public class BasicSettings
{
- public AfterDownloadOperation AfterDownload { get; set; }
- public AllowStatus IsListenClipboard { get; set; }
- public AllowStatus IsAutoParseVideo { get; set; }
- public ParseScope ParseScope { get; set; }
- public DownloadFinishedSort DownloadFinishedSort { get; set; }
+ public AfterDownloadOperation AfterDownload { get; set; } = AfterDownloadOperation.NOT_SET;
+ public AllowStatus IsListenClipboard { get; set; } = AllowStatus.NONE;
+ public AllowStatus IsAutoParseVideo { get; set; } = AllowStatus.NONE;
+ public ParseScope ParseScope { get; set; } = ParseScope.NOT_SET;
+ public AllowStatus IsAutoDownloadAll { get; set; } = AllowStatus.NONE;
+ public DownloadFinishedSort DownloadFinishedSort { get; set; } = DownloadFinishedSort.NOT_SET;
}
}
diff --git a/DownKyi.Core/Settings/Models/DanmakuSettings.cs b/DownKyi.Core/Settings/Models/DanmakuSettings.cs
index 64bc828..e018152 100644
--- a/DownKyi.Core/Settings/Models/DanmakuSettings.cs
+++ b/DownKyi.Core/Settings/Models/DanmakuSettings.cs
@@ -5,15 +5,15 @@
///
public class DanmakuSettings
{
- public AllowStatus DanmakuTopFilter { get; set; }
- public AllowStatus DanmakuBottomFilter { get; set; }
- public AllowStatus DanmakuScrollFilter { get; set; }
- public AllowStatus IsCustomDanmakuResolution { get; set; }
- public int DanmakuScreenWidth { get; set; }
- public int DanmakuScreenHeight { get; set; }
- public string DanmakuFontName { get; set; }
- public int DanmakuFontSize { get; set; }
- public int DanmakuLineCount { get; set; }
- public DanmakuLayoutAlgorithm DanmakuLayoutAlgorithm { get; set; }
+ public AllowStatus DanmakuTopFilter { get; set; } = AllowStatus.NONE;
+ public AllowStatus DanmakuBottomFilter { get; set; } = AllowStatus.NONE;
+ public AllowStatus DanmakuScrollFilter { get; set; } = AllowStatus.NONE;
+ public AllowStatus IsCustomDanmakuResolution { get; set; } = AllowStatus.NONE;
+ public int DanmakuScreenWidth { get; set; } = -1;
+ public int DanmakuScreenHeight { get; set; } = -1;
+ public string DanmakuFontName { get; set; } = null;
+ public int DanmakuFontSize { get; set; } = -1;
+ public int DanmakuLineCount { get; set; } = -1;
+ public DanmakuLayoutAlgorithm DanmakuLayoutAlgorithm { get; set; } = DanmakuLayoutAlgorithm.NONE;
}
}
diff --git a/DownKyi.Core/Settings/Models/NetworkSettings.cs b/DownKyi.Core/Settings/Models/NetworkSettings.cs
index cdfcb5f..6b283f8 100644
--- a/DownKyi.Core/Settings/Models/NetworkSettings.cs
+++ b/DownKyi.Core/Settings/Models/NetworkSettings.cs
@@ -7,17 +7,17 @@ namespace DownKyi.Core.Settings.Models
///
public class NetworkSettings
{
- public AllowStatus IsLiftingOfRegion { get; set; }
- public int AriaListenPort { get; set; }
- public AriaConfigLogLevel AriaLogLevel { get; set; }
- public int AriaMaxConcurrentDownloads { get; set; }
- public int AriaSplit { get; set; }
- public int AriaMaxOverallDownloadLimit { get; set; }
- public int AriaMaxDownloadLimit { get; set; }
- public AriaConfigFileAllocation AriaFileAllocation { get; set; }
+ public AllowStatus IsLiftingOfRegion { get; set; } = AllowStatus.NONE;
+ public int AriaListenPort { get; set; } = -1;
+ public AriaConfigLogLevel AriaLogLevel { get; set; } = AriaConfigLogLevel.NOT_SET;
+ public int AriaMaxConcurrentDownloads { get; set; } = -1;
+ public int AriaSplit { get; set; } = -1;
+ public int AriaMaxOverallDownloadLimit { get; set; } = -1;
+ public int AriaMaxDownloadLimit { get; set; } = -1;
+ public AriaConfigFileAllocation AriaFileAllocation { get; set; } = AriaConfigFileAllocation.NOT_SET;
- public AllowStatus IsAriaHttpProxy { get; set; }
- public string AriaHttpProxy { get; set; }
- public int AriaHttpProxyListenPort { get; set; }
+ public AllowStatus IsAriaHttpProxy { get; set; } = AllowStatus.NONE;
+ public string AriaHttpProxy { get; set; } = null;
+ public int AriaHttpProxyListenPort { get; set; } = -1;
}
}
diff --git a/DownKyi.Core/Settings/Models/VideoContentSettings.cs b/DownKyi.Core/Settings/Models/VideoContentSettings.cs
new file mode 100644
index 0000000..ddc26a1
--- /dev/null
+++ b/DownKyi.Core/Settings/Models/VideoContentSettings.cs
@@ -0,0 +1,11 @@
+namespace DownKyi.Core.Settings.Models
+{
+ public class VideoContentSettings
+ {
+ public bool DownloadAudio { get; set; } = true;
+ public bool DownloadVideo { get; set; } = true;
+ public bool DownloadDanmaku { get; set; } = true;
+ public bool DownloadSubtitle { get; set; } = true;
+ public bool DownloadCover { get; set; } = true;
+ }
+}
diff --git a/DownKyi.Core/Settings/Models/VideoSettings.cs b/DownKyi.Core/Settings/Models/VideoSettings.cs
index d5fe834..0cf431e 100644
--- a/DownKyi.Core/Settings/Models/VideoSettings.cs
+++ b/DownKyi.Core/Settings/Models/VideoSettings.cs
@@ -8,13 +8,16 @@ namespace DownKyi.Core.Settings.Models
///
public class VideoSettings
{
- public VideoCodecs VideoCodecs { get; set; } // AVC or HEVC
- public int Quality { get; set; } // 画质
- public int AudioQuality { get; set; } // 音质
- public AllowStatus IsTranscodingFlvToMp4 { get; set; } // 是否将flv转为mp4
- public string SaveVideoRootPath { get; set; } // 视频保存路径
- public List HistoryVideoRootPaths { get; set; } // 历史视频保存路径
- public AllowStatus IsUseSaveVideoRootPath { get; set; } // 是否使用默认视频保存路径
- public List FileNameParts { get; set; } // 文件命名格式
+ public VideoCodecs VideoCodecs { get; set; } = VideoCodecs.NONE; // AVC or HEVC
+ public int Quality { get; set; } = -1; // 画质
+ public int AudioQuality { get; set; } = -1; // 音质
+ public AllowStatus IsTranscodingFlvToMp4 { get; set; } = AllowStatus.NONE; // 是否将flv转为mp4
+ public string SaveVideoRootPath { get; set; } = null; // 视频保存路径
+ public List HistoryVideoRootPaths { get; set; } = null; // 历史视频保存路径
+ public AllowStatus IsUseSaveVideoRootPath { get; set; } = AllowStatus.NONE; // 是否使用默认视频保存路径
+ public VideoContentSettings VideoContent { get; set; } = null; // 下载内容
+ public List FileNameParts { get; set; } = null; // 文件命名格式
+ public string FileNamePartTimeFormat { get; set; } = null; // 文件命名中的时间格式
+ public OrderFormat OrderFormat { get; set; } = OrderFormat.NOT_SET; // 文件命名中的序号格式
}
}
diff --git a/DownKyi.Core/Settings/OrderFormat.cs b/DownKyi.Core/Settings/OrderFormat.cs
new file mode 100644
index 0000000..f496835
--- /dev/null
+++ b/DownKyi.Core/Settings/OrderFormat.cs
@@ -0,0 +1,9 @@
+namespace DownKyi.Core.Settings
+{
+ public enum OrderFormat
+ {
+ NOT_SET = 0,
+ NATURAL, // 自然数
+ LEADING_ZEROS, // 前导零填充
+ }
+}
diff --git a/DownKyi.Core/Settings/ParseScope.cs b/DownKyi.Core/Settings/ParseScope.cs
index b028eac..d846ebf 100644
--- a/DownKyi.Core/Settings/ParseScope.cs
+++ b/DownKyi.Core/Settings/ParseScope.cs
@@ -2,6 +2,7 @@
{
public enum ParseScope
{
+ NOT_SET = 0,
NONE = 1,
SELECTED_ITEM,
CURRENT_SECTION,
diff --git a/DownKyi.Core/Settings/SettingsManager.About.cs b/DownKyi.Core/Settings/SettingsManager.About.cs
index b4a2f75..5cb15cb 100644
--- a/DownKyi.Core/Settings/SettingsManager.About.cs
+++ b/DownKyi.Core/Settings/SettingsManager.About.cs
@@ -15,7 +15,7 @@
public AllowStatus IsReceiveBetaVersion()
{
appSettings = GetSettings();
- if (appSettings.About.IsReceiveBetaVersion == 0)
+ if (appSettings.About.IsReceiveBetaVersion == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
IsReceiveBetaVersion(isReceiveBetaVersion);
@@ -42,7 +42,7 @@
public AllowStatus GetAutoUpdateWhenLaunch()
{
appSettings = GetSettings();
- if (appSettings.About.AutoUpdateWhenLaunch == 0)
+ if (appSettings.About.AutoUpdateWhenLaunch == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
SetAutoUpdateWhenLaunch(autoUpdateWhenLaunch);
diff --git a/DownKyi.Core/Settings/SettingsManager.Basic.cs b/DownKyi.Core/Settings/SettingsManager.Basic.cs
index d5f93e7..ccf618f 100644
--- a/DownKyi.Core/Settings/SettingsManager.Basic.cs
+++ b/DownKyi.Core/Settings/SettingsManager.Basic.cs
@@ -14,6 +14,9 @@
// 默认的视频解析项
private readonly ParseScope parseScope = ParseScope.NONE;
+ // 解析后自动下载解析视频
+ private readonly AllowStatus isAutoDownloadAll = AllowStatus.NO;
+
// 下载完成列表排序
private readonly DownloadFinishedSort finishedSort = DownloadFinishedSort.DOWNLOAD;
@@ -24,7 +27,7 @@
public AfterDownloadOperation GetAfterDownloadOperation()
{
appSettings = GetSettings();
- if (appSettings.Basic.AfterDownload == 0)
+ if (appSettings.Basic.AfterDownload == AfterDownloadOperation.NOT_SET)
{
// 第一次获取,先设置默认值
SetAfterDownloadOperation(afterDownload);
@@ -51,7 +54,7 @@
public AllowStatus IsListenClipboard()
{
appSettings = GetSettings();
- if (appSettings.Basic.IsListenClipboard == 0)
+ if (appSettings.Basic.IsListenClipboard == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
IsListenClipboard(isListenClipboard);
@@ -78,7 +81,7 @@
public AllowStatus IsAutoParseVideo()
{
appSettings = GetSettings();
- if (appSettings.Basic.IsAutoParseVideo == 0)
+ if (appSettings.Basic.IsAutoParseVideo == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
IsAutoParseVideo(isAutoParseVideo);
@@ -105,7 +108,7 @@
public ParseScope GetParseScope()
{
appSettings = GetSettings();
- if (appSettings.Basic.ParseScope == 0)
+ if (appSettings.Basic.ParseScope == ParseScope.NOT_SET)
{
// 第一次获取,先设置默认值
SetParseScope(parseScope);
@@ -125,6 +128,33 @@
return SetSettings();
}
+ ///
+ /// 解析后是否自动下载解析视频
+ ///
+ ///
+ public AllowStatus IsAutoDownloadAll()
+ {
+ appSettings = GetSettings();
+ if (appSettings.Basic.IsAutoDownloadAll == AllowStatus.NONE)
+ {
+ // 第一次获取,先设置默认值
+ IsAutoDownloadAll(isAutoDownloadAll);
+ return isAutoDownloadAll;
+ }
+ return appSettings.Basic.IsAutoDownloadAll;
+ }
+
+ ///
+ /// 解析后是否自动下载解析视频
+ ///
+ ///
+ ///
+ public bool IsAutoDownloadAll(AllowStatus isAutoDownloadAll)
+ {
+ appSettings.Basic.IsAutoDownloadAll = isAutoDownloadAll;
+ return SetSettings();
+ }
+
///
/// 获取下载完成列表排序
///
@@ -132,7 +162,7 @@
public DownloadFinishedSort GetDownloadFinishedSort()
{
appSettings = GetSettings();
- if (appSettings.Basic.DownloadFinishedSort == 0)
+ if (appSettings.Basic.DownloadFinishedSort == DownloadFinishedSort.NOT_SET)
{
// 第一次获取,先设置默认值
SetDownloadFinishedSort(finishedSort);
diff --git a/DownKyi.Core/Settings/SettingsManager.Danmaku.cs b/DownKyi.Core/Settings/SettingsManager.Danmaku.cs
index 34f2b95..48e9a1b 100644
--- a/DownKyi.Core/Settings/SettingsManager.Danmaku.cs
+++ b/DownKyi.Core/Settings/SettingsManager.Danmaku.cs
@@ -40,7 +40,7 @@
public AllowStatus GetDanmakuTopFilter()
{
appSettings = GetSettings();
- if (appSettings.Danmaku.DanmakuTopFilter == 0)
+ if (appSettings.Danmaku.DanmakuTopFilter == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
SetDanmakuTopFilter(danmakuTopFilter);
@@ -67,7 +67,7 @@
public AllowStatus GetDanmakuBottomFilter()
{
appSettings = GetSettings();
- if (appSettings.Danmaku.DanmakuBottomFilter == 0)
+ if (appSettings.Danmaku.DanmakuBottomFilter == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
SetDanmakuBottomFilter(danmakuBottomFilter);
@@ -94,7 +94,7 @@
public AllowStatus GetDanmakuScrollFilter()
{
appSettings = GetSettings();
- if (appSettings.Danmaku.DanmakuScrollFilter == 0)
+ if (appSettings.Danmaku.DanmakuScrollFilter == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
SetDanmakuScrollFilter(danmakuScrollFilter);
@@ -121,7 +121,7 @@
public AllowStatus IsCustomDanmakuResolution()
{
appSettings = GetSettings();
- if (appSettings.Danmaku.IsCustomDanmakuResolution == 0)
+ if (appSettings.Danmaku.IsCustomDanmakuResolution == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
IsCustomDanmakuResolution(isCustomDanmakuResolution);
@@ -148,7 +148,7 @@
public int GetDanmakuScreenWidth()
{
appSettings = GetSettings();
- if (appSettings.Danmaku.DanmakuScreenWidth == 0)
+ if (appSettings.Danmaku.DanmakuScreenWidth == -1)
{
// 第一次获取,先设置默认值
SetDanmakuScreenWidth(danmakuScreenWidth);
@@ -175,7 +175,7 @@
public int GetDanmakuScreenHeight()
{
appSettings = GetSettings();
- if (appSettings.Danmaku.DanmakuScreenHeight == 0)
+ if (appSettings.Danmaku.DanmakuScreenHeight == -1)
{
// 第一次获取,先设置默认值
SetDanmakuScreenHeight(danmakuScreenHeight);
@@ -229,7 +229,7 @@
public int GetDanmakuFontSize()
{
appSettings = GetSettings();
- if (appSettings.Danmaku.DanmakuFontSize == 0)
+ if (appSettings.Danmaku.DanmakuFontSize == -1)
{
// 第一次获取,先设置默认值
SetDanmakuFontSize(danmakuFontSize);
@@ -256,7 +256,7 @@
public int GetDanmakuLineCount()
{
appSettings = GetSettings();
- if (appSettings.Danmaku.DanmakuLineCount == 0)
+ if (appSettings.Danmaku.DanmakuLineCount == -1)
{
// 第一次获取,先设置默认值
SetDanmakuLineCount(danmakuLineCount);
@@ -283,7 +283,7 @@
public DanmakuLayoutAlgorithm GetDanmakuLayoutAlgorithm()
{
appSettings = GetSettings();
- if (appSettings.Danmaku.DanmakuLayoutAlgorithm == 0)
+ if (appSettings.Danmaku.DanmakuLayoutAlgorithm == DanmakuLayoutAlgorithm.NONE)
{
// 第一次获取,先设置默认值
SetDanmakuLayoutAlgorithm(danmakuLayoutAlgorithm);
diff --git a/DownKyi.Core/Settings/SettingsManager.Network.cs b/DownKyi.Core/Settings/SettingsManager.Network.cs
index 95675e2..37842de 100644
--- a/DownKyi.Core/Settings/SettingsManager.Network.cs
+++ b/DownKyi.Core/Settings/SettingsManager.Network.cs
@@ -8,7 +8,7 @@ namespace DownKyi.Core.Settings
private readonly AllowStatus isLiftingOfRegion = AllowStatus.YES;
// Aria服务器端口号
- private readonly int ariaListenPort = 6800;
+ private readonly int ariaListenPort = 6801;
// Aria日志等级
private readonly AriaConfigLogLevel ariaLogLevel = AriaConfigLogLevel.INFO;
@@ -26,7 +26,7 @@ namespace DownKyi.Core.Settings
private readonly int ariaMaxDownloadLimit = 0;
// Aria文件预分配
- private readonly AriaConfigFileAllocation ariaFileAllocation = AriaConfigFileAllocation.PREALLOC;
+ private readonly AriaConfigFileAllocation ariaFileAllocation = AriaConfigFileAllocation.NONE;
// Aria HttpProxy代理
private readonly AllowStatus isAriaHttpProxy = AllowStatus.NO;
@@ -40,7 +40,7 @@ namespace DownKyi.Core.Settings
public AllowStatus IsLiftingOfRegion()
{
appSettings = GetSettings();
- if (appSettings.Network.IsLiftingOfRegion == 0)
+ if (appSettings.Network.IsLiftingOfRegion == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
IsLiftingOfRegion(isLiftingOfRegion);
@@ -67,7 +67,7 @@ namespace DownKyi.Core.Settings
public int GetAriaListenPort()
{
appSettings = GetSettings();
- if (appSettings.Network.AriaListenPort == 0)
+ if (appSettings.Network.AriaListenPort == -1)
{
// 第一次获取,先设置默认值
SetAriaListenPort(ariaListenPort);
@@ -94,7 +94,7 @@ namespace DownKyi.Core.Settings
public AriaConfigLogLevel GetAriaLogLevel()
{
appSettings = GetSettings();
- if (appSettings.Network.AriaLogLevel == 0)
+ if (appSettings.Network.AriaLogLevel == AriaConfigLogLevel.NOT_SET)
{
// 第一次获取,先设置默认值
SetAriaLogLevel(ariaLogLevel);
@@ -121,7 +121,7 @@ namespace DownKyi.Core.Settings
public int GetAriaMaxConcurrentDownloads()
{
appSettings = GetSettings();
- if (appSettings.Network.AriaMaxConcurrentDownloads == 0)
+ if (appSettings.Network.AriaMaxConcurrentDownloads == -1)
{
// 第一次获取,先设置默认值
SetAriaMaxConcurrentDownloads(ariaMaxConcurrentDownloads);
@@ -148,7 +148,7 @@ namespace DownKyi.Core.Settings
public int GetAriaSplit()
{
appSettings = GetSettings();
- if (appSettings.Network.AriaSplit == 0)
+ if (appSettings.Network.AriaSplit == -1)
{
// 第一次获取,先设置默认值
SetAriaSplit(ariaSplit);
@@ -175,7 +175,7 @@ namespace DownKyi.Core.Settings
public int GetAriaMaxOverallDownloadLimit()
{
appSettings = GetSettings();
- if (appSettings.Network.AriaMaxOverallDownloadLimit == 0)
+ if (appSettings.Network.AriaMaxOverallDownloadLimit == -1)
{
// 第一次获取,先设置默认值
SetAriaMaxOverallDownloadLimit(ariaMaxOverallDownloadLimit);
@@ -202,7 +202,7 @@ namespace DownKyi.Core.Settings
public int GetAriaMaxDownloadLimit()
{
appSettings = GetSettings();
- if (appSettings.Network.AriaMaxDownloadLimit == 0)
+ if (appSettings.Network.AriaMaxDownloadLimit == -1)
{
// 第一次获取,先设置默认值
SetAriaMaxDownloadLimit(ariaMaxDownloadLimit);
@@ -229,7 +229,7 @@ namespace DownKyi.Core.Settings
public AriaConfigFileAllocation GetAriaFileAllocation()
{
appSettings = GetSettings();
- if (appSettings.Network.AriaFileAllocation == 0)
+ if (appSettings.Network.AriaFileAllocation == AriaConfigFileAllocation.NOT_SET)
{
// 第一次获取,先设置默认值
SetAriaFileAllocation(ariaFileAllocation);
@@ -256,7 +256,7 @@ namespace DownKyi.Core.Settings
public AllowStatus IsAriaHttpProxy()
{
appSettings = GetSettings();
- if (appSettings.Network.IsAriaHttpProxy == 0)
+ if (appSettings.Network.IsAriaHttpProxy == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
IsAriaHttpProxy(isAriaHttpProxy);
@@ -310,7 +310,7 @@ namespace DownKyi.Core.Settings
public int GetAriaHttpProxyListenPort()
{
appSettings = GetSettings();
- if (appSettings.Network.AriaHttpProxyListenPort == 0)
+ if (appSettings.Network.AriaHttpProxyListenPort == -1)
{
// 第一次获取,先设置默认值
SetAriaHttpProxyListenPort(ariaHttpProxyListenPort);
diff --git a/DownKyi.Core/Settings/SettingsManager.Video.cs b/DownKyi.Core/Settings/SettingsManager.Video.cs
index aa50f59..7a88cc4 100644
--- a/DownKyi.Core/Settings/SettingsManager.Video.cs
+++ b/DownKyi.Core/Settings/SettingsManager.Video.cs
@@ -1,4 +1,5 @@
using DownKyi.Core.FileName;
+using DownKyi.Core.Settings.Models;
using System;
using System.Collections.Generic;
using System.IO;
@@ -28,6 +29,9 @@ namespace DownKyi.Core.Settings
// 是否使用默认下载目录,如果是,则每次点击下载选中项时不再询问下载目录
private readonly AllowStatus isUseSaveVideoRootPath = AllowStatus.NO;
+ // 下载内容
+ private readonly VideoContentSettings videoContent = new VideoContentSettings();
+
// 文件命名格式
private readonly List fileNameParts = new List
{
@@ -44,6 +48,12 @@ namespace DownKyi.Core.Settings
FileNamePart.VIDEO_CODEC,
};
+ // 文件命名中的时间格式
+ private readonly string fileNamePartTimeFormat = "yyyy-MM-dd";
+
+ // 文件命名中的序号格式
+ private readonly OrderFormat orderFormat = OrderFormat.NATURAL;
+
///
/// 获取优先下载的视频编码
///
@@ -51,7 +61,7 @@ namespace DownKyi.Core.Settings
public VideoCodecs GetVideoCodecs()
{
appSettings = GetSettings();
- if (appSettings.Video.VideoCodecs == 0)
+ if (appSettings.Video.VideoCodecs == VideoCodecs.NONE)
{
// 第一次获取,先设置默认值
SetVideoCodecs(videoCodecs);
@@ -78,7 +88,7 @@ namespace DownKyi.Core.Settings
public int GetQuality()
{
appSettings = GetSettings();
- if (appSettings.Video.Quality == 0)
+ if (appSettings.Video.Quality == -1)
{
// 第一次获取,先设置默认值
SetQuality(quality);
@@ -105,7 +115,7 @@ namespace DownKyi.Core.Settings
public int GetAudioQuality()
{
appSettings = GetSettings();
- if (appSettings.Video.AudioQuality == 0)
+ if (appSettings.Video.AudioQuality == -1)
{
// 第一次获取,先设置默认值
SetAudioQuality(audioQuality);
@@ -132,7 +142,7 @@ namespace DownKyi.Core.Settings
public AllowStatus IsTranscodingFlvToMp4()
{
appSettings = GetSettings();
- if (appSettings.Video.IsTranscodingFlvToMp4 == 0)
+ if (appSettings.Video.IsTranscodingFlvToMp4 == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
IsTranscodingFlvToMp4(isTranscodingFlvToMp4);
@@ -213,7 +223,7 @@ namespace DownKyi.Core.Settings
public AllowStatus IsUseSaveVideoRootPath()
{
appSettings = GetSettings();
- if (appSettings.Video.IsUseSaveVideoRootPath == 0)
+ if (appSettings.Video.IsUseSaveVideoRootPath == AllowStatus.NONE)
{
// 第一次获取,先设置默认值
IsUseSaveVideoRootPath(isUseSaveVideoRootPath);
@@ -233,6 +243,33 @@ namespace DownKyi.Core.Settings
return SetSettings();
}
+ ///
+ /// 获取下载内容
+ ///
+ ///
+ public VideoContentSettings GetVideoContent()
+ {
+ appSettings = GetSettings();
+ if (appSettings.Video.VideoContent == null)
+ {
+ // 第一次获取,先设置默认值
+ SetVideoContent(videoContent);
+ return videoContent;
+ }
+ return appSettings.Video.VideoContent;
+ }
+
+ ///
+ /// 设置下载内容
+ ///
+ ///
+ ///
+ public bool SetVideoContent(VideoContentSettings videoContent)
+ {
+ appSettings.Video.VideoContent = videoContent;
+ return SetSettings();
+ }
+
///
/// 获取文件命名格式
///
@@ -260,5 +297,59 @@ namespace DownKyi.Core.Settings
return SetSettings();
}
+ ///
+ /// 获取文件命名中的时间格式
+ ///
+ ///
+ public string GetFileNamePartTimeFormat()
+ {
+ appSettings = GetSettings();
+ if (appSettings.Video.FileNamePartTimeFormat == null || appSettings.Video.FileNamePartTimeFormat == string.Empty)
+ {
+ // 第一次获取,先设置默认值
+ SetFileNamePartTimeFormat(fileNamePartTimeFormat);
+ return fileNamePartTimeFormat;
+ }
+ return appSettings.Video.FileNamePartTimeFormat;
+ }
+
+ ///
+ /// 设置文件命名中的时间格式
+ ///
+ ///
+ ///
+ public bool SetFileNamePartTimeFormat(string fileNamePartTimeFormat)
+ {
+ appSettings.Video.FileNamePartTimeFormat = fileNamePartTimeFormat;
+ return SetSettings();
+ }
+
+ ///
+ /// 获取文件命名中的序号格式
+ ///
+ ///
+ public OrderFormat GetOrderFormat()
+ {
+ appSettings = GetSettings();
+ if (appSettings.Video.OrderFormat == OrderFormat.NOT_SET)
+ {
+ // 第一次获取,先设置默认值
+ SetOrderFormat(orderFormat);
+ return orderFormat;
+ }
+ return appSettings.Video.OrderFormat;
+ }
+
+ ///
+ /// 设置文件命名中的序号格式
+ ///
+ ///
+ ///
+ public bool SetOrderFormat(OrderFormat orderFormat)
+ {
+ appSettings.Video.OrderFormat = orderFormat;
+ return SetSettings();
+ }
+
}
}
diff --git a/DownKyi.Core/Settings/SettingsManager.cs b/DownKyi.Core/Settings/SettingsManager.cs
index a5da781..f6d19b0 100644
--- a/DownKyi.Core/Settings/SettingsManager.cs
+++ b/DownKyi.Core/Settings/SettingsManager.cs
@@ -57,9 +57,11 @@ namespace DownKyi.Core.Settings
{
try
{
- StreamReader streamReader = File.OpenText(settingsName);
+ FileStream fileStream = new FileStream(settingsName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ StreamReader streamReader = new StreamReader(fileStream, System.Text.Encoding.UTF8);
string jsonWordTemplate = streamReader.ReadToEnd();
streamReader.Close();
+ fileStream.Close();
#if DEBUG
#else
@@ -71,7 +73,8 @@ namespace DownKyi.Core.Settings
}
catch (Exception e)
{
- Logging.LogManager.Error(e);
+ Utils.Debugging.Console.PrintLine("GetSettings()发生异常: {0}", e);
+ Logging.LogManager.Error("SettingsManager", e);
return new AppSettings();
}
}
@@ -97,7 +100,8 @@ namespace DownKyi.Core.Settings
}
catch (Exception e)
{
- Logging.LogManager.Error(e);
+ Utils.Debugging.Console.PrintLine("SetSettings()发生异常: {0}", e);
+ Logging.LogManager.Error("SettingsManager", e);
return false;
}
}
diff --git a/DownKyi.Core/Storage/Database/DbHelper.cs b/DownKyi.Core/Storage/Database/DbHelper.cs
index 8b6db35..a2e753f 100644
--- a/DownKyi.Core/Storage/Database/DbHelper.cs
+++ b/DownKyi.Core/Storage/Database/DbHelper.cs
@@ -1,20 +1,37 @@
-using System;
+using DownKyi.Core.Logging;
+using System;
+using System.Collections.Generic;
using System.Data.SQLite;
namespace DownKyi.Core.Storage.Database
{
public class DbHelper
{
+ private readonly string connStr;
private readonly SQLiteConnection conn;
+ private static readonly Dictionary database = new Dictionary();
+
///
/// 创建一个数据库
///
///
public DbHelper(string dbPath)
{
- string connStr = $"Data Source={dbPath};Version=3;";
+ connStr = $"Data Source={dbPath};Version=3;";
+
+ if (database.ContainsKey(connStr))
+ {
+ conn = database[connStr];
+
+ if (conn != null)
+ {
+ return;
+ }
+ }
+
conn = new SQLiteConnection(connStr);
+ database.Add(connStr, conn);
}
///
@@ -24,9 +41,21 @@ namespace DownKyi.Core.Storage.Database
///
public DbHelper(string dbPath, string secretKey)
{
- string connStr = $"Data Source={dbPath};Version=3;";
+ connStr = $"Data Source={dbPath};Version=3;";
+
+ if (database.ContainsKey(connStr))
+ {
+ conn = database[connStr];
+
+ if (conn != null)
+ {
+ return;
+ }
+ }
+
conn = new SQLiteConnection(connStr);
conn.SetPassword(secretKey);
+ database.Add(connStr, conn);
}
///
@@ -43,6 +72,8 @@ namespace DownKyi.Core.Storage.Database
///
public void Open()
{
+ if (conn == null) { return; }
+
if (!IsOpen())
{
conn.Open();
@@ -54,9 +85,13 @@ namespace DownKyi.Core.Storage.Database
///
public void Close()
{
+ if (conn == null) { return; }
+
if (IsOpen())
{
conn.Close();
+
+ database.Remove(connStr);
}
}
@@ -66,21 +101,31 @@ namespace DownKyi.Core.Storage.Database
///
public void ExecuteNonQuery(string sql, Action action = null)
{
- lock (conn)
+ if (conn == null) { return; }
+
+ try
{
- Open();
- using (var tr = conn.BeginTransaction())
+ lock (conn)
{
- using (var command = conn.CreateCommand())
+ Open();
+ using (var tr = conn.BeginTransaction())
{
- command.CommandText = sql;
- // 添加参数
- action?.Invoke(command.Parameters);
- command.ExecuteNonQuery();
+ using (var command = conn.CreateCommand())
+ {
+ command.CommandText = sql;
+ // 添加参数
+ action?.Invoke(command.Parameters);
+ command.ExecuteNonQuery();
+ }
+ tr.Commit();
}
- tr.Commit();
}
}
+ catch (SQLiteException e)
+ {
+ Utils.Debugging.Console.PrintLine("DbHelper ExecuteNonQuery()发生异常: {0}", e);
+ LogManager.Error("DbHelper ExecuteNonQuery()", e);
+ }
}
///
@@ -90,16 +135,26 @@ namespace DownKyi.Core.Storage.Database
///
public void ExecuteQuery(string sql, Action action)
{
- lock (conn)
+ if (conn == null) { return; }
+
+ try
{
- Open();
- using (var command = conn.CreateCommand())
+ lock (conn)
{
- command.CommandText = sql;
- var reader = command.ExecuteReader();
- action(reader);
+ Open();
+ using (var command = conn.CreateCommand())
+ {
+ command.CommandText = sql;
+ var reader = command.ExecuteReader();
+ action(reader);
+ }
}
}
+ catch (SQLiteException e)
+ {
+ Utils.Debugging.Console.PrintLine("DbHelper ExecuteQuery()发生异常: {0}", e);
+ LogManager.Error("DbHelper ExecuteQuery()", e);
+ }
}
}
diff --git a/DownKyi.Core/Storage/StorageCover.cs b/DownKyi.Core/Storage/StorageCover.cs
index a1556aa..dee2701 100644
--- a/DownKyi.Core/Storage/StorageCover.cs
+++ b/DownKyi.Core/Storage/StorageCover.cs
@@ -5,6 +5,7 @@ using System;
using System.Drawing;
using System.IO;
using System.Windows.Media.Imaging;
+using WebPSharp;
namespace DownKyi.Core.Storage
{
@@ -44,10 +45,38 @@ namespace DownKyi.Core.Storage
{
if (cover == null) { return null; }
- Bitmap bitmap = new Bitmap(cover);
- Image thumbnail = bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero);
+ try
+ {
+ Bitmap bitmap = new Bitmap(cover);
+ Image thumbnail = bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero);
+
+ return StorageUtils.BitmapToBitmapImage(new Bitmap(thumbnail));
+ }
+ catch (ArgumentException)
+ {
+ try
+ {
+ SimpleDecoder simpleDecoder = new SimpleDecoder(cover);
+ Bitmap bitmap = simpleDecoder.WebPtoBitmap();
+ Image thumbnail = bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero);
- return StorageUtils.BitmapToBitmapImage(new Bitmap(thumbnail));
+ return StorageUtils.BitmapToBitmapImage(new Bitmap(thumbnail));
+ }
+ catch (Exception ex)
+ {
+ Utils.Debugging.Console.PrintLine("GetCoverThumbnail()发生异常: {0}", ex);
+ LogManager.Error("StorageCover.GetCoverThumbnail()", ex);
+
+ return null;
+ }
+ }
+ catch (Exception e)
+ {
+ Utils.Debugging.Console.PrintLine("GetCoverThumbnail()发生异常: {0}", e);
+ LogManager.Error("StorageCover.GetCoverThumbnail()", e);
+
+ return null;
+ }
}
///
@@ -90,7 +119,7 @@ namespace DownKyi.Core.Storage
};
coverDb.Update(newCover);
- coverDb.Close();
+ //coverDb.Close();
return $"{StorageManager.GetCover()}/{cover.Md5}";
}
else
@@ -108,12 +137,12 @@ namespace DownKyi.Core.Storage
};
coverDb.Update(newCover);
- coverDb.Close();
+ //coverDb.Close();
return $"{StorageManager.GetCover()}/{md5}";
}
else
{
- coverDb.Close();
+ //coverDb.Close();
return null;
}
}
@@ -133,12 +162,12 @@ namespace DownKyi.Core.Storage
};
coverDb.Insert(newCover);
- coverDb.Close();
+ //coverDb.Close();
return $"{StorageManager.GetCover()}/{md5}";
}
else
{
- coverDb.Close();
+ //coverDb.Close();
return null;
}
}
diff --git a/DownKyi.Core/Storage/StorageHeader.cs b/DownKyi.Core/Storage/StorageHeader.cs
index 09a768a..49e0d5a 100644
--- a/DownKyi.Core/Storage/StorageHeader.cs
+++ b/DownKyi.Core/Storage/StorageHeader.cs
@@ -5,6 +5,7 @@ using System;
using System.Drawing;
using System.IO;
using System.Windows.Media.Imaging;
+using WebPSharp;
namespace DownKyi.Core.Storage
{
@@ -44,10 +45,38 @@ namespace DownKyi.Core.Storage
{
if (header == null) { return null; }
- var bitmap = new Bitmap(header);
- var thumbnail = bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero);
+ try
+ {
+ Bitmap bitmap = new Bitmap(header);
+ Image thumbnail = bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero);
+
+ return StorageUtils.BitmapToBitmapImage(new Bitmap(thumbnail));
+ }
+ catch (ArgumentException)
+ {
+ try
+ {
+ SimpleDecoder simpleDecoder = new SimpleDecoder(header);
+ Bitmap bitmap = simpleDecoder.WebPtoBitmap();
+ Image thumbnail = bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero);
- return StorageUtils.BitmapToBitmapImage(new Bitmap(thumbnail));
+ return StorageUtils.BitmapToBitmapImage(new Bitmap(thumbnail));
+ }
+ catch (Exception ex)
+ {
+ Utils.Debugging.Console.PrintLine("GetHeaderThumbnail()发生异常: {0}", ex);
+ LogManager.Error("StorageHeader.GetHeaderThumbnail()", ex);
+
+ return null;
+ }
+ }
+ catch (Exception e)
+ {
+ Utils.Debugging.Console.PrintLine("GetHeaderThumbnail()发生异常: {0}", e);
+ LogManager.Error("StorageHeader.GetHeaderThumbnail()", e);
+
+ return null;
+ }
}
///
@@ -58,7 +87,7 @@ namespace DownKyi.Core.Storage
public string GetHeader(long mid, string name, string url)
{
HeaderDb headerDb = new HeaderDb();
- var header = headerDb.QueryByMid(mid);
+ Header header = headerDb.QueryByMid(mid);
if (header != null)
{
@@ -73,7 +102,7 @@ namespace DownKyi.Core.Storage
Md5 = header.Md5
};
headerDb.Update(newHeader);
- headerDb.Close();
+ //headerDb.Close();
return $"{StorageManager.GetHeader()}/{header.Md5}";
}
else
@@ -89,12 +118,12 @@ namespace DownKyi.Core.Storage
Md5 = md5
};
headerDb.Insert(newHeader);
- headerDb.Close();
+ //headerDb.Close();
return $"{StorageManager.GetHeader()}/{md5}";
}
else
{
- headerDb.Close();
+ //headerDb.Close();
return null;
}
}
@@ -112,12 +141,12 @@ namespace DownKyi.Core.Storage
Md5 = md5
};
headerDb.Insert(newHeader);
- headerDb.Close();
+ //headerDb.Close();
return $"{StorageManager.GetHeader()}/{md5}";
}
else
{
- headerDb.Close();
+ //headerDb.Close();
return null;
}
}
diff --git a/DownKyi.Core/Utils/Format.cs b/DownKyi.Core/Utils/Format.cs
index 910cafd..6e0faf1 100644
--- a/DownKyi.Core/Utils/Format.cs
+++ b/DownKyi.Core/Utils/Format.cs
@@ -199,7 +199,7 @@ namespace DownKyi.Core.Utils
destName = Regex.Replace(destName, @"\p{C}+", string.Empty);
// 移除前导和尾部的空白字符、dot符
- return destName.Trim().TrimStart('.').TrimEnd('.');
+ return destName.Trim('.').Trim();
}
}
diff --git a/DownKyi.Core/Utils/MachineCode.cs b/DownKyi.Core/Utils/MachineCode.cs
index 5c13cb2..faecd8f 100644
--- a/DownKyi.Core/Utils/MachineCode.cs
+++ b/DownKyi.Core/Utils/MachineCode.cs
@@ -20,8 +20,8 @@ namespace DownKyi.Core.Utils
string machineCodeString = "PC." +
machineCode.GetMainBordId() + "." +
- machineCode.GetCpuInfo() + "." +
- machineCode.GetDiskID();// + "." +
+ machineCode.GetCpuInfo();// + "." +
+ //machineCode.GetDiskID();// + "." +
//machineCode.GetMoAddress();
return machineCodeString.Replace(" ", "");
}
diff --git a/DownKyi/aria2_COPYING.txt b/DownKyi.Core/aria2_COPYING.txt
similarity index 100%
rename from DownKyi/aria2_COPYING.txt
rename to DownKyi.Core/aria2_COPYING.txt
diff --git a/DownKyi.Core/aria2c.exe b/DownKyi.Core/aria2c.exe
new file mode 100644
index 0000000..97b2b5c
Binary files /dev/null and b/DownKyi.Core/aria2c.exe differ
diff --git a/DownKyi/ffmpeg.exe b/DownKyi.Core/ffmpeg.exe
similarity index 71%
rename from DownKyi/ffmpeg.exe
rename to DownKyi.Core/ffmpeg.exe
index 3284f06..06e8a67 100644
Binary files a/DownKyi/ffmpeg.exe and b/DownKyi.Core/ffmpeg.exe differ
diff --git a/DownKyi.Core/packages.config b/DownKyi.Core/packages.config
index c49a756..8f12907 100644
--- a/DownKyi.Core/packages.config
+++ b/DownKyi.Core/packages.config
@@ -11,4 +11,5 @@
+
\ No newline at end of file
diff --git a/DownKyi.sln b/DownKyi.sln
index 5bc5e70..30ddbe1 100644
--- a/DownKyi.sln
+++ b/DownKyi.sln
@@ -19,29 +19,73 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{97075FCD-6E8F-4FF9-B73A-994197F3765A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{97075FCD-6E8F-4FF9-B73A-994197F3765A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Debug|x64.ActiveCfg = Debug|x64
+ {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Debug|x64.Build.0 = Debug|x64
+ {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Debug|x86.ActiveCfg = Debug|x86
+ {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Debug|x86.Build.0 = Debug|x86
{97075FCD-6E8F-4FF9-B73A-994197F3765A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97075FCD-6E8F-4FF9-B73A-994197F3765A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Release|x64.ActiveCfg = Release|x64
+ {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Release|x64.Build.0 = Release|x64
+ {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Release|x86.ActiveCfg = Release|x86
+ {97075FCD-6E8F-4FF9-B73A-994197F3765A}.Release|x86.Build.0 = Release|x86
{4FDE0364-F65B-4812-BFE8-34E886624FBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FDE0364-F65B-4812-BFE8-34E886624FBD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Debug|x64.ActiveCfg = Debug|x64
+ {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Debug|x64.Build.0 = Debug|x64
+ {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Debug|x86.ActiveCfg = Debug|x86
+ {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Debug|x86.Build.0 = Debug|x86
{4FDE0364-F65B-4812-BFE8-34E886624FBD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4FDE0364-F65B-4812-BFE8-34E886624FBD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Release|x64.ActiveCfg = Release|x64
+ {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Release|x64.Build.0 = Release|x64
+ {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Release|x86.ActiveCfg = Release|x86
+ {4FDE0364-F65B-4812-BFE8-34E886624FBD}.Release|x86.Build.0 = Release|x86
{3107CD63-E257-455E-AE81-1FD3582B067A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3107CD63-E257-455E-AE81-1FD3582B067A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3107CD63-E257-455E-AE81-1FD3582B067A}.Debug|x64.ActiveCfg = Debug|x64
+ {3107CD63-E257-455E-AE81-1FD3582B067A}.Debug|x64.Build.0 = Debug|x64
+ {3107CD63-E257-455E-AE81-1FD3582B067A}.Debug|x86.ActiveCfg = Debug|x86
+ {3107CD63-E257-455E-AE81-1FD3582B067A}.Debug|x86.Build.0 = Debug|x86
{3107CD63-E257-455E-AE81-1FD3582B067A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3107CD63-E257-455E-AE81-1FD3582B067A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3107CD63-E257-455E-AE81-1FD3582B067A}.Release|x64.ActiveCfg = Release|x64
+ {3107CD63-E257-455E-AE81-1FD3582B067A}.Release|x64.Build.0 = Release|x64
+ {3107CD63-E257-455E-AE81-1FD3582B067A}.Release|x86.ActiveCfg = Release|x86
+ {3107CD63-E257-455E-AE81-1FD3582B067A}.Release|x86.Build.0 = Release|x86
{81B9719E-DA29-444F-BB72-CBD5819A654D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81B9719E-DA29-444F-BB72-CBD5819A654D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {81B9719E-DA29-444F-BB72-CBD5819A654D}.Debug|x64.ActiveCfg = Debug|x64
+ {81B9719E-DA29-444F-BB72-CBD5819A654D}.Debug|x64.Build.0 = Debug|x64
+ {81B9719E-DA29-444F-BB72-CBD5819A654D}.Debug|x86.ActiveCfg = Debug|x86
+ {81B9719E-DA29-444F-BB72-CBD5819A654D}.Debug|x86.Build.0 = Debug|x86
{81B9719E-DA29-444F-BB72-CBD5819A654D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81B9719E-DA29-444F-BB72-CBD5819A654D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {81B9719E-DA29-444F-BB72-CBD5819A654D}.Release|x64.ActiveCfg = Release|x64
+ {81B9719E-DA29-444F-BB72-CBD5819A654D}.Release|x64.Build.0 = Release|x64
+ {81B9719E-DA29-444F-BB72-CBD5819A654D}.Release|x86.ActiveCfg = Release|x86
+ {81B9719E-DA29-444F-BB72-CBD5819A654D}.Release|x86.Build.0 = Release|x86
{95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Debug|x64.ActiveCfg = Debug|x64
+ {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Debug|x64.Build.0 = Debug|x64
+ {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Debug|x86.ActiveCfg = Debug|x86
+ {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Debug|x86.Build.0 = Debug|x86
{95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Release|Any CPU.Build.0 = Release|Any CPU
+ {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Release|x64.ActiveCfg = Release|x64
+ {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Release|x64.Build.0 = Release|x64
+ {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Release|x86.ActiveCfg = Release|x86
+ {95F12C16-86B5-43D5-AF3E-D2489E2DB239}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/DownKyi/App.xaml.cs b/DownKyi/App.xaml.cs
index 1ef4e1f..d698c99 100644
--- a/DownKyi/App.xaml.cs
+++ b/DownKyi/App.xaml.cs
@@ -16,6 +16,7 @@ using DownKyi.Views.Settings;
using DownKyi.Views.Toolbox;
using DownKyi.Views.UserSpace;
using Prism.Ioc;
+using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -201,6 +202,7 @@ namespace DownKyi
containerRegistry.RegisterForNavigation(ViewModels.UserSpace.ViewChannelViewModel.Tag);
// dialogs
+ containerRegistry.RegisterDialog(ViewAlertDialogViewModel.Tag);
containerRegistry.RegisterDialog(ViewDownloadSetterViewModel.Tag);
containerRegistry.RegisterDialog(ViewParsingSelectorViewModel.Tag);
diff --git a/DownKyi/AppConstant.cs b/DownKyi/AppConstant.cs
new file mode 100644
index 0000000..cad527c
--- /dev/null
+++ b/DownKyi/AppConstant.cs
@@ -0,0 +1,7 @@
+namespace DownKyi
+{
+ public class AppConstant
+ {
+ public const string ClipboardId = "32ff00b1-1a09-4b25-9ca7-dcb6914b141c";
+ }
+}
diff --git a/DownKyi/DownKyi.csproj b/DownKyi/DownKyi.csproj
index 7a7c8b2..0ed81f1 100644
--- a/DownKyi/DownKyi.csproj
+++ b/DownKyi/DownKyi.csproj
@@ -56,6 +56,22 @@
app.manifest
+
+ x64
+ bin\x64\Debug\
+
+
+ x64
+ bin\x64\Release\
+
+
+ x86
+ bin\x86\Debug\
+
+
+ x86
+ bin\x86\Release\
+
@@ -79,6 +95,7 @@
MSBuild:Compile
Designer
+
CustomPager.xaml
@@ -97,11 +114,15 @@
+
+
+
+
@@ -170,6 +191,9 @@
+
+ ViewAlertDialog.xaml
+
ViewDownloadSetter.xaml
@@ -337,6 +361,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -554,18 +582,6 @@
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
diff --git a/DownKyi/FFmpeg_LICENSE.txt b/DownKyi/FFmpeg_LICENSE.txt
deleted file mode 100644
index 65c5ca8..0000000
--- a/DownKyi/FFmpeg_LICENSE.txt
+++ /dev/null
@@ -1,165 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/DownKyi/Images/SystemIcon.cs b/DownKyi/Images/SystemIcon.cs
index b6bec27..b2b83cb 100644
--- a/DownKyi/Images/SystemIcon.cs
+++ b/DownKyi/Images/SystemIcon.cs
@@ -65,6 +65,34 @@
l1.8-2.2c0-0.1,0-0.5-0.1-0.8l-3.1-3.6C29.7,17.1,29.5,17,29.2,17z",
Fill = "#FF000000"
};
+
+ Info = new VectorImage
+ {
+ Height = 20,
+ Width = 20,
+ Data = @"M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0
+ 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z",
+ Fill = "#FF00bcf2"
+ };
+
+ Warning = new VectorImage
+ {
+ Height = 20,
+ Width = 20,
+ Data = @"M12 5.99L19.53 19H4.47L12 5.99M2.74 18c-.77 1.33.19 3 1.73 3h15.06c1.54 0 2.5-1.67 1.73-3L13.73
+ 4.99c-.77-1.33-2.69-1.33-3.46 0L2.74 18zM11 11v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zm0 5h2v2h-2z",
+ Fill = "#FFffb900"
+ };
+
+ Error = new VectorImage
+ {
+ Height = 20,
+ Width = 20,
+ Data = @"M12 7c.55 0 1 .45 1 1v4c0 .55-.45 1-1 1s-1-.45-1-1V8c0-.55.45-1 1-1zm-.01-5C6.47 2 2 6.48 2 12s4.47
+ 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8
+ 8-3.58 8-8 8zm1-3h-2v-2h2v2z",
+ Fill = "#FFd83b01"
+ };
}
public VectorImage Close { get; private set; }
@@ -72,5 +100,9 @@
public VectorImage Minimize { get; private set; }
public VectorImage Restore { get; private set; }
public VectorImage Skin { get; private set; }
+
+ public VectorImage Info { get; private set; }
+ public VectorImage Warning { get; private set; }
+ public VectorImage Error { get; private set; }
}
}
diff --git a/DownKyi/Languages/Default.xaml b/DownKyi/Languages/Default.xaml
index 7617c23..89d7ff0 100644
--- a/DownKyi/Languages/Default.xaml
+++ b/DownKyi/Languages/Default.xaml
@@ -185,6 +185,7 @@
监听剪贴板
视频自动解析
视频解析范围:
+ 解析后自动下载已解析视频
网络
Aria服务器端口:
@@ -224,6 +225,10 @@
UP主ID
UP主昵称
恢复默认
+ 时间格式:
+ 序号格式:
+ 自然数
+ 前导零填充
弹幕
按类型屏蔽
@@ -293,7 +298,14 @@
提取视频
+ 信息
+ 警告
+ 错误
+
+ 确定
取消
+
+ 您确定要删除吗?
请选择文件夹
@@ -302,6 +314,7 @@
浏览
盘剩余空间:
下载内容:
+ 下载内容
所有
音频
视频
diff --git a/DownKyi/Models/AppInfo.cs b/DownKyi/Models/AppInfo.cs
index c83274f..2b9b0b0 100644
--- a/DownKyi/Models/AppInfo.cs
+++ b/DownKyi/Models/AppInfo.cs
@@ -3,12 +3,12 @@
public class AppInfo
{
public string Name { get; } = "哔哩下载姬";
- public int VersionCode { get; } = 503;
+ public int VersionCode { get; } = 508;
#if DEBUG
- public string VersionName { get; } = "1.5.0-alpha4 Debug";
+ public string VersionName { get; } = "1.5.1 Debug";
#else
- public string VersionName { get; } = "1.5.0-alpha4";
+ public string VersionName { get; } = "1.5.1";
#endif
}
diff --git a/DownKyi/Models/OrderFormatDisplay.cs b/DownKyi/Models/OrderFormatDisplay.cs
new file mode 100644
index 0000000..5e2a1a3
--- /dev/null
+++ b/DownKyi/Models/OrderFormatDisplay.cs
@@ -0,0 +1,10 @@
+using DownKyi.Core.Settings;
+
+namespace DownKyi.Models
+{
+ public class OrderFormatDisplay
+ {
+ public string Name { get; set; }
+ public OrderFormat OrderFormat { get; set; }
+ }
+}
diff --git a/DownKyi/Properties/AssemblyInfo.cs b/DownKyi/Properties/AssemblyInfo.cs
index 557ec1b..55552dc 100644
--- a/DownKyi/Properties/AssemblyInfo.cs
+++ b/DownKyi/Properties/AssemblyInfo.cs
@@ -12,7 +12,7 @@ using System.Windows;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("DownKyi")]
[assembly: AssemblyProduct("DownKyi")]
-[assembly: AssemblyCopyright("Copyright © Downkyi 2020-2021")]
+[assembly: AssemblyCopyright("Copyright © Downkyi 2020-2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -51,5 +51,5 @@ using System.Windows;
// 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("1.5.0.0")]
-[assembly: AssemblyFileVersion("1.5.0.0")]
+[assembly: AssemblyVersion("1.5.1.0")]
+[assembly: AssemblyFileVersion("1.5.1.0")]
diff --git a/DownKyi/Services/AlertService.cs b/DownKyi/Services/AlertService.cs
new file mode 100644
index 0000000..e30a9ff
--- /dev/null
+++ b/DownKyi/Services/AlertService.cs
@@ -0,0 +1,75 @@
+using DownKyi.Images;
+using DownKyi.Utils;
+using DownKyi.ViewModels.Dialogs;
+using Prism.Services.Dialogs;
+
+namespace DownKyi.Services
+{
+ public class AlertService
+ {
+ private readonly IDialogService dialogService;
+
+ public AlertService(IDialogService dialogService)
+ {
+ this.dialogService = dialogService;
+ }
+
+ ///
+ /// 显示一个信息弹窗
+ ///
+ ///
+ ///
+ public ButtonResult ShowInfo(string message)
+ {
+ VectorImage image = SystemIcon.Instance().Info;
+ string title = DictionaryResource.GetString("Info");
+ return ShowMessage(image, title, message);
+ }
+
+ ///
+ /// 显示一个警告弹窗
+ ///
+ ///
+ ///
+ public ButtonResult ShowWarning(string message)
+ {
+ VectorImage image = SystemIcon.Instance().Warning;
+ string title = DictionaryResource.GetString("Warning");
+ return ShowMessage(image, title, message);
+ }
+
+ ///
+ /// 显示一个错误弹窗
+ ///
+ ///
+ ///
+ public ButtonResult ShowError(string message)
+ {
+ VectorImage image = SystemIcon.Instance().Error;
+ string title = DictionaryResource.GetString("Error");
+ return ShowMessage(image, title, message);
+ }
+
+ private ButtonResult ShowMessage(VectorImage image, string type, string message)
+ {
+ ButtonResult result = ButtonResult.None;
+ if (dialogService == null)
+ {
+ return result;
+ }
+
+ DialogParameters param = new DialogParameters
+ {
+ { "image", image },
+ { "title", type },
+ { "message", message }
+ };
+ dialogService.ShowDialog(ViewAlertDialogViewModel.Tag, param, buttonResult =>
+ {
+ result = buttonResult.Result;
+ });
+ return result;
+ }
+
+ }
+}
diff --git a/DownKyi/Services/BangumiInfoService.cs b/DownKyi/Services/BangumiInfoService.cs
index aebf31c..69f1c6d 100644
--- a/DownKyi/Services/BangumiInfoService.cs
+++ b/DownKyi/Services/BangumiInfoService.cs
@@ -3,6 +3,7 @@ using DownKyi.Core.BiliApi.Bangumi.Models;
using DownKyi.Core.BiliApi.BiliUtils;
using DownKyi.Core.BiliApi.VideoStream;
using DownKyi.Core.BiliApi.VideoStream.Models;
+using DownKyi.Core.Settings;
using DownKyi.Core.Storage;
using DownKyi.Core.Utils;
using DownKyi.Utils;
@@ -120,10 +121,12 @@ namespace DownKyi.Services
};
}
+ // 文件命名中的时间格式
+ string timeFormat = SettingsManager.GetInstance().GetFileNamePartTimeFormat();
// 视频发布时间
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
DateTime dateTime = startTime.AddSeconds(episode.PubTime);
- page.PublishTime = dateTime.ToString("yyyy-MM-dd");
+ page.PublishTime = dateTime.ToString(timeFormat);
pages.Add(page);
}
@@ -135,11 +138,9 @@ namespace DownKyi.Services
/// 获取视频章节与剧集
///
///
- public List GetVideoSections()
+ public List GetVideoSections(bool noUgc = false)
{
if (bangumiSeason == null) { return null; }
- if (bangumiSeason.Section == null) { return null; }
- if (bangumiSeason.Section.Count == 0) { return null; }
List videoSections = new List
{
@@ -152,6 +153,15 @@ namespace DownKyi.Services
}
};
+ // 不需要其他季或花絮内容
+ if (noUgc)
+ {
+ return videoSections;
+ }
+
+ if (bangumiSeason.Section == null) { return null; }
+ if (bangumiSeason.Section.Count == 0) { return null; }
+
foreach (BangumiSection section in bangumiSeason.Section)
{
List pages = new List();
@@ -194,10 +204,12 @@ namespace DownKyi.Services
};
}
+ // 文件命名中的时间格式
+ string timeFormat = SettingsManager.GetInstance().GetFileNamePartTimeFormat();
// 视频发布时间
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
DateTime dateTime = startTime.AddSeconds(episode.PubTime);
- page.PublishTime = dateTime.ToString("yyyy-MM-dd");
+ page.PublishTime = dateTime.ToString(timeFormat);
pages.Add(page);
}
diff --git a/DownKyi/Services/CheeseInfoService.cs b/DownKyi/Services/CheeseInfoService.cs
index a49e925..62b5520 100644
--- a/DownKyi/Services/CheeseInfoService.cs
+++ b/DownKyi/Services/CheeseInfoService.cs
@@ -3,6 +3,7 @@ using DownKyi.Core.BiliApi.Cheese;
using DownKyi.Core.BiliApi.Cheese.Models;
using DownKyi.Core.BiliApi.VideoStream;
using DownKyi.Core.BiliApi.VideoStream.Models;
+using DownKyi.Core.Settings;
using DownKyi.Core.Storage;
using DownKyi.Core.Utils;
using DownKyi.Utils;
@@ -88,10 +89,12 @@ namespace DownKyi.Services
};
}
+ // 文件命名中的时间格式
+ string timeFormat = SettingsManager.GetInstance().GetFileNamePartTimeFormat();
// 视频发布时间
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
DateTime dateTime = startTime.AddSeconds(episode.ReleaseDate);
- page.PublishTime = dateTime.ToString("yyyy-MM-dd");
+ page.PublishTime = dateTime.ToString(timeFormat);
pages.Add(page);
}
@@ -103,7 +106,7 @@ namespace DownKyi.Services
/// 获取视频章节与剧集
///
///
- public List GetVideoSections()
+ public List GetVideoSections(bool noUgc = false)
{
return null;
}
diff --git a/DownKyi/Services/Download/AddToDownloadService.cs b/DownKyi/Services/Download/AddToDownloadService.cs
index f6d1273..c90519d 100644
--- a/DownKyi/Services/Download/AddToDownloadService.cs
+++ b/DownKyi/Services/Download/AddToDownloadService.cs
@@ -4,6 +4,7 @@ using DownKyi.Core.BiliApi.Zone;
using DownKyi.Core.FileName;
using DownKyi.Core.Logging;
using DownKyi.Core.Settings;
+using DownKyi.Core.Settings.Models;
using DownKyi.Core.Utils;
using DownKyi.Events;
using DownKyi.Models;
@@ -103,7 +104,7 @@ namespace DownKyi.Services.Download
return;
}
- videoSections = videoInfoService.GetVideoSections();
+ videoSections = videoInfoService.GetVideoSections(true);
if (videoSections == null)
{
LogManager.Debug(Tag, "videoSections is not exist.");
@@ -160,6 +161,14 @@ namespace DownKyi.Services.Download
// 是否使用默认下载目录
if (SettingsManager.GetInstance().IsUseSaveVideoRootPath() == AllowStatus.YES)
{
+ // 下载内容
+ VideoContentSettings videoContent = SettingsManager.GetInstance().GetVideoContent();
+ downloadAudio = videoContent.DownloadAudio;
+ downloadVideo = videoContent.DownloadVideo;
+ downloadDanmaku = videoContent.DownloadDanmaku;
+ downloadSubtitle = videoContent.DownloadSubtitle;
+ downloadCover = videoContent.DownloadCover;
+
directory = SettingsManager.GetInstance().GetSaveVideoRootPath();
}
else
@@ -196,7 +205,14 @@ namespace DownKyi.Services.Download
return directory;
}
- public int AddToDownload(IEventAggregator eventAggregator, string directory)
+ ///
+ /// 添加到下载列表
+ ///
+ /// 传递事件的对象
+ /// 下载路径
+ /// 是否下载所有,包括未选中项
+ /// 添加的数量
+ public int AddToDownload(IEventAggregator eventAggregator, string directory, bool isAll = false)
{
if (directory == null || directory == string.Empty) { return -1; }
if (videoSections == null) { return -1; }
@@ -212,7 +228,7 @@ namespace DownKyi.Services.Download
foreach (VideoPage page in section.VideoPages)
{
// 只下载选中项,跳过未选中项
- if (!page.IsSelected) { continue; }
+ if (!isAll && !page.IsSelected) { continue; }
// 没有解析的也跳过
if (page.PlayUrl == null) { continue; }
@@ -288,8 +304,7 @@ namespace DownKyi.Services.Download
// 文件路径
List fileNameParts = SettingsManager.GetInstance().GetFileNameParts();
- FileName fileName = FileName.Builder(fileNameParts)
- .SetOrder(page.Order)
+ FileName fileName = FileName.Builder(fileNameParts)
.SetSection(Format.FormatFileName(sectionName))
.SetMainTitle(Format.FormatFileName(videoInfoView.Title))
.SetPageTitle(Format.FormatFileName(page.Name))
@@ -302,7 +317,21 @@ namespace DownKyi.Services.Download
.SetBvid(page.Bvid)
.SetCid(page.Cid)
.SetUpMid(page.Owner.Mid)
- .SetUpName(page.Owner.Name);
+ .SetUpName(Format.FormatFileName(page.Owner.Name));
+
+ // 序号设置
+ OrderFormat orderFormat = SettingsManager.GetInstance().GetOrderFormat();
+ switch (orderFormat)
+ {
+ case OrderFormat.NATURAL:
+ fileName.SetOrder(page.Order);
+ break;
+ case OrderFormat.LEADING_ZEROS:
+ fileName.SetOrder(page.Order, section.VideoPages.Count);
+ break;
+ }
+
+ // 合成绝对路径
string filePath = Path.Combine(directory, fileName.RelativePath());
// 视频类别
diff --git a/DownKyi/Services/Download/AriaDownloadService.cs b/DownKyi/Services/Download/AriaDownloadService.cs
index c768fad..9981b2f 100644
--- a/DownKyi/Services/Download/AriaDownloadService.cs
+++ b/DownKyi/Services/Download/AriaDownloadService.cs
@@ -137,25 +137,33 @@ namespace DownKyi.Services.Download
if (downloadVideo.BackupUrl != null) { urls.AddRange(downloadVideo.BackupUrl); }
// 路径
+ downloading.DownloadBase.FilePath = downloading.DownloadBase.FilePath.Replace("\\", "/");
string[] temp = downloading.DownloadBase.FilePath.Split('/');
- string path = downloading.DownloadBase.FilePath.Replace(temp[temp.Length - 1], "");
+ //string path = downloading.DownloadBase.FilePath.Replace(temp[temp.Length - 1], "");
+ string path = downloading.DownloadBase.FilePath.TrimEnd(temp[temp.Length - 1].ToCharArray());
// 下载文件名
string fileName = Guid.NewGuid().ToString("N");
-
string key = $"{downloadVideo.Id}_{downloadVideo.Codecs}";
+
// 老版本数据库没有这一项,会变成null
if (downloading.Downloading.DownloadedFiles == null)
+ {
downloading.Downloading.DownloadedFiles = new List();
- // 还要检查一下文件有没有被人删掉,删掉的话重新下载
- // 如果下载视频之后音频文件被人删了。此时gid还是视频的,会下错文件
- if (downloading.Downloading.DownloadedFiles.Contains(key) && File.Exists(Path.Combine(path, fileName)))
- return Path.Combine(path, fileName);
+ }
+
if (downloading.Downloading.DownloadFiles.ContainsKey(key))
{
// 如果存在,表示下载过,
// 则继续使用上次下载的文件名
fileName = downloading.Downloading.DownloadFiles[key];
+
+ // 还要检查一下文件有没有被人删掉,删掉的话重新下载
+ // 如果下载视频之后音频文件被人删了。此时gid还是视频的,会下错文件
+ if (downloading.Downloading.DownloadedFiles.Contains(key) && File.Exists(Path.Combine(path, fileName)))
+ {
+ return Path.Combine(path, fileName);
+ }
}
else
{
@@ -502,6 +510,9 @@ namespace DownKyi.Services.Download
///
private async Task DoWork()
{
+ // 上次循环时正在下载的数量
+ int lastDownloadingCount = 0;
+
while (true)
{
int maxDownloading = SettingsManager.GetInstance().GetAriaMaxConcurrentDownloads();
@@ -554,6 +565,13 @@ namespace DownKyi.Services.Download
break;
}
+ // 判断下载列表中的视频是否全部下载完成
+ if (lastDownloadingCount > 0 && downloadingList.Count == 0 && downloadedList.Count > 0)
+ {
+ AfterDownload();
+ }
+ lastDownloadingCount = downloadingList.Count;
+
// 降低CPU占用
await Task.Delay(500);
}
@@ -574,8 +592,11 @@ namespace DownKyi.Services.Download
private async Task SingleDownload(DownloadingItem downloading)
{
// 路径
+ downloading.DownloadBase.FilePath = downloading.DownloadBase.FilePath.Replace("\\", "/");
string[] temp = downloading.DownloadBase.FilePath.Split('/');
- string path = downloading.DownloadBase.FilePath.Replace(temp[temp.Length - 1], "");
+ //string path = downloading.DownloadBase.FilePath.Replace(temp[temp.Length - 1], "");
+ string path = downloading.DownloadBase.FilePath.TrimEnd(temp[temp.Length - 1].ToCharArray());
+
// 路径不存在则创建
if (!Directory.Exists(path))
{
@@ -815,6 +836,36 @@ namespace DownKyi.Services.Download
downloading.StartOrPause.Fill = DictionaryResource.GetColor("ColorPrimary");
}
+ ///
+ /// 下载完成后的操作
+ ///
+ private void AfterDownload()
+ {
+ AfterDownloadOperation operation = SettingsManager.GetInstance().GetAfterDownloadOperation();
+ switch (operation)
+ {
+ case AfterDownloadOperation.NONE:
+ // 没有操作
+ break;
+ case AfterDownloadOperation.OPEN_FOLDER:
+ // 打开文件夹
+ break;
+ case AfterDownloadOperation.CLOSE_APP:
+ // 关闭程序
+ App.PropertyChangeAsync(() =>
+ {
+ System.Windows.Application.Current.Shutdown();
+ });
+ break;
+ case AfterDownloadOperation.CLOSE_SYSTEM:
+ // 关机
+ System.Diagnostics.Process.Start("shutdown.exe", "-s");
+ break;
+ default:
+ break;
+ }
+ }
+
///
/// 获取图片的扩展名
///
@@ -973,10 +1024,10 @@ namespace DownKyi.Services.Download
{
//HttpProxy = $"http://{Settings.GetAriaHttpProxy()}:{Settings.GetAriaHttpProxyListenPort()}",
Dir = path,
- Out = localFileName
- //Header = $"cookie: {Login.GetLoginInfoCookiesString()}\nreferer: https://www.bilibili.com",
- //UseHead = "true",
- //UserAgent = Utils.GetUserAgent()
+ Out = localFileName,
+ Header = $"cookie: {LoginHelper.GetLoginInfoCookiesString()}\nreferer: https://www.bilibili.com",
+ UseHead = "true",
+ UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36",
};
// 如果设置了代理,则增加HttpProxy
diff --git a/DownKyi/Services/Download/DownloadStorageService.cs b/DownKyi/Services/Download/DownloadStorageService.cs
index d0bab9e..5421aa9 100644
--- a/DownKyi/Services/Download/DownloadStorageService.cs
+++ b/DownKyi/Services/Download/DownloadStorageService.cs
@@ -7,6 +7,16 @@ namespace DownKyi.Services.Download
{
public class DownloadStorageService
{
+ ~DownloadStorageService()
+ {
+ DownloadingDb downloadingDb = new DownloadingDb();
+ downloadingDb.Close();
+ DownloadedDb downloadedDb = new DownloadedDb();
+ downloadedDb.Close();
+ DownloadBaseDb downloadBaseDb = new DownloadBaseDb();
+ downloadBaseDb.Close();
+ }
+
#region 下载中数据
///
@@ -25,7 +35,7 @@ namespace DownKyi.Services.Download
{
downloadingDb.Insert(downloadingItem.DownloadBase.Uuid, downloadingItem.Downloading);
}
- downloadingDb.Close();
+ //downloadingDb.Close();
}
///
@@ -40,7 +50,7 @@ namespace DownKyi.Services.Download
DownloadingDb downloadingDb = new DownloadingDb();
downloadingDb.Delete(downloadingItem.DownloadBase.Uuid);
- downloadingDb.Close();
+ //downloadingDb.Close();
}
///
@@ -52,7 +62,7 @@ namespace DownKyi.Services.Download
// 从数据库获取数据
DownloadingDb downloadingDb = new DownloadingDb();
Dictionary dic = downloadingDb.QueryAll();
- downloadingDb.Close();
+ //downloadingDb.Close();
// 遍历
List list = new List();
@@ -66,6 +76,7 @@ namespace DownKyi.Services.Download
Downloading = downloading
};
+ if (downloadingItem.DownloadBase == null) { continue; }
list.Add(downloadingItem);
}
}
@@ -85,7 +96,7 @@ namespace DownKyi.Services.Download
DownloadingDb downloadingDb = new DownloadingDb();
downloadingDb.Update(downloadingItem.DownloadBase.Uuid, downloadingItem.Downloading);
- downloadingDb.Close();
+ //downloadingDb.Close();
}
#endregion
@@ -108,7 +119,7 @@ namespace DownKyi.Services.Download
{
downloadedDb.Insert(downloadedItem.DownloadBase.Uuid, downloadedItem.Downloaded);
}
- downloadedDb.Close();
+ //downloadedDb.Close();
}
///
@@ -123,7 +134,7 @@ namespace DownKyi.Services.Download
DownloadedDb downloadedDb = new DownloadedDb();
downloadedDb.Delete(downloadedItem.DownloadBase.Uuid);
- downloadedDb.Close();
+ //downloadedDb.Close();
}
///
@@ -135,7 +146,7 @@ namespace DownKyi.Services.Download
// 从数据库获取数据
DownloadedDb downloadedDb = new DownloadedDb();
Dictionary dic = downloadedDb.QueryAll();
- downloadedDb.Close();
+ //downloadedDb.Close();
// 遍历
List list = new List();
@@ -143,13 +154,14 @@ namespace DownKyi.Services.Download
{
if (item.Value is Downloaded downloaded)
{
- DownloadedItem downloadingItem = new DownloadedItem
+ DownloadedItem downloadedItem = new DownloadedItem
{
DownloadBase = GetDownloadBase(item.Key),
Downloaded = downloaded
};
- list.Add(downloadingItem);
+ if (downloadedItem.DownloadBase == null) { continue; }
+ list.Add(downloadedItem);
}
}
@@ -168,7 +180,7 @@ namespace DownKyi.Services.Download
DownloadedDb downloadedDb = new DownloadedDb();
downloadedDb.Update(downloadedItem.DownloadBase.Uuid, downloadedItem.Downloaded);
- downloadedDb.Close();
+ //downloadedDb.Close();
}
#endregion
@@ -189,7 +201,7 @@ namespace DownKyi.Services.Download
{
downloadBaseDb.Insert(downloadBase.Uuid, downloadBase);
}
- downloadBaseDb.Close();
+ //downloadBaseDb.Close();
}
///
@@ -200,7 +212,7 @@ namespace DownKyi.Services.Download
{
DownloadBaseDb downloadBaseDb = new DownloadBaseDb();
downloadBaseDb.Delete(uuid);
- downloadBaseDb.Close();
+ //downloadBaseDb.Close();
}
///
@@ -211,7 +223,7 @@ namespace DownKyi.Services.Download
{
DownloadBaseDb downloadBaseDb = new DownloadBaseDb();
object obj = downloadBaseDb.QueryById(uuid);
- downloadBaseDb.Close();
+ //downloadBaseDb.Close();
return obj is DownloadBase downloadBase ? downloadBase : null;
}
@@ -226,7 +238,7 @@ namespace DownKyi.Services.Download
DownloadBaseDb downloadBaseDb = new DownloadBaseDb();
downloadBaseDb.Update(downloadBase.Uuid, downloadBase);
- downloadBaseDb.Close();
+ //downloadBaseDb.Close();
}
#endregion
diff --git a/DownKyi/Services/IInfoService.cs b/DownKyi/Services/IInfoService.cs
index a882569..43bd09b 100644
--- a/DownKyi/Services/IInfoService.cs
+++ b/DownKyi/Services/IInfoService.cs
@@ -7,7 +7,7 @@ namespace DownKyi.Services
{
VideoInfoView GetVideoView();
- List GetVideoSections();
+ List GetVideoSections(bool noUgc);
List GetVideoPages();
diff --git a/DownKyi/Services/VideoInfoService.cs b/DownKyi/Services/VideoInfoService.cs
index bcb3561..ed9738b 100644
--- a/DownKyi/Services/VideoInfoService.cs
+++ b/DownKyi/Services/VideoInfoService.cs
@@ -2,6 +2,7 @@
using DownKyi.Core.BiliApi.Video;
using DownKyi.Core.BiliApi.Video.Models;
using DownKyi.Core.BiliApi.VideoStream;
+using DownKyi.Core.Settings;
using DownKyi.Core.Storage;
using DownKyi.Core.Utils;
using DownKyi.ViewModels.PageViewModels;
@@ -96,10 +97,12 @@ namespace DownKyi.Services
};
}
+ // 文件命名中的时间格式
+ string timeFormat = SettingsManager.GetInstance().GetFileNamePartTimeFormat();
// 视频发布时间
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
DateTime dateTime = startTime.AddSeconds(videoView.Pubdate);
- videoPage.PublishTime = dateTime.ToString("yyyy-MM-dd");
+ videoPage.PublishTime = dateTime.ToString(timeFormat);
videoPages.Add(videoPage);
}
@@ -111,15 +114,30 @@ namespace DownKyi.Services
/// 获取视频章节与剧集
///
///
- public List GetVideoSections()
+ public List GetVideoSections(bool noUgc = false)
{
if (videoView == null) { return null; }
+
+ List videoSections = new List();
+
+ // 不需要ugc内容
+ if (noUgc)
+ {
+ videoSections.Add(new VideoSection
+ {
+ Id = 0,
+ Title = "default",
+ IsSelected = true,
+ VideoPages = GetVideoPages()
+ });
+
+ return videoSections;
+ }
+
if (videoView.UgcSeason == null) { return null; }
if (videoView.UgcSeason.Sections == null) { return null; }
if (videoView.UgcSeason.Sections.Count == 0) { return null; }
- List videoSections = new List();
-
foreach (UgcSection section in videoView.UgcSeason.Sections)
{
List pages = new List();
@@ -151,10 +169,12 @@ namespace DownKyi.Services
};
}
+ // 文件命名中的时间格式
+ string timeFormat = SettingsManager.GetInstance().GetFileNamePartTimeFormat();
// 视频发布时间
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
DateTime dateTime = startTime.AddSeconds(videoView.Pubdate);
- page.PublishTime = dateTime.ToString("yyyy-MM-dd");
+ page.PublishTime = dateTime.ToString(timeFormat);
// 这里的发布时间有问题,
// 如果是合集,也会执行这里,
// 但是发布时间是入口视频的,不是所有视频的
diff --git a/DownKyi/Utils/WindowAdaptation.cs b/DownKyi/Utils/WindowAdaptation.cs
new file mode 100644
index 0000000..355be0d
--- /dev/null
+++ b/DownKyi/Utils/WindowAdaptation.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Drawing;
+using System.Windows;
+using System.Windows.Forms;
+using System.Windows.Interop;
+
+namespace DownKyi.Utils
+{
+ ///
+ /// 为窗口添加附加属性的辅助类
+ ///
+ /// https://www.cnblogs.com/kybs0/p/9834023.html
+ ///
+ public class WindowAdaptation
+ {
+ #region 窗口宽度比例
+ ///
+ /// 窗口宽度比例 单位:小数(0 - 1.0]
+ /// 窗口实际宽度=使用屏幕可显示区域(屏幕高度-任务栏高度)* 窗口宽度比例
+ ///
+ public static readonly DependencyProperty WidthByScreenRatioProperty = DependencyProperty.RegisterAttached(
+ "WidthByScreenRatio", typeof(double), typeof(WindowAdaptation), new PropertyMetadata(1.0, OnWidthByScreenRatioPropertyChanged));
+
+ private static void OnWidthByScreenRatioPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is Window window && e.NewValue is double widthByScreenRatio)
+ {
+ if (widthByScreenRatio <= 0 || widthByScreenRatio > 1)
+ {
+ throw new ArgumentException($"屏幕比例不支持{widthByScreenRatio}");
+ }
+
+ var screenDisplayArea = GetScreenSize(window);
+ var screenRatioWidth = screenDisplayArea.Width * widthByScreenRatio;
+
+ //if (!double.IsNaN(window.Width) && screenDisplayArea.Width > window.Width)
+ //{
+ // window.Width = window.Width;
+ //}
+ //else
+ //{
+ // window.Width = screenRatioWidth;
+ //}
+
+ if (!double.IsNaN(window.Width) && screenRatioWidth > window.Width)
+ {
+ window.Width = window.Width;
+ }
+ else if (!double.IsNaN(window.MinWidth) && screenRatioWidth < window.MinWidth)
+ {
+ window.Width = screenDisplayArea.Width;
+ }
+ else
+ {
+ window.Width = screenRatioWidth;
+ }
+ }
+ }
+
+ public static void SetWidthByScreenRatio(DependencyObject element, double value)
+ {
+ element.SetValue(WidthByScreenRatioProperty, value);
+ }
+
+ public static double GetWidthByScreenRatio(DependencyObject element)
+ {
+ return (double)element.GetValue(WidthByScreenRatioProperty);
+ }
+
+ #endregion
+
+ #region 窗口高度比例
+ ///
+ /// 窗口宽度比例 单位:小数(0 - 1.0]
+ /// 窗口实际宽度=使用屏幕可显示区域(屏幕高度-任务栏高度)* 窗口宽度比例
+ ///
+ public static readonly DependencyProperty HeightByScreenRatioProperty = DependencyProperty.RegisterAttached(
+ "HeightByScreenRatio", typeof(double), typeof(WindowAdaptation), new PropertyMetadata(1.0, OnHeightByScreenRatioPropertyChanged));
+
+ private static void OnHeightByScreenRatioPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is Window window && e.NewValue is double heightByScreenRatio)
+ {
+ if (heightByScreenRatio <= 0 || heightByScreenRatio > 1)
+ {
+ throw new ArgumentException($"屏幕比例不支持{heightByScreenRatio}");
+ }
+
+ var screenDisplayArea = GetScreenSize(window);
+ var screenRatioHeight = screenDisplayArea.Height * heightByScreenRatio;
+
+ if (!double.IsNaN(window.Height) && screenDisplayArea.Height > window.Height)
+ {
+ window.Height = window.Height;
+ }
+ else
+ {
+ window.Height = screenRatioHeight;
+ }
+
+ //if (!double.IsNaN(window.Height) && screenRatioHeight > window.Height)
+ //{
+ // window.Height = window.Height;
+ //}
+ //else if (!double.IsNaN(window.MinHeight) && screenRatioHeight < window.MinHeight)
+ //{
+ // window.Height = screenDisplayArea.Height;
+ //}
+ //else
+ //{
+ // window.Height = screenRatioHeight;
+ //}
+ }
+ }
+
+ public static void SetHeightByScreenRatio(DependencyObject element, double value)
+ {
+ element.SetValue(HeightByScreenRatioProperty, value);
+ }
+
+ public static double GetHeightByScreenRatio(DependencyObject element)
+ {
+ return (double)element.GetValue(HeightByScreenRatioProperty);
+ }
+
+ #endregion
+
+ const int DpiPercent = 96;
+ private static dynamic GetScreenSize(Window window)
+ {
+ var intPtr = new WindowInteropHelper(window).Handle;//获取当前窗口的句柄
+ var screen = Screen.FromHandle(intPtr);//获取当前屏幕
+ using (Graphics currentGraphics = Graphics.FromHwnd(intPtr))
+ {
+ //分别获取当前屏幕X/Y方向的DPI
+ double dpiXRatio = currentGraphics.DpiX / DpiPercent;
+ double dpiYRatio = currentGraphics.DpiY / DpiPercent;
+
+ var width = screen.WorkingArea.Width / dpiXRatio;
+ var height = screen.WorkingArea.Height / dpiYRatio;
+
+ return new { Width = width, Height = height };
+ }
+ }
+ }
+}
diff --git a/DownKyi/ViewModels/BaseViewModel.cs b/DownKyi/ViewModels/BaseViewModel.cs
index 54d623f..89d5852 100644
--- a/DownKyi/ViewModels/BaseViewModel.cs
+++ b/DownKyi/ViewModels/BaseViewModel.cs
@@ -1,6 +1,7 @@
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;
+using Prism.Services.Dialogs;
using System;
using System.Windows;
@@ -9,6 +10,7 @@ namespace DownKyi.ViewModels
public class BaseViewModel : BindableBase, INavigationAware
{
protected readonly IEventAggregator eventAggregator;
+ protected readonly IDialogService dialogService;
protected string ParentView = string.Empty;
public BaseViewModel(IEventAggregator eventAggregator)
@@ -16,6 +18,12 @@ namespace DownKyi.ViewModels
this.eventAggregator = eventAggregator;
}
+ public BaseViewModel(IEventAggregator eventAggregator, IDialogService dialogService)
+ {
+ this.eventAggregator = eventAggregator;
+ this.dialogService = dialogService;
+ }
+
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
diff --git a/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs b/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs
index 2da4b97..287d65b 100644
--- a/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs
+++ b/DownKyi/ViewModels/Dialogs/BaseDialogViewModel.cs
@@ -115,16 +115,16 @@ namespace DownKyi.ViewModels.Dialogs
public event Action RequestClose;
- public bool CanCloseDialog()
+ public virtual bool CanCloseDialog()
{
return true;
}
- public void OnDialogClosed()
+ public virtual void OnDialogClosed()
{
}
- public void OnDialogOpened(IDialogParameters parameters)
+ public virtual void OnDialogOpened(IDialogParameters parameters)
{
}
diff --git a/DownKyi/ViewModels/Dialogs/ViewAlertDialogViewModel.cs b/DownKyi/ViewModels/Dialogs/ViewAlertDialogViewModel.cs
new file mode 100644
index 0000000..4a61093
--- /dev/null
+++ b/DownKyi/ViewModels/Dialogs/ViewAlertDialogViewModel.cs
@@ -0,0 +1,65 @@
+using DownKyi.Images;
+using Prism.Commands;
+using Prism.Services.Dialogs;
+
+namespace DownKyi.ViewModels.Dialogs
+{
+ public class ViewAlertDialogViewModel : BaseDialogViewModel
+ {
+ public const string Tag = "DialogAlert";
+
+ #region 页面属性申明
+
+ private VectorImage image;
+ public VectorImage Image
+ {
+ get => image;
+ set => SetProperty(ref image, value);
+ }
+
+ private string message;
+ public string Message
+ {
+ get { return message; }
+ set { SetProperty(ref message, value); }
+ }
+
+ #endregion
+
+ public ViewAlertDialogViewModel()
+ {
+
+ }
+
+ #region 命令申明
+
+ // 确认事件
+ private DelegateCommand allowCommand;
+ public DelegateCommand AllowCommand => allowCommand ?? (allowCommand = new DelegateCommand(ExecuteAllowCommand));
+
+ ///
+ /// 确认事件
+ ///
+ private void ExecuteAllowCommand()
+ {
+ ButtonResult result = ButtonResult.OK;
+ RaiseRequestClose(new DialogResult(result));
+ }
+
+ #endregion
+
+ #region 接口实现
+
+ public override void OnDialogOpened(IDialogParameters parameters)
+ {
+ base.OnDialogOpened(parameters);
+
+ Image = parameters.GetValue("image");
+ Title = parameters.GetValue("title");
+ Message = parameters.GetValue("message");
+ }
+
+ #endregion
+
+ }
+}
diff --git a/DownKyi/ViewModels/Dialogs/ViewDownloadSetterViewModel.cs b/DownKyi/ViewModels/Dialogs/ViewDownloadSetterViewModel.cs
index c62b6aa..d806a42 100644
--- a/DownKyi/ViewModels/Dialogs/ViewDownloadSetterViewModel.cs
+++ b/DownKyi/ViewModels/Dialogs/ViewDownloadSetterViewModel.cs
@@ -1,4 +1,5 @@
using DownKyi.Core.Settings;
+using DownKyi.Core.Settings.Models;
using DownKyi.Core.Utils;
using DownKyi.Events;
using DownKyi.Images;
@@ -136,14 +137,23 @@ namespace DownKyi.ViewModels.Dialogs
FolderIcon = NormalIcon.Instance().Folder;
FolderIcon.Fill = DictionaryResource.GetColor("ColorPrimary");
- DownloadAll = true;
- DownloadAudio = true;
- DownloadVideo = true;
- DownloadDanmaku = true;
- DownloadSubtitle = true;
- DownloadCover = true;
+ // 下载内容
+ VideoContentSettings videoContent = SettingsManager.GetInstance().GetVideoContent();
- #endregion
+ DownloadAudio = videoContent.DownloadAudio;
+ DownloadVideo = videoContent.DownloadVideo;
+ DownloadDanmaku = videoContent.DownloadDanmaku;
+ DownloadSubtitle = videoContent.DownloadSubtitle;
+ DownloadCover = videoContent.DownloadCover;
+
+ if (DownloadAudio && DownloadVideo && DownloadDanmaku && DownloadSubtitle && DownloadCover)
+ {
+ DownloadAll = true;
+ }
+ else
+ {
+ DownloadAll = false;
+ }
// 历史下载目录
DirectoryList = SettingsManager.GetInstance().GetHistoryVideoRootPaths();
@@ -156,6 +166,9 @@ namespace DownKyi.ViewModels.Dialogs
// 是否使用默认下载目录
IsDefaultDownloadDirectory = SettingsManager.GetInstance().IsUseSaveVideoRootPath() == AllowStatus.YES;
+
+ #endregion
+
}
#region 命令申明
@@ -213,6 +226,8 @@ namespace DownKyi.ViewModels.Dialogs
DownloadSubtitle = false;
DownloadCover = false;
}
+
+ SetVideoContent();
}
// 音频选择事件
@@ -227,13 +242,14 @@ namespace DownKyi.ViewModels.Dialogs
if (!DownloadAudio)
{
DownloadAll = false;
- return;
}
if (DownloadAudio && DownloadVideo && DownloadDanmaku && DownloadSubtitle && DownloadCover)
{
DownloadAll = true;
}
+
+ SetVideoContent();
}
// 视频选择事件
@@ -248,13 +264,14 @@ namespace DownKyi.ViewModels.Dialogs
if (!DownloadVideo)
{
DownloadAll = false;
- return;
}
if (DownloadAudio && DownloadVideo && DownloadDanmaku && DownloadSubtitle && DownloadCover)
{
DownloadAll = true;
}
+
+ SetVideoContent();
}
// 弹幕选择事件
@@ -269,13 +286,14 @@ namespace DownKyi.ViewModels.Dialogs
if (!DownloadDanmaku)
{
DownloadAll = false;
- return;
}
if (DownloadAudio && DownloadVideo && DownloadDanmaku && DownloadSubtitle && DownloadCover)
{
DownloadAll = true;
}
+
+ SetVideoContent();
}
// 字幕选择事件
@@ -290,13 +308,14 @@ namespace DownKyi.ViewModels.Dialogs
if (!DownloadSubtitle)
{
DownloadAll = false;
- return;
}
if (DownloadAudio && DownloadVideo && DownloadDanmaku && DownloadSubtitle && DownloadCover)
{
DownloadAll = true;
}
+
+ SetVideoContent();
}
// 封面选择事件
@@ -311,13 +330,14 @@ namespace DownKyi.ViewModels.Dialogs
if (!DownloadCover)
{
DownloadAll = false;
- return;
}
if (DownloadAudio && DownloadVideo && DownloadDanmaku && DownloadSubtitle && DownloadCover)
{
DownloadAll = true;
}
+
+ SetVideoContent();
}
// 确认下载事件
@@ -370,6 +390,23 @@ namespace DownKyi.ViewModels.Dialogs
#endregion
+ ///
+ /// 保存下载视频内容到设置
+ ///
+ private void SetVideoContent()
+ {
+ VideoContentSettings videoContent = new VideoContentSettings
+ {
+ DownloadAudio = DownloadAudio,
+ DownloadVideo = DownloadVideo,
+ DownloadDanmaku = DownloadDanmaku,
+ DownloadSubtitle = DownloadSubtitle,
+ DownloadCover = DownloadCover
+ };
+
+ SettingsManager.GetInstance().SetVideoContent(videoContent);
+ }
+
///
/// 设置下载路径
///
diff --git a/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs b/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs
index 4586b8a..d1f1b30 100644
--- a/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs
+++ b/DownKyi/ViewModels/DownloadManager/DownloadBaseItem.cs
@@ -2,6 +2,7 @@
using DownKyi.Core.BiliApi.Zone;
using DownKyi.Models;
using Prism.Mvvm;
+using Prism.Services.Dialogs;
using System.Windows;
using System.Windows.Media;
@@ -9,6 +10,18 @@ namespace DownKyi.ViewModels.DownloadManager
{
public class DownloadBaseItem : BindableBase
{
+ public IDialogService DialogService;
+
+ public DownloadBaseItem()
+ {
+ DialogService = null;
+ }
+
+ public DownloadBaseItem(IDialogService dialogService)
+ {
+ DialogService = dialogService;
+ }
+
// model数据
private DownloadBase downloadBase;
public DownloadBase DownloadBase
diff --git a/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs b/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs
index 15fd55f..8bb6518 100644
--- a/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs
+++ b/DownKyi/ViewModels/DownloadManager/DownloadedItem.cs
@@ -1,14 +1,20 @@
using DownKyi.Images;
using DownKyi.Models;
+using DownKyi.Services;
using DownKyi.Utils;
using Prism.Commands;
+using Prism.Services.Dialogs;
using System.IO;
namespace DownKyi.ViewModels.DownloadManager
{
public class DownloadedItem : DownloadBaseItem
{
- public DownloadedItem() : base()
+ public DownloadedItem() : this(null)
+ {
+ }
+
+ public DownloadedItem(IDialogService dialogService) : base(dialogService)
{
// 打开文件夹按钮
OpenFolder = ButtonIcon.Instance().Folder;
@@ -131,6 +137,13 @@ namespace DownKyi.ViewModels.DownloadManager
///
private void ExecuteRemoveVideoCommand()
{
+ AlertService alertService = new AlertService(DialogService);
+ ButtonResult result = alertService.ShowWarning(DictionaryResource.GetString("ConfirmDelete"));
+ if (result != ButtonResult.OK)
+ {
+ return;
+ }
+
App.DownloadedList.Remove(this);
}
diff --git a/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs b/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs
index dc51226..0f090eb 100644
--- a/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs
+++ b/DownKyi/ViewModels/DownloadManager/DownloadingItem.cs
@@ -1,14 +1,20 @@
using DownKyi.Core.BiliApi.VideoStream.Models;
using DownKyi.Images;
using DownKyi.Models;
+using DownKyi.Services;
using DownKyi.Utils;
using Prism.Commands;
+using Prism.Services.Dialogs;
namespace DownKyi.ViewModels.DownloadManager
{
public class DownloadingItem : DownloadBaseItem
{
- public DownloadingItem() : base()
+ public DownloadingItem() : this(null)
+ {
+ }
+
+ public DownloadingItem(IDialogService dialogService) : base(dialogService)
{
// 暂停继续按钮
StartOrPause = ButtonIcon.Instance().Pause;
@@ -211,6 +217,13 @@ namespace DownKyi.ViewModels.DownloadManager
///
private void ExecuteDeleteCommand()
{
+ AlertService alertService = new AlertService(DialogService);
+ ButtonResult result = alertService.ShowWarning(DictionaryResource.GetString("ConfirmDelete"));
+ if (result != ButtonResult.OK)
+ {
+ return;
+ }
+
App.DownloadingList.Remove(this);
}
diff --git a/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs b/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs
index c4d94a1..9a081c3 100644
--- a/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs
+++ b/DownKyi/ViewModels/DownloadManager/ViewDownloadFinishedViewModel.cs
@@ -1,9 +1,14 @@
using DownKyi.Core.Settings;
+using DownKyi.Services;
+using DownKyi.Utils;
using Prism.Commands;
using Prism.Events;
+using Prism.Regions;
+using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
@@ -31,10 +36,27 @@ namespace DownKyi.ViewModels.DownloadManager
#endregion
- public ViewDownloadFinishedViewModel(IEventAggregator eventAggregator) : base(eventAggregator)
+ public ViewDownloadFinishedViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator, dialogService)
{
// 初始化DownloadedList
DownloadedList = App.DownloadedList;
+ DownloadedList.CollectionChanged += new NotifyCollectionChangedEventHandler(async (object sender, NotifyCollectionChangedEventArgs e) =>
+ {
+ await Task.Run(() =>
+ {
+ if (e.Action == NotifyCollectionChangedAction.Add)
+ {
+ foreach (var item in DownloadedList)
+ {
+ if (item != null && item.DialogService == null)
+ {
+ item.DialogService = dialogService;
+ }
+ }
+ }
+ });
+ });
+ SetDialogService();
DownloadFinishedSort finishedSort = SettingsManager.GetInstance().GetDownloadFinishedSort();
switch (finishedSort)
@@ -95,6 +117,13 @@ namespace DownKyi.ViewModels.DownloadManager
///
private async void ExecuteClearAllDownloadedCommand()
{
+ AlertService alertService = new AlertService(dialogService);
+ ButtonResult result = alertService.ShowWarning(DictionaryResource.GetString("ConfirmDelete"));
+ if (result != ButtonResult.OK)
+ {
+ return;
+ }
+
// 使用Clear()不能触发NotifyCollectionChangedAction.Remove事件
// 因此遍历删除
// DownloadingList中元素被删除后不能继续遍历
@@ -113,5 +142,26 @@ namespace DownKyi.ViewModels.DownloadManager
#endregion
+ private async void SetDialogService()
+ {
+ await Task.Run(() =>
+ {
+ foreach (var item in DownloadedList)
+ {
+ if (item != null && item.DialogService == null)
+ {
+ item.DialogService = dialogService;
+ }
+ }
+ });
+ }
+
+ public override void OnNavigatedFrom(NavigationContext navigationContext)
+ {
+ base.OnNavigatedFrom(navigationContext);
+
+ SetDialogService();
+ }
+
}
}
diff --git a/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs b/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs
index a30c30b..aade091 100644
--- a/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs
+++ b/DownKyi/ViewModels/DownloadManager/ViewDownloadingViewModel.cs
@@ -1,11 +1,15 @@
using DownKyi.Images;
using DownKyi.Models;
+using DownKyi.Services;
using DownKyi.Utils;
using Prism.Commands;
using Prism.Events;
+using Prism.Regions;
+using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
@@ -26,10 +30,28 @@ namespace DownKyi.ViewModels.DownloadManager
#endregion
- public ViewDownloadingViewModel(IEventAggregator eventAggregator) : base(eventAggregator)
+ public ViewDownloadingViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator, dialogService)
{
// 初始化DownloadingList
DownloadingList = App.DownloadingList;
+ DownloadingList.CollectionChanged += new NotifyCollectionChangedEventHandler(async (object sender, NotifyCollectionChangedEventArgs e) =>
+ {
+ await Task.Run(() =>
+ {
+ if (e.Action == NotifyCollectionChangedAction.Add)
+ {
+ foreach (var item in DownloadingList)
+ {
+ if (item != null && item.DialogService == null)
+ {
+ item.DialogService = dialogService;
+ }
+ }
+ }
+ });
+ });
+ SetDialogService();
+
}
#region 命令申明
@@ -133,6 +155,13 @@ namespace DownKyi.ViewModels.DownloadManager
///
private async void ExecuteDeleteAllDownloadingCommand()
{
+ AlertService alertService = new AlertService(dialogService);
+ ButtonResult result = alertService.ShowWarning(DictionaryResource.GetString("ConfirmDelete"));
+ if (result != ButtonResult.OK)
+ {
+ return;
+ }
+
// 使用Clear()不能触发NotifyCollectionChangedAction.Remove事件
// 因此遍历删除
// DownloadingList中元素被删除后不能继续遍历
@@ -151,5 +180,26 @@ namespace DownKyi.ViewModels.DownloadManager
#endregion
+ private async void SetDialogService()
+ {
+ await Task.Run(() =>
+ {
+ foreach (var item in DownloadingList)
+ {
+ if (item != null && item.DialogService == null)
+ {
+ item.DialogService = dialogService;
+ }
+ }
+ });
+ }
+
+ public override void OnNavigatedFrom(NavigationContext navigationContext)
+ {
+ base.OnNavigatedFrom(navigationContext);
+
+ SetDialogService();
+ }
+
}
}
diff --git a/DownKyi/ViewModels/MainWindowViewModel.cs b/DownKyi/ViewModels/MainWindowViewModel.cs
index c806981..47714da 100644
--- a/DownKyi/ViewModels/MainWindowViewModel.cs
+++ b/DownKyi/ViewModels/MainWindowViewModel.cs
@@ -354,7 +354,7 @@ namespace DownKyi.ViewModels
}
SearchService searchService = new SearchService();
- searchService.BiliInput(input, ViewIndexViewModel.Tag, eventAggregator);
+ searchService.BiliInput(input + AppConstant.ClipboardId, ViewIndexViewModel.Tag, eventAggregator);
}
#endregion
diff --git a/DownKyi/ViewModels/PageViewModels/VideoPage.cs b/DownKyi/ViewModels/PageViewModels/VideoPage.cs
index b7660d0..f04787b 100644
--- a/DownKyi/ViewModels/PageViewModels/VideoPage.cs
+++ b/DownKyi/ViewModels/PageViewModels/VideoPage.cs
@@ -104,7 +104,7 @@ namespace DownKyi.ViewModels.PageViewModels
LogManager.Error("ExecuteVideoQualitySelectedCommand", e);
}
- if (VideoQuality != null && VideoQuality.Quality == 126)
+ if (VideoQuality != null && VideoQuality.Quality == 126 && PlayUrl != null && PlayUrl.Dash != null && PlayUrl.Dash.Dolby != null)
{
ListHelper.AddUnique(AudioQualityFormatList, dolby);
AudioQualityFormat = dolby;
diff --git a/DownKyi/ViewModels/Settings/ViewBasicViewModel.cs b/DownKyi/ViewModels/Settings/ViewBasicViewModel.cs
index 032e02e..eee40ca 100644
--- a/DownKyi/ViewModels/Settings/ViewBasicViewModel.cs
+++ b/DownKyi/ViewModels/Settings/ViewBasicViewModel.cs
@@ -67,6 +67,13 @@ namespace DownKyi.ViewModels.Settings
set { SetProperty(ref selectedParseScope, value); }
}
+ private bool autoDownloadAll;
+ public bool AutoDownloadAll
+ {
+ get => autoDownloadAll;
+ set => SetProperty(ref autoDownloadAll, value);
+ }
+
#endregion
public ViewBasicViewModel(IEventAggregator eventAggregator) : base(eventAggregator)
@@ -77,10 +84,10 @@ namespace DownKyi.ViewModels.Settings
// 解析范围
ParseScopes = new List()
{
- new ParseScopeDisplay{ Name =DictionaryResource.GetString("ParseNone"),ParseScope=ParseScope.NONE},
- new ParseScopeDisplay{ Name =DictionaryResource.GetString("ParseSelectedItem"),ParseScope=ParseScope.SELECTED_ITEM},
- new ParseScopeDisplay{ Name =DictionaryResource.GetString("ParseCurrentSection"),ParseScope=ParseScope.CURRENT_SECTION},
- new ParseScopeDisplay{ Name =DictionaryResource.GetString("ParseAll"),ParseScope=ParseScope.ALL}
+ new ParseScopeDisplay{ Name = DictionaryResource.GetString("ParseNone"), ParseScope = ParseScope.NONE },
+ new ParseScopeDisplay{ Name = DictionaryResource.GetString("ParseSelectedItem"), ParseScope = ParseScope.SELECTED_ITEM },
+ new ParseScopeDisplay{ Name = DictionaryResource.GetString("ParseCurrentSection"), ParseScope = ParseScope.CURRENT_SECTION },
+ new ParseScopeDisplay{ Name = DictionaryResource.GetString("ParseAll"), ParseScope = ParseScope.ALL }
};
#endregion
@@ -113,6 +120,10 @@ namespace DownKyi.ViewModels.Settings
ParseScope parseScope = SettingsManager.GetInstance().GetParseScope();
SelectedParseScope = ParseScopes.FirstOrDefault(t => { return t.ParseScope == parseScope; });
+ // 解析后是否自动下载解析视频
+ AllowStatus isAutoDownloadAll = SettingsManager.GetInstance().IsAutoDownloadAll();
+ AutoDownloadAll = isAutoDownloadAll == AllowStatus.YES;
+
isOnNavigatedTo = false;
}
@@ -193,6 +204,21 @@ namespace DownKyi.ViewModels.Settings
PublishTip(isSucceed);
}
+ // 解析后是否自动下载解析视频
+ private DelegateCommand autoDownloadAllCommand;
+ public DelegateCommand AutoDownloadAllCommand => autoDownloadAllCommand ?? (autoDownloadAllCommand = new DelegateCommand(ExecuteAutoDownloadAllCommand));
+
+ ///
+ /// 解析后是否自动下载解析视频
+ ///
+ private void ExecuteAutoDownloadAllCommand()
+ {
+ AllowStatus isAutoDownloadAll = AutoDownloadAll ? AllowStatus.YES : AllowStatus.NO;
+
+ bool isSucceed = SettingsManager.GetInstance().IsAutoDownloadAll(isAutoDownloadAll);
+ PublishTip(isSucceed);
+ }
+
#endregion
///
diff --git a/DownKyi/ViewModels/Settings/ViewDanmakuViewModel.cs b/DownKyi/ViewModels/Settings/ViewDanmakuViewModel.cs
index c9fda5b..cdc557b 100644
--- a/DownKyi/ViewModels/Settings/ViewDanmakuViewModel.cs
+++ b/DownKyi/ViewModels/Settings/ViewDanmakuViewModel.cs
@@ -144,7 +144,7 @@ namespace DownKyi.ViewModels.Settings
// 弹幕字体
string danmakuFont = SettingsManager.GetInstance().GetDanmakuFontName();
- if (Fonts.Contains(danmakuFont))
+ if (danmakuFont != null && Fonts.Contains(danmakuFont))
{
// 只有系统中存在当前设置的字体,才能显示
SelectedFont = danmakuFont;
diff --git a/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs b/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs
index 002d20f..a7ffd52 100644
--- a/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs
+++ b/DownKyi/ViewModels/Settings/ViewVideoViewModel.cs
@@ -1,7 +1,9 @@
using DownKyi.Core.BiliApi.BiliUtils;
using DownKyi.Core.FileName;
using DownKyi.Core.Settings;
+using DownKyi.Core.Settings.Models;
using DownKyi.Events;
+using DownKyi.Models;
using DownKyi.Utils;
using Prism.Commands;
using Prism.Events;
@@ -9,6 +11,7 @@ using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Collections.Specialized;
using System.Linq;
namespace DownKyi.ViewModels.Settings
@@ -84,6 +87,48 @@ namespace DownKyi.ViewModels.Settings
set => SetProperty(ref saveVideoDirectory, value);
}
+ private bool downloadAll;
+ public bool DownloadAll
+ {
+ get { return downloadAll; }
+ set { SetProperty(ref downloadAll, value); }
+ }
+
+ private bool downloadAudio;
+ public bool DownloadAudio
+ {
+ get { return downloadAudio; }
+ set { SetProperty(ref downloadAudio, value); }
+ }
+
+ private bool downloadVideo;
+ public bool DownloadVideo
+ {
+ get { return downloadVideo; }
+ set { SetProperty(ref downloadVideo, value); }
+ }
+
+ private bool downloadDanmaku;
+ public bool DownloadDanmaku
+ {
+ get { return downloadDanmaku; }
+ set { SetProperty(ref downloadDanmaku, value); }
+ }
+
+ private bool downloadSubtitle;
+ public bool DownloadSubtitle
+ {
+ get { return downloadSubtitle; }
+ set { SetProperty(ref downloadSubtitle, value); }
+ }
+
+ private bool downloadCover;
+ public bool DownloadCover
+ {
+ get { return downloadCover; }
+ set { SetProperty(ref downloadCover, value); }
+ }
+
private ObservableCollection selectedFileName;
public ObservableCollection SelectedFileName
{
@@ -105,8 +150,35 @@ namespace DownKyi.ViewModels.Settings
set => SetProperty(ref selectedOptionalField, value);
}
- #endregion
+ private List fileNamePartTimeFormatList;
+ public List FileNamePartTimeFormatList
+ {
+ get => fileNamePartTimeFormatList;
+ set => SetProperty(ref fileNamePartTimeFormatList, value);
+ }
+
+ private string selectedFileNamePartTimeFormat;
+ public string SelectedFileNamePartTimeFormat
+ {
+ get => selectedFileNamePartTimeFormat;
+ set => SetProperty(ref selectedFileNamePartTimeFormat, value);
+ }
+
+ private List orderFormatList;
+ public List OrderFormatList
+ {
+ get => orderFormatList;
+ set => SetProperty(ref orderFormatList, value);
+ }
+
+ private OrderFormatDisplay orderFormatDisplay;
+ public OrderFormatDisplay OrderFormatDisplay
+ {
+ get => orderFormatDisplay;
+ set => SetProperty(ref orderFormatDisplay, value);
+ }
+ #endregion
public ViewVideoViewModel(IEventAggregator eventAggregator) : base(eventAggregator)
{
@@ -129,6 +201,20 @@ namespace DownKyi.ViewModels.Settings
// 文件命名格式
SelectedFileName = new ObservableCollection();
+
+ SelectedFileName.CollectionChanged += new NotifyCollectionChangedEventHandler((sender, e) =>
+ {
+ // 当前显示的命名格式part
+ List fileName = new List();
+ foreach (DisplayFileNamePart item in SelectedFileName)
+ {
+ fileName.Add(item.Id);
+ }
+
+ bool isSucceed = SettingsManager.GetInstance().SetFileNameParts(fileName);
+ PublishTip(isSucceed);
+ });
+
OptionalFields = new ObservableCollection();
foreach (FileNamePart item in Enum.GetValues(typeof(FileNamePart)))
{
@@ -138,6 +224,20 @@ namespace DownKyi.ViewModels.Settings
SelectedOptionalField = -1;
+ // 文件命名中的时间格式
+ FileNamePartTimeFormatList = new List
+ {
+ "yyyy-MM-dd",
+ "yyyy.MM.dd",
+ };
+
+ // 文件命名中的序号格式
+ OrderFormatList = new List
+ {
+ new OrderFormatDisplay{ Name = DictionaryResource.GetString("OrderFormatNatural"), OrderFormat = OrderFormat.NATURAL },
+ new OrderFormatDisplay{ Name = DictionaryResource.GetString("OrderFormatLeadingZeros"), OrderFormat = OrderFormat.LEADING_ZEROS },
+ };
+
#endregion
}
@@ -175,6 +275,24 @@ namespace DownKyi.ViewModels.Settings
// 默认下载目录
SaveVideoDirectory = SettingsManager.GetInstance().GetSaveVideoRootPath();
+ // 下载内容
+ VideoContentSettings videoContent = SettingsManager.GetInstance().GetVideoContent();
+
+ DownloadAudio = videoContent.DownloadAudio;
+ DownloadVideo = videoContent.DownloadVideo;
+ DownloadDanmaku = videoContent.DownloadDanmaku;
+ DownloadSubtitle = videoContent.DownloadSubtitle;
+ DownloadCover = videoContent.DownloadCover;
+
+ if (DownloadAudio && DownloadVideo && DownloadDanmaku && DownloadSubtitle && DownloadCover)
+ {
+ DownloadAll = true;
+ }
+ else
+ {
+ DownloadAll = false;
+ }
+
// 文件命名格式
List fileNameParts = SettingsManager.GetInstance().GetFileNameParts();
SelectedFileName.Clear();
@@ -184,6 +302,13 @@ namespace DownKyi.ViewModels.Settings
SelectedFileName.Add(new DisplayFileNamePart { Id = item, Title = display });
}
+ // 文件命名中的时间格式
+ SelectedFileNamePartTimeFormat = SettingsManager.GetInstance().GetFileNamePartTimeFormat();
+
+ // 文件命名中的序号格式
+ OrderFormat orderFormat = SettingsManager.GetInstance().GetOrderFormat();
+ OrderFormatDisplay = OrderFormatList.FirstOrDefault(t => { return t.OrderFormat == orderFormat; });
+
isOnNavigatedTo = false;
}
@@ -288,16 +413,157 @@ namespace DownKyi.ViewModels.Settings
}
}
- // 选中文件名字段点击事件
- private DelegateCommand
private async void UpdateUserInfo()
{
- LoginPanelVisibility = Visibility.Hidden;
-
- // 检查本地是否存在login文件,没有则说明未登录
- if (!File.Exists(StorageManager.GetLogin()))
+ try
{
- LoginPanelVisibility = Visibility.Visible;
- Header = new BitmapImage(new Uri("pack://application:,,,/Resources/default_header.jpg"));
- UserName = null;
- return;
- }
+ LoginPanelVisibility = Visibility.Hidden;
- await Task.Run(new Action(() =>
- {
- // 获取用户信息
- var userInfo = UserInfo.GetUserInfoForNavigation();
- if (userInfo != null)
+ // 检查本地是否存在login文件,没有则说明未登录
+ if (!File.Exists(StorageManager.GetLogin()))
{
- SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings
- {
- Mid = userInfo.Mid,
- Name = userInfo.Name,
- IsLogin = userInfo.IsLogin,
- IsVip = userInfo.VipStatus == 1
- });
- }
- else
- {
- SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings
- {
- Mid = -1,
- Name = "",
- IsLogin = false,
- IsVip = false
- });
+ LoginPanelVisibility = Visibility.Visible;
+ Header = new BitmapImage(new Uri("pack://application:,,,/Resources/default_header.jpg"));
+ UserName = null;
+ return;
}
- PropertyChangeAsync(new Action(() =>
+ await Task.Run(new Action(() =>
{
- LoginPanelVisibility = Visibility.Visible;
-
+ // 获取用户信息
+ var userInfo = UserInfo.GetUserInfoForNavigation();
if (userInfo != null)
{
- if (userInfo.Face != null)
+ SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings
+ {
+ Mid = userInfo.Mid,
+ Name = userInfo.Name,
+ IsLogin = userInfo.IsLogin,
+ IsVip = userInfo.VipStatus == 1
+ });
+ }
+ else
+ {
+ SettingsManager.GetInstance().SetUserInfo(new UserInfoSettings
+ {
+ Mid = -1,
+ Name = "",
+ IsLogin = false,
+ IsVip = false
+ });
+ }
+
+ PropertyChangeAsync(new Action(() =>
+ {
+ LoginPanelVisibility = Visibility.Visible;
+
+ if (userInfo != null)
{
- Header = new StorageHeader().GetHeaderThumbnail(userInfo.Mid, userInfo.Name, userInfo.Face, 36, 36);
+ if (userInfo.Face != null)
+ {
+ Header = new StorageHeader().GetHeaderThumbnail(userInfo.Mid, userInfo.Name, userInfo.Face, 36, 36);
+ }
+ else
+ {
+ Header = new BitmapImage(new Uri("pack://application:,,,/Resources/default_header.jpg"));
+ }
+ UserName = userInfo.Name;
}
else
{
Header = new BitmapImage(new Uri("pack://application:,,,/Resources/default_header.jpg"));
+ UserName = null;
}
- UserName = userInfo.Name;
- }
- else
- {
- Header = new BitmapImage(new Uri("pack://application:,,,/Resources/default_header.jpg"));
- UserName = null;
- }
+ }));
}));
- }));
+ }
+ catch (Exception e)
+ {
+ Core.Utils.Debugging.Console.PrintLine("UpdateUserInfo()发生异常: {0}", e);
+ LogManager.Error(Tag, e);
+ }
}
#endregion
diff --git a/DownKyi/ViewModels/ViewLoginViewModel.cs b/DownKyi/ViewModels/ViewLoginViewModel.cs
index 6767e83..4b89904 100644
--- a/DownKyi/ViewModels/ViewLoginViewModel.cs
+++ b/DownKyi/ViewModels/ViewLoginViewModel.cs
@@ -98,26 +98,34 @@ namespace DownKyi.ViewModels
///
private void Login()
{
- var loginUrl = LoginQR.GetLoginUrl();
- if (loginUrl == null) { return; }
-
- if (loginUrl.Status != true)
+ try
{
- ExecuteBackSpace();
- return;
- }
+ var loginUrl = LoginQR.GetLoginUrl();
+ if (loginUrl == null) { return; }
- if (loginUrl.Data == null || loginUrl.Data.Url == null)
- {
- eventAggregator.GetEvent().Publish(DictionaryResource.GetString("GetLoginUrlFailed"));
- return;
- }
+ if (loginUrl.Status != true)
+ {
+ ExecuteBackSpace();
+ return;
+ }
- PropertyChangeAsync(new Action(() => { LoginQRCode = LoginQR.GetLoginQRCode(loginUrl.Data.Url); }));
- Core.Utils.Debugging.Console.PrintLine(loginUrl.Data.Url + "\n");
- LogManager.Debug(Tag, loginUrl.Data.Url);
+ if (loginUrl.Data == null || loginUrl.Data.Url == null)
+ {
+ eventAggregator.GetEvent().Publish(DictionaryResource.GetString("GetLoginUrlFailed"));
+ return;
+ }
+
+ PropertyChangeAsync(new Action(() => { LoginQRCode = LoginQR.GetLoginQRCode(loginUrl.Data.Url); }));
+ Core.Utils.Debugging.Console.PrintLine(loginUrl.Data.Url + "\n");
+ LogManager.Debug(Tag, loginUrl.Data.Url);
- GetLoginStatus(loginUrl.Data.OauthKey);
+ GetLoginStatus(loginUrl.Data.OauthKey);
+ }
+ catch (Exception e)
+ {
+ Core.Utils.Debugging.Console.PrintLine("Login()发生异常: {0}", e);
+ LogManager.Error(Tag, e);
+ }
}
///
diff --git a/DownKyi/ViewModels/ViewVideoDetailViewModel.cs b/DownKyi/ViewModels/ViewVideoDetailViewModel.cs
index 10b69c8..088a7ae 100644
--- a/DownKyi/ViewModels/ViewVideoDetailViewModel.cs
+++ b/DownKyi/ViewModels/ViewVideoDetailViewModel.cs
@@ -27,10 +27,8 @@ namespace DownKyi.ViewModels
{
public const string Tag = "PageVideoDetail";
- private readonly IDialogService dialogService;
-
// 保存输入字符串,避免被用户修改
- private string input;
+ private string input = null;
#region 页面属性申明
@@ -106,10 +104,8 @@ namespace DownKyi.ViewModels
#endregion
- public ViewVideoDetailViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator)
+ public ViewVideoDetailViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator, dialogService)
{
- this.dialogService = dialogService;
-
#region 属性初始化
// 初始化loading gif
@@ -480,6 +476,13 @@ namespace DownKyi.ViewModels
}
LoadingVisibility = Visibility.Collapsed;
+
+ // 解析后是否自动下载解析视频
+ AllowStatus isAutoDownloadAll = SettingsManager.GetInstance().IsAutoDownloadAll();
+ if (parseScope != ParseScope.NONE && isAutoDownloadAll == AllowStatus.YES)
+ {
+ AddToDownload(true);
+ }
}
///
@@ -498,56 +501,57 @@ namespace DownKyi.ViewModels
///
/// 添加到下载列表事件
///
- private async void ExecuteAddToDownloadCommand()
- {
- AddToDownloadService addToDownloadService = null;
- // 视频
- if (ParseEntrance.IsAvUrl(input) || ParseEntrance.IsBvUrl(input))
- {
- addToDownloadService = new AddToDownloadService(PlayStreamType.VIDEO);
- }
- // 番剧(电影、电视剧)
- else if (ParseEntrance.IsBangumiSeasonUrl(input) || ParseEntrance.IsBangumiEpisodeUrl(input) || ParseEntrance.IsBangumiMediaUrl(input))
- {
- addToDownloadService = new AddToDownloadService(PlayStreamType.BANGUMI);
- }
- // 课程
- else if (ParseEntrance.IsCheeseSeasonUrl(input) || ParseEntrance.IsCheeseEpisodeUrl(input))
- {
- addToDownloadService = new AddToDownloadService(PlayStreamType.CHEESE);
- }
- else
- {
- return;
- }
-
- // 选择文件夹
- string directory = addToDownloadService.SetDirectory(dialogService);
-
- // 视频计数
- int i = 0;
- await Task.Run(() =>
- {
- // 传递video对象
- addToDownloadService.GetVideo(VideoInfoView, VideoSections.ToList());
- // 下载
- i = addToDownloadService.AddToDownload(eventAggregator, directory);
- });
-
- if (directory == null)
- {
- return;
- }
-
- // 通知用户添加到下载列表的结果
- if (i <= 0)
- {
- eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipAddDownloadingZero"));
- }
- else
- {
- eventAggregator.GetEvent().Publish($"{DictionaryResource.GetString("TipAddDownloadingFinished1")}{i}{DictionaryResource.GetString("TipAddDownloadingFinished2")}");
- }
+ private void ExecuteAddToDownloadCommand()
+ {
+ AddToDownload(false);
+ //AddToDownloadService addToDownloadService = null;
+ //// 视频
+ //if (ParseEntrance.IsAvUrl(input) || ParseEntrance.IsBvUrl(input))
+ //{
+ // addToDownloadService = new AddToDownloadService(PlayStreamType.VIDEO);
+ //}
+ //// 番剧(电影、电视剧)
+ //else if (ParseEntrance.IsBangumiSeasonUrl(input) || ParseEntrance.IsBangumiEpisodeUrl(input) || ParseEntrance.IsBangumiMediaUrl(input))
+ //{
+ // addToDownloadService = new AddToDownloadService(PlayStreamType.BANGUMI);
+ //}
+ //// 课程
+ //else if (ParseEntrance.IsCheeseSeasonUrl(input) || ParseEntrance.IsCheeseEpisodeUrl(input))
+ //{
+ // addToDownloadService = new AddToDownloadService(PlayStreamType.CHEESE);
+ //}
+ //else
+ //{
+ // return;
+ //}
+
+ //// 选择文件夹
+ //string directory = addToDownloadService.SetDirectory(dialogService);
+
+ //// 视频计数
+ //int i = 0;
+ //await Task.Run(() =>
+ //{
+ // // 传递video对象
+ // addToDownloadService.GetVideo(VideoInfoView, VideoSections.ToList());
+ // // 下载
+ // i = addToDownloadService.AddToDownload(eventAggregator, directory);
+ //});
+
+ //if (directory == null)
+ //{
+ // return;
+ //}
+
+ //// 通知用户添加到下载列表的结果
+ //if (i <= 0)
+ //{
+ // eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipAddDownloadingZero"));
+ //}
+ //else
+ //{
+ // eventAggregator.GetEvent().Publish($"{DictionaryResource.GetString("TipAddDownloadingFinished1")}{i}{DictionaryResource.GetString("TipAddDownloadingFinished2")}");
+ //}
}
///
@@ -610,6 +614,7 @@ namespace DownKyi.ViewModels
///
private void UpdateView(IInfoService videoInfoService, VideoPage param)
{
+ // 获取视频详情
VideoInfoView = videoInfoService.GetVideoView();
if (VideoInfoView == null)
{
@@ -627,7 +632,16 @@ namespace DownKyi.ViewModels
NoDataVisibility = Visibility.Collapsed;
}
- List videoSections = videoInfoService.GetVideoSections();
+ // 获取视频列表
+ List videoSections = videoInfoService.GetVideoSections(false);
+
+ // 清空以前的数据
+ PropertyChangeAsync(new Action(() =>
+ {
+ VideoSections.Clear();
+ }));
+
+ // 添加新数据
if (videoSections == null)
{
LogManager.Debug(Tag, "videoSections is not exist.");
@@ -663,6 +677,62 @@ namespace DownKyi.ViewModels
videoInfoService.GetVideoStream(videoPage);
}
+ ///
+ /// 添加到下载列表事件
+ ///
+ /// 是否下载所有,包括未选中项
+ private async void AddToDownload(bool isAll)
+ {
+ AddToDownloadService addToDownloadService = null;
+ // 视频
+ if (ParseEntrance.IsAvUrl(input) || ParseEntrance.IsBvUrl(input))
+ {
+ addToDownloadService = new AddToDownloadService(PlayStreamType.VIDEO);
+ }
+ // 番剧(电影、电视剧)
+ else if (ParseEntrance.IsBangumiSeasonUrl(input) || ParseEntrance.IsBangumiEpisodeUrl(input) || ParseEntrance.IsBangumiMediaUrl(input))
+ {
+ addToDownloadService = new AddToDownloadService(PlayStreamType.BANGUMI);
+ }
+ // 课程
+ else if (ParseEntrance.IsCheeseSeasonUrl(input) || ParseEntrance.IsCheeseEpisodeUrl(input))
+ {
+ addToDownloadService = new AddToDownloadService(PlayStreamType.CHEESE);
+ }
+ else
+ {
+ return;
+ }
+
+ // 选择文件夹
+ string directory = addToDownloadService.SetDirectory(dialogService);
+
+ // 视频计数
+ int i = 0;
+ await Task.Run(() =>
+ {
+ // 传递video对象
+ addToDownloadService.GetVideo(VideoInfoView, VideoSections.ToList());
+ // 下载
+ i = addToDownloadService.AddToDownload(eventAggregator, directory, isAll);
+ });
+
+ if (directory == null)
+ {
+ return;
+ }
+
+ // 通知用户添加到下载列表的结果
+ if (i <= 0)
+ {
+ eventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipAddDownloadingZero"));
+ }
+ else
+ {
+ eventAggregator.GetEvent().Publish($"{DictionaryResource.GetString("TipAddDownloadingFinished1")}{i}{DictionaryResource.GetString("TipAddDownloadingFinished2")}");
+ }
+ }
+
#endregion
///
@@ -671,8 +741,6 @@ namespace DownKyi.ViewModels
///
public override void OnNavigatedTo(NavigationContext navigationContext)
{
- base.OnNavigatedTo(navigationContext);
-
ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark");
DownloadManage = ButtonIcon.Instance().DownloadManage;
@@ -683,13 +751,25 @@ namespace DownKyi.ViewModels
// Parent参数为null时,表示是从下一个页面返回到本页面,不需要执行任务
if (navigationContext.Parameters.GetValue("Parent") != null)
{
+ string param = navigationContext.Parameters.GetValue("Parameter");
+ // 移除剪贴板id
+ string intput = param.Replace(AppConstant.ClipboardId, "");
+
+ // 检测是否从剪贴板传入
+ if (InputText == intput && param.EndsWith(AppConstant.ClipboardId))
+ {
+ return;
+ }
+
// 正在执行任务时不开启新任务
if (LoadingVisibility != Visibility.Visible)
{
- InputText = navigationContext.Parameters.GetValue("Parameter");
+ InputText = intput;
PropertyChangeAsync(ExecuteInputCommand);
}
}
+
+ base.OnNavigatedTo(navigationContext);
}
}
diff --git a/DownKyi/Views/Dialogs/ViewAlertDialog.xaml b/DownKyi/Views/Dialogs/ViewAlertDialog.xaml
new file mode 100644
index 0000000..16de4ef
--- /dev/null
+++ b/DownKyi/Views/Dialogs/ViewAlertDialog.xaml
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DownKyi/Views/Dialogs/ViewAlertDialog.xaml.cs b/DownKyi/Views/Dialogs/ViewAlertDialog.xaml.cs
new file mode 100644
index 0000000..1bcd2ab
--- /dev/null
+++ b/DownKyi/Views/Dialogs/ViewAlertDialog.xaml.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace DownKyi.Views.Dialogs
+{
+ ///
+ /// ViewAlertDialog.xaml 的交互逻辑
+ ///
+ public partial class ViewAlertDialog : UserControl
+ {
+ public ViewAlertDialog()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/DownKyi/Views/Dialogs/ViewDownloadSetter.xaml b/DownKyi/Views/Dialogs/ViewDownloadSetter.xaml
index f354ee8..e612b8e 100644
--- a/DownKyi/Views/Dialogs/ViewDownloadSetter.xaml
+++ b/DownKyi/Views/Dialogs/ViewDownloadSetter.xaml
@@ -24,7 +24,7 @@