├── .gitattributes
├── .gitignore
├── Nandaka.Common
├── ExtendedWebClient.cs
├── GenericEqualityComparer.cs
├── LimitedConcurrencyLevelTaskScheduler .cs
├── ListStringConverter.cs
├── Nandaka.Common.csproj
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── SecureIt.cs
├── Util.cs
├── WPF
│ └── ZoomBorder.cs
├── WebImgConverter.cs
└── app.config
├── Nijie.Test
├── App.config
├── Nijie.Test.csproj
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── UnitTest1.cs
├── UpdateHtmlForm.Designer.cs
├── UpdateHtmlForm.cs
├── UpdateHtmlForm.resx
├── packages.config
└── testpage
│ ├── image-doujin-popup.html
│ ├── image-doujin.html
│ ├── image-manga-filter.html
│ ├── image-manga-popup-filter.html
│ ├── image-manga-popup.html
│ ├── image-manga.html
│ ├── image-normal.html
│ ├── image-video-popup.html
│ ├── image-video.html
│ ├── image.html
│ ├── index.html
│ ├── member-bookmarked-images-lastpage.html
│ ├── member-bookmarked-images.html
│ ├── member-doujins.html
│ ├── member-images.html
│ ├── search-tag-exact-latest-lastpage.html
│ ├── search-tag-exact-latest.html
│ ├── search-tag-partial-latest-lastpage.html
│ └── search-tag-partial-latest.html
├── NijieDownloader.Library
├── App.config
├── DAL
│ └── NijieContext.cs
├── Migrations
│ ├── 201402201406506_InitialCreate.Designer.cs
│ ├── 201402201406506_InitialCreate.cs
│ ├── 201402201406506_InitialCreate.resx
│ ├── 201403061411087_AddNijieTags.Designer.cs
│ ├── 201403061411087_AddNijieTags.cs
│ ├── 201403061411087_AddNijieTags.resx
│ ├── 201404021353243_1.0.3.1.Designer.cs
│ ├── 201404021353243_1.0.3.1.cs
│ ├── 201404021353243_1.0.3.1.resx
│ └── Configuration.cs
├── Model
│ ├── NijieImage.cs
│ ├── NijieLoginInfo.cs
│ ├── NijieMangaInfo.cs
│ ├── NijieMember.cs
│ ├── NijieSearch.cs
│ ├── NijieSearchOption.cs
│ └── NijieTag.cs
├── Nijie.Bookmark.cs
├── Nijie.Image.cs
├── Nijie.Login.cs
├── Nijie.Member.cs
├── Nijie.Search.cs
├── Nijie.cs
├── NijieConstants.cs
├── NijieDownloader.Library.csproj
├── NijieException.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Settings.Designer.cs
│ └── Settings.settings
└── packages.config
├── NijieDownloader.UI
├── App.xaml
├── App.xaml.cs
├── ImageLoader.cs
├── JobRunner.cs
├── JobStatusToVisibilityConverter.cs
├── JobTypeToVisibilityConverter.cs
├── Main
│ ├── BatchDownloadPage.xaml
│ ├── BatchDownloadPage.xaml.cs
│ ├── BookmarkPage.xaml
│ ├── BookmarkPage.xaml.cs
│ ├── ImagePage.xaml
│ ├── ImagePage.xaml.cs
│ ├── MemberPage.xaml
│ ├── MemberPage.xaml.cs
│ ├── Popup
│ │ ├── AddJobPopup.xaml
│ │ └── AddJobPopup.xaml.cs
│ ├── SearchPage.xaml
│ └── SearchPage.xaml.cs
├── MainWindow.UIHelper.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── NijieDownloader.UI.csproj
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── Resources
│ ├── donate.gif
│ ├── error_icon.png
│ ├── friends.png
│ ├── loading.png
│ ├── no_avatar.jpg
│ ├── queued.png
│ ├── thumbnail_anime.png
│ └── thumbnail_comic.png
├── Settings
│ ├── About.xaml
│ ├── About.xaml.cs
│ ├── Download.xaml
│ ├── Download.xaml.cs
│ ├── LoginInfo.xaml
│ ├── LoginInfo.xaml.cs
│ ├── Network.xaml
│ └── Network.xaml.cs
├── ViewModel
│ ├── JobDownloadViewModel.cs
│ ├── JobDownloadViewModelComparer.cs
│ ├── NijieImageViewModel.cs
│ ├── NijieMemberBookmarkViewModel.cs
│ ├── NijieMemberViewModel.cs
│ ├── NijieSearchViewModel.cs
│ ├── ViewModelBase.cs
│ └── ViewModelHelper.cs
├── app.config
├── nijie_icon.ico
└── packages.config
├── NijieDownloader.sln
├── NijieDownloader.vsmdi
├── README.txt
├── TestImage.txt
├── changelog.txt
└── packages
└── repositories.config
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
24 | Nijie.Test/testpage/*.htm linguist-vendored=False
25 | Nijie.Test/testpage/*.html linguist-vendored=False
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | packages/*
2 |
3 | #################
4 | ## Eclipse
5 | #################
6 |
7 | *.pydevproject
8 | .project
9 | .metadata
10 | bin/
11 | tmp/
12 | *.tmp
13 | *.bak
14 | *.swp
15 | *~.nib
16 | local.properties
17 | .classpath
18 | .settings/
19 | .loadpath
20 |
21 | # External tool builders
22 | .externalToolBuilders/
23 |
24 | # Locally stored "Eclipse launch configurations"
25 | *.launch
26 |
27 | # CDT-specific
28 | .cproject
29 |
30 | # PDT-specific
31 | .buildpath
32 |
33 |
34 | #################
35 | ## Visual Studio
36 | #################
37 |
38 | ## Ignore Visual Studio temporary files, build results, and
39 | ## files generated by popular Visual Studio add-ons.
40 |
41 | # User-specific files
42 | *.suo
43 | *.user
44 | *.sln.docstates
45 |
46 | # Build results
47 | [Dd]ebug/
48 | [Rr]elease/
49 | *_i.c
50 | *_p.c
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.vspscc
65 | .builds
66 | *.dotCover
67 |
68 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
69 | #packages/
70 |
71 | # Visual C++ cache files
72 | ipch/
73 | *.aps
74 | *.ncb
75 | *.opensdf
76 | *.sdf
77 |
78 | # Visual Studio profiler
79 | *.psess
80 | *.vsp
81 |
82 | # ReSharper is a .NET coding add-in
83 | _ReSharper*
84 |
85 | # Installshield output folder
86 | [Ee]xpress
87 |
88 | # DocProject is a documentation generator add-in
89 | DocProject/buildhelp/
90 | DocProject/Help/*.HxT
91 | DocProject/Help/*.HxC
92 | DocProject/Help/*.hhc
93 | DocProject/Help/*.hhk
94 | DocProject/Help/*.hhp
95 | DocProject/Help/Html2
96 | DocProject/Help/html
97 |
98 | # Click-Once directory
99 | publish
100 |
101 | # Others
102 | [Bb]in
103 | [Oo]bj
104 | sql
105 | TestResults
106 | *.Cache
107 | ClientBin
108 | stylecop.*
109 | ~$*
110 | *.dbmdl
111 | Generated_Code #added for RIA/Silverlight projects
112 |
113 | # Backup & report files from converting an old project file to a newer
114 | # Visual Studio version. Backup files are not needed, because we have git ;-)
115 | _UpgradeReport_Files/
116 | Backup*/
117 | UpgradeLog*.XML
118 |
119 |
120 |
121 | ############
122 | ## Windows
123 | ############
124 |
125 | # Windows image file caches
126 | Thumbs.db
127 |
128 | # Folder config file
129 | Desktop.ini
130 |
131 |
132 | #############
133 | ## Python
134 | #############
135 |
136 | *.py[co]
137 |
138 | # Packages
139 | *.egg
140 | *.egg-info
141 | dist
142 | build
143 | eggs
144 | parts
145 | bin
146 | var
147 | sdist
148 | develop-eggs
149 | .installed.cfg
150 |
151 | # Installer logs
152 | pip-log.txt
153 |
154 | # Unit test / coverage reports
155 | .coverage
156 | .tox
157 |
158 | #Translations
159 | *.mo
160 |
161 | #Mr Developer
162 | .mr.developer.cfg
163 |
164 | # Mac crap
165 | .DS_Store
166 | *.7z
167 | list.txt
168 | nijie_icon.ico
169 |
--------------------------------------------------------------------------------
/Nandaka.Common/GenericEqualityComparer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace Nandaka.Common
7 | {
8 | ///
9 | /// http://stackoverflow.com/a/10720211
10 | ///
11 | ///
12 | public class EqualityComparer : IEqualityComparer
13 | {
14 | public EqualityComparer(Func cmp)
15 | {
16 | this.cmp = cmp;
17 | }
18 | public bool Equals(T x, T y)
19 | {
20 | return cmp(x, y);
21 | }
22 |
23 | public int GetHashCode(T obj)
24 | {
25 | return obj.GetHashCode();
26 | }
27 |
28 | private Func cmp { get; set; }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Nandaka.Common/LimitedConcurrencyLevelTaskScheduler .cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace Nandaka.Common
9 | {
10 | ///
11 | /// Provides a task scheduler that ensures a maximum concurrency level while
12 | /// running on top of the thread pool.
13 | /// http://msdn.microsoft.com/en-us/library/ee789351(v=vs.110).aspx
14 | ///
15 | public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
16 | {
17 | // Indicates whether the current thread is processing work items.
18 | [ThreadStatic]
19 | private static bool _currentThreadIsProcessingItems;
20 |
21 | // The list of tasks to be executed
22 | private readonly LinkedList _tasks = new LinkedList(); // protected by lock(_tasks)
23 |
24 | // The maximum concurrency level allowed by this scheduler.
25 | private readonly int _maxDegreeOfParallelism;
26 |
27 | // Indicates whether the scheduler is currently processing work items.
28 | private int _delegatesQueuedOrRunning = 0;
29 |
30 | // Creates a new instance with the specified degree of parallelism.
31 | public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism, int hardLimit)
32 | {
33 | if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
34 | if (maxDegreeOfParallelism > 0 && maxDegreeOfParallelism <= hardLimit)
35 | _maxDegreeOfParallelism = maxDegreeOfParallelism;
36 | else
37 | _maxDegreeOfParallelism = 2;
38 | }
39 |
40 | // Queues a task to the scheduler.
41 | protected sealed override void QueueTask(Task task)
42 | {
43 | // Add the task to the list of tasks to be processed. If there aren't enough
44 | // delegates currently queued or running to process tasks, schedule another.
45 | lock (_tasks)
46 | {
47 | _tasks.AddLast(task);
48 | if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
49 | {
50 | ++_delegatesQueuedOrRunning;
51 | NotifyThreadPoolOfPendingWork();
52 | }
53 | }
54 | }
55 |
56 | // Inform the ThreadPool that there's work to be executed for this scheduler.
57 | private void NotifyThreadPoolOfPendingWork()
58 | {
59 | ThreadPool.UnsafeQueueUserWorkItem(_ =>
60 | {
61 | // Note that the current thread is now processing work items.
62 | // This is necessary to enable inlining of tasks into this thread.
63 | _currentThreadIsProcessingItems = true;
64 | try
65 | {
66 | // Process all available items in the queue.
67 | while (true)
68 | {
69 | Task item;
70 | lock (_tasks)
71 | {
72 | // When there are no more items to be processed,
73 | // note that we're done processing, and get out.
74 | if (_tasks.Count == 0)
75 | {
76 | --_delegatesQueuedOrRunning;
77 | break;
78 | }
79 |
80 | // Get the next item from the queue
81 | item = _tasks.First.Value;
82 | _tasks.RemoveFirst();
83 | }
84 |
85 | // Execute the task we pulled out of the queue
86 | base.TryExecuteTask(item);
87 | }
88 | }
89 | // We're done processing items on the current thread
90 | finally { _currentThreadIsProcessingItems = false; }
91 | }, null);
92 | }
93 |
94 | // Attempts to execute the specified task on the current thread.
95 | protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
96 | {
97 | // If this thread isn't already processing a task, we don't support inlining
98 | if (!_currentThreadIsProcessingItems) return false;
99 |
100 | // If the task was previously queued, remove it from the queue
101 | if (taskWasPreviouslyQueued)
102 | // Try to run the task.
103 | if (TryDequeue(task))
104 | return base.TryExecuteTask(task);
105 | else
106 | return false;
107 | else
108 | return base.TryExecuteTask(task);
109 | }
110 |
111 | // Attempt to remove a previously scheduled task from the scheduler.
112 | protected sealed override bool TryDequeue(Task task)
113 | {
114 | lock (_tasks) return _tasks.Remove(task);
115 | }
116 |
117 | // Gets the maximum concurrency level supported by this scheduler.
118 | public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } }
119 |
120 | // Gets an enumerable of the tasks currently scheduled on this scheduler.
121 | protected sealed override IEnumerable GetScheduledTasks()
122 | {
123 | bool lockTaken = false;
124 | try
125 | {
126 | Monitor.TryEnter(_tasks, ref lockTaken);
127 | if (lockTaken) return _tasks;
128 | else throw new NotSupportedException();
129 | }
130 | finally
131 | {
132 | if (lockTaken) Monitor.Exit(_tasks);
133 | }
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/Nandaka.Common/ListStringConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows.Data;
6 |
7 | namespace Nandaka.Common
8 | {
9 | [ValueConversion(typeof(List), typeof(string))]
10 | public class ListToStringConverter : IValueConverter
11 | {
12 |
13 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
14 | {
15 | if (targetType != typeof(string))
16 | throw new InvalidOperationException("The target must be a String");
17 |
18 | var temp = value as List;
19 | if (temp == null || temp.Count == 0) return "";
20 |
21 | var delimiter = ", ";
22 | if (parameter != null && parameter.GetType() == typeof(string))
23 | {
24 | if (!String.IsNullOrWhiteSpace(parameter as string))
25 | delimiter = parameter as string;
26 | }
27 | return String.Join(delimiter, ((List)value).ToArray());
28 | }
29 |
30 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
31 | {
32 | if (targetType != typeof(List))
33 | throw new InvalidOperationException("The target must be a List");
34 |
35 | string delimiter = ", ";
36 | if (parameter != null && parameter.GetType() == typeof(string))
37 | {
38 | if (!String.IsNullOrWhiteSpace(parameter as string))
39 | delimiter = parameter as string;
40 | }
41 |
42 | var temp = value as string;
43 | var result = new List();
44 | if (!string.IsNullOrWhiteSpace(temp))
45 | {
46 | result = temp.Split(new string[] { delimiter }, StringSplitOptions.None).ToList();
47 | }
48 | return result;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Nandaka.Common/Nandaka.Common.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {679DC8EF-673E-40CC-8478-08B3CD4BA836}
9 | Library
10 | Properties
11 | Nandaka.Common
12 | Nandaka.Common
13 | v4.5
14 | 512
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | false
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 | false
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | Component
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | True
65 | True
66 | Settings.settings
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | PublicSettingsSingleFileGenerator
76 | Settings.Designer.cs
77 |
78 |
79 |
80 |
87 |
--------------------------------------------------------------------------------
/Nandaka.Common/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Nandaka.Common")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Nandaka.Common")]
13 | [assembly: AssemblyCopyright("Copyright © Nandaka 2014-2021")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("a08cd296-1cf9-4770-ba74-01e98d84d508")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.5")]
36 | [assembly: AssemblyFileVersion("1.0.0.5")]
37 |
--------------------------------------------------------------------------------
/Nandaka.Common/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Nandaka.Common.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
16 | public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("60000")]
29 | public int Timeout {
30 | get {
31 | return ((int)(this["Timeout"]));
32 | }
33 | set {
34 | this["Timeout"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
41 | public bool UseProxy {
42 | get {
43 | return ((bool)(this["UseProxy"]));
44 | }
45 | set {
46 | this["UseProxy"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.UserScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("")]
53 | public string ProxyAddress {
54 | get {
55 | return ((string)(this["ProxyAddress"]));
56 | }
57 | set {
58 | this["ProxyAddress"] = value;
59 | }
60 | }
61 |
62 | [global::System.Configuration.UserScopedSettingAttribute()]
63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
64 | [global::System.Configuration.DefaultSettingValueAttribute("0")]
65 | public int ProxyPort {
66 | get {
67 | return ((int)(this["ProxyPort"]));
68 | }
69 | set {
70 | this["ProxyPort"] = value;
71 | }
72 | }
73 |
74 | [global::System.Configuration.UserScopedSettingAttribute()]
75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
76 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
77 | public bool UseProxyLogin {
78 | get {
79 | return ((bool)(this["UseProxyLogin"]));
80 | }
81 | set {
82 | this["UseProxyLogin"] = value;
83 | }
84 | }
85 |
86 | [global::System.Configuration.UserScopedSettingAttribute()]
87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
88 | [global::System.Configuration.DefaultSettingValueAttribute("")]
89 | public string ProxyUsername {
90 | get {
91 | return ((string)(this["ProxyUsername"]));
92 | }
93 | set {
94 | this["ProxyUsername"] = value;
95 | }
96 | }
97 |
98 | [global::System.Configuration.UserScopedSettingAttribute()]
99 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
100 | [global::System.Configuration.DefaultSettingValueAttribute("")]
101 | public string ProxyPassword {
102 | get {
103 | return ((string)(this["ProxyPassword"]));
104 | }
105 | set {
106 | this["ProxyPassword"] = value;
107 | }
108 | }
109 |
110 | [global::System.Configuration.UserScopedSettingAttribute()]
111 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
112 | [global::System.Configuration.DefaultSettingValueAttribute("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome" +
113 | "/31.0.1650.63 Safari/537.36")]
114 | public string UserAgent {
115 | get {
116 | return ((string)(this["UserAgent"]));
117 | }
118 | set {
119 | this["UserAgent"] = value;
120 | }
121 | }
122 |
123 | [global::System.Configuration.UserScopedSettingAttribute()]
124 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
125 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
126 | public bool PadUserAgent {
127 | get {
128 | return ((bool)(this["PadUserAgent"]));
129 | }
130 | set {
131 | this["PadUserAgent"] = value;
132 | }
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/Nandaka.Common/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 60000
7 |
8 |
9 | False
10 |
11 |
12 |
13 |
14 |
15 | 0
16 |
17 |
18 | False
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
28 |
29 |
30 | False
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Nandaka.Common/SecureIt.cs:
--------------------------------------------------------------------------------
1 | /***
2 | * Taken from http://stackoverflow.com/a/8875545
3 | */
4 |
5 | using System.Collections.Generic;
6 | using System.Runtime.InteropServices;
7 | using System.Security;
8 | using System.Security.Cryptography;
9 | using System.Text;
10 | using System;
11 |
12 | namespace Nandaka.Common
13 | {
14 | public static class SecureIt
15 | {
16 | private static readonly byte[] entropy = Encoding.Unicode.GetBytes("Salt Is Not A Password");
17 |
18 | public static string EncryptString(this SecureString input)
19 | {
20 | if (input == null)
21 | {
22 | return null;
23 | }
24 |
25 | var encryptedData = ProtectedData.Protect(
26 | Encoding.Unicode.GetBytes(input.ToInsecureString()),
27 | entropy,
28 | DataProtectionScope.CurrentUser);
29 |
30 | return Convert.ToBase64String(encryptedData);
31 | }
32 |
33 | public static SecureString DecryptString(this string encryptedData)
34 | {
35 | if (encryptedData == null)
36 | {
37 | return null;
38 | }
39 |
40 | try
41 | {
42 | var decryptedData = ProtectedData.Unprotect(
43 | Convert.FromBase64String(encryptedData),
44 | entropy,
45 | DataProtectionScope.CurrentUser);
46 |
47 | return Encoding.Unicode.GetString(decryptedData).ToSecureString();
48 | }
49 | catch
50 | {
51 | return new SecureString();
52 | }
53 | }
54 |
55 | public static SecureString ToSecureString(this IEnumerable input)
56 | {
57 | if (input == null)
58 | {
59 | return null;
60 | }
61 |
62 | var secure = new SecureString();
63 |
64 | foreach (var c in input)
65 | {
66 | secure.AppendChar(c);
67 | }
68 |
69 | secure.MakeReadOnly();
70 | return secure;
71 | }
72 |
73 | public static string ToInsecureString(this SecureString input)
74 | {
75 | if (input == null)
76 | {
77 | return null;
78 | }
79 |
80 | var ptr = Marshal.SecureStringToBSTR(input);
81 |
82 | try
83 | {
84 | return Marshal.PtrToStringBSTR(ptr);
85 | }
86 | finally
87 | {
88 | Marshal.ZeroFreeBSTR(ptr);
89 | }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Nandaka.Common/WPF/ZoomBorder.cs:
--------------------------------------------------------------------------------
1 | /***
2 | * From https://github.com/wieslawsoltes/PanAndZoom/blob/master/PanAndZoom/ZoomBorder.cs
3 | ***/
4 |
5 | using System.Linq;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Input;
9 | using System.Windows.Media;
10 |
11 | namespace Nandaka.Common.WPF
12 | {
13 | public class ZoomBorder : Border
14 | {
15 | private UIElement child = null;
16 | private Point origin;
17 | private Point start;
18 |
19 | private TranslateTransform GetTranslateTransform(UIElement element)
20 | {
21 | return (TranslateTransform)((TransformGroup)element.RenderTransform)
22 | .Children.First(tr => tr is TranslateTransform);
23 | }
24 |
25 | private ScaleTransform GetScaleTransform(UIElement element)
26 | {
27 | return (ScaleTransform)((TransformGroup)element.RenderTransform)
28 | .Children.First(tr => tr is ScaleTransform);
29 | }
30 |
31 | public override UIElement Child
32 | {
33 | get { return base.Child; }
34 | set
35 | {
36 | if (value != null && value != this.Child)
37 | this.Initialize(value);
38 | base.Child = value;
39 | }
40 | }
41 |
42 | public void Initialize(UIElement element)
43 | {
44 | this.child = element;
45 |
46 | if (child != null)
47 | {
48 | TransformGroup group = new TransformGroup();
49 | ScaleTransform st = new ScaleTransform();
50 | group.Children.Add(st);
51 | TranslateTransform tt = new TranslateTransform();
52 | group.Children.Add(tt);
53 | child.RenderTransform = group;
54 | child.RenderTransformOrigin = new Point(0.0, 0.0);
55 | this.MouseWheel += child_MouseWheel;
56 | this.MouseLeftButtonDown += child_MouseLeftButtonDown;
57 | this.MouseLeftButtonUp += child_MouseLeftButtonUp;
58 | this.MouseMove += child_MouseMove;
59 | this.PreviewMouseRightButtonDown += new MouseButtonEventHandler(
60 | child_PreviewMouseRightButtonDown);
61 | this.MouseDown += new MouseButtonEventHandler(ZoomBorder_MouseDown);
62 | }
63 | }
64 |
65 | ///
66 | /// Reset zoom on double click
67 | ///
68 | ///
69 | ///
70 | private void ZoomBorder_MouseDown(object sender, MouseButtonEventArgs e)
71 | {
72 | if (e.ClickCount >= 2)
73 | {
74 | // reset zoom
75 | Reset();
76 | }
77 | }
78 |
79 | public void Reset()
80 | {
81 | if (child != null)
82 | {
83 | // reset zoom
84 | var st = GetScaleTransform(child);
85 | st.ScaleX = 1.0;
86 | st.ScaleY = 1.0;
87 |
88 | // reset pan
89 | var tt = GetTranslateTransform(child);
90 | tt.X = 0.0;
91 | tt.Y = 0.0;
92 | }
93 | }
94 |
95 | #region Child Events
96 |
97 | private void child_MouseWheel(object sender, MouseWheelEventArgs e)
98 | {
99 | if (child != null)
100 | {
101 | var st = GetScaleTransform(child);
102 | var tt = GetTranslateTransform(child);
103 |
104 | double zoom = e.Delta > 0 ? .2 : -.2;
105 | if (!(e.Delta > 0) && (st.ScaleX < .4 || st.ScaleY < .4))
106 | return;
107 |
108 | Point relative = e.GetPosition(child);
109 | double abosuluteX;
110 | double abosuluteY;
111 |
112 | abosuluteX = relative.X * st.ScaleX + tt.X;
113 | abosuluteY = relative.Y * st.ScaleY + tt.Y;
114 |
115 | st.ScaleX += zoom;
116 | st.ScaleY += zoom;
117 |
118 | tt.X = abosuluteX - relative.X * st.ScaleX;
119 | tt.Y = abosuluteY - relative.Y * st.ScaleY;
120 | }
121 | }
122 |
123 | private void child_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
124 | {
125 | if (child != null)
126 | {
127 | var tt = GetTranslateTransform(child);
128 | start = e.GetPosition(this);
129 | origin = new Point(tt.X, tt.Y);
130 | this.Cursor = Cursors.Hand;
131 | child.CaptureMouse();
132 | }
133 | }
134 |
135 | private void child_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
136 | {
137 | if (child != null)
138 | {
139 | child.ReleaseMouseCapture();
140 | this.Cursor = Cursors.Arrow;
141 | }
142 | }
143 |
144 | private void child_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
145 | {
146 | this.Reset();
147 | }
148 |
149 | private void child_MouseMove(object sender, MouseEventArgs e)
150 | {
151 | if (child != null)
152 | {
153 | if (child.IsMouseCaptured)
154 | {
155 | var tt = GetTranslateTransform(child);
156 | Vector v = start - e.GetPosition(this);
157 | tt.X = origin.X - v.X;
158 | tt.Y = origin.Y - v.Y;
159 | }
160 | }
161 | }
162 |
163 | #endregion Child Events
164 | }
165 | }
--------------------------------------------------------------------------------
/Nandaka.Common/WebImgConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | using System.Windows.Data;
7 | using System.Windows.Media.Imaging;
8 | using System.IO;
9 |
10 |
11 | namespace Nandaka.Common
12 | {
13 | public class WebImgConverter : IValueConverter
14 | {
15 | public object Convert(object value)
16 | {
17 | if (value != null)
18 | {
19 | var url = value.ToString();
20 | if (url.StartsWith("//"))
21 | {
22 | url = "http:" + url;
23 | }
24 |
25 | //ExtendedWebClient client = new ExtendedWebClient();
26 | //var result = client.DownloadData(url);
27 | //using (var ms = new MemoryStream(result))
28 | //{
29 | // var image = new BitmapImage();
30 | // image.BeginInit();
31 | // image.CacheOption = BitmapCacheOption.OnLoad;
32 | // image.StreamSource = ms;
33 | // image.EndInit();
34 | // return image;
35 | //}
36 | BitmapImage bi = new BitmapImage(new Uri(url));
37 | return bi;
38 |
39 | }
40 | else
41 | {
42 | return null;
43 | }
44 |
45 | }
46 |
47 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
48 | {
49 | return Convert(value);
50 | }
51 |
52 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
53 | {
54 | return Convert(value);
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Nandaka.Common/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | 60000
12 |
13 |
14 | False
15 |
16 |
17 |
18 |
19 |
20 | 0
21 |
22 |
23 | False
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
33 |
34 |
35 | False
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Nijie.Test/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
11 |
14 |
15 |
16 |
17 |
20 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 60000
52 |
53 |
54 | False
55 |
56 |
57 | localhost>
58 |
59 |
60 | 8118
61 |
62 |
63 | False
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
73 |
74 |
75 | False
76 |
77 |
78 |
79 |
80 | False
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/Nijie.Test/Nijie.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 |
8 |
9 | 2.0
10 | {C64EC614-A577-42AB-A67A-21C85A698797}
11 | Library
12 | Properties
13 | NijieDownloader.Test
14 | Nijie.Test
15 | v4.5
16 | 512
17 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
18 |
19 |
20 |
21 |
22 |
23 | true
24 | full
25 | false
26 | bin\Debug\
27 | DEBUG;TRACE
28 | prompt
29 | 4
30 | false
31 |
32 |
33 | pdbonly
34 | true
35 | bin\Release\
36 | TRACE
37 | prompt
38 | 4
39 | false
40 |
41 |
42 |
43 | ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll
44 |
45 |
46 | ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll
47 |
48 |
49 | ..\packages\EntityFramework.SqlServerCompact.6.4.4\lib\net45\EntityFramework.SqlServerCompact.dll
50 |
51 |
52 | ..\packages\HtmlAgilityPack.1.11.31\lib\Net45\HtmlAgilityPack.dll
53 |
54 |
55 | ..\packages\log4net.2.0.12\lib\net45\log4net.dll
56 |
57 |
58 |
59 |
60 |
61 |
62 | 3.5
63 |
64 |
65 |
66 |
67 | ..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | False
77 |
78 |
79 |
80 |
81 |
82 | True
83 | True
84 | Settings.settings
85 |
86 |
87 |
88 | Form
89 |
90 |
91 | UpdateHtmlForm.cs
92 |
93 |
94 |
95 |
96 | {679DC8EF-673E-40CC-8478-08B3CD4BA836}
97 | Nandaka.Common
98 |
99 |
100 | {6976B954-CD09-4FE6-9880-BF45150A6EF2}
101 | NijieDownloader.Library
102 |
103 |
104 |
105 |
106 | Designer
107 |
108 |
109 |
110 | SettingsSingleFileGenerator
111 | Settings.Designer.cs
112 |
113 |
114 |
115 |
116 | UpdateHtmlForm.cs
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 | if not exist "$(TargetDir)x86" md "$(TargetDir)x86"
126 | xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86"
127 | if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64"
128 | xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"
129 |
130 |
131 |
132 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
133 |
134 |
135 |
136 |
137 |
138 |
145 |
--------------------------------------------------------------------------------
/Nijie.Test/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("NijieDownloader.Test")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("NijieDownloader.Test")]
13 | [assembly: AssemblyCopyright("Copyright © Nandaka 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("d3cb862f-3d50-4c73-8e21-982e0a5e2d4b")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/Nijie.Test/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace NijieDownloader.Test.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("")]
29 | public string Username {
30 | get {
31 | return ((string)(this["Username"]));
32 | }
33 | set {
34 | this["Username"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("")]
41 | public string Password {
42 | get {
43 | return ((string)(this["Password"]));
44 | }
45 | set {
46 | this["Password"] = value;
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Nijie.Test/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Nijie.Test/UpdateHtmlForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace NijieDownloader.Test
2 | {
3 | partial class UpdateHtmlForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.btnUpdate = new System.Windows.Forms.Button();
32 | this.txtLog = new System.Windows.Forms.TextBox();
33 | this.txtUser = new System.Windows.Forms.TextBox();
34 | this.txtPass = new System.Windows.Forms.TextBox();
35 | this.label1 = new System.Windows.Forms.Label();
36 | this.Pass = new System.Windows.Forms.Label();
37 | this.btnLogin = new System.Windows.Forms.Button();
38 | this.SuspendLayout();
39 | //
40 | // btnUpdate
41 | //
42 | this.btnUpdate.Location = new System.Drawing.Point(465, 12);
43 | this.btnUpdate.Name = "btnUpdate";
44 | this.btnUpdate.Size = new System.Drawing.Size(75, 23);
45 | this.btnUpdate.TabIndex = 0;
46 | this.btnUpdate.Text = "Update";
47 | this.btnUpdate.UseVisualStyleBackColor = true;
48 | this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click);
49 | //
50 | // txtLog
51 | //
52 | this.txtLog.Location = new System.Drawing.Point(12, 44);
53 | this.txtLog.Multiline = true;
54 | this.txtLog.Name = "txtLog";
55 | this.txtLog.Size = new System.Drawing.Size(528, 206);
56 | this.txtLog.TabIndex = 1;
57 | //
58 | // txtUser
59 | //
60 | this.txtUser.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::NijieDownloader.Test.Properties.Settings.Default, "Username", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
61 | this.txtUser.Location = new System.Drawing.Point(56, 12);
62 | this.txtUser.Name = "txtUser";
63 | this.txtUser.Size = new System.Drawing.Size(136, 22);
64 | this.txtUser.TabIndex = 2;
65 | this.txtUser.Text = global::NijieDownloader.Test.Properties.Settings.Default.Username;
66 | //
67 | // txtPass
68 | //
69 | this.txtPass.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::NijieDownloader.Test.Properties.Settings.Default, "Password", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
70 | this.txtPass.Location = new System.Drawing.Point(233, 12);
71 | this.txtPass.Name = "txtPass";
72 | this.txtPass.Size = new System.Drawing.Size(163, 22);
73 | this.txtPass.TabIndex = 3;
74 | this.txtPass.Text = global::NijieDownloader.Test.Properties.Settings.Default.Password;
75 | //
76 | // label1
77 | //
78 | this.label1.AutoSize = true;
79 | this.label1.Location = new System.Drawing.Point(12, 15);
80 | this.label1.Name = "label1";
81 | this.label1.Size = new System.Drawing.Size(30, 13);
82 | this.label1.TabIndex = 4;
83 | this.label1.Text = "User";
84 | //
85 | // Pass
86 | //
87 | this.Pass.AutoSize = true;
88 | this.Pass.Location = new System.Drawing.Point(198, 17);
89 | this.Pass.Name = "Pass";
90 | this.Pass.Size = new System.Drawing.Size(29, 13);
91 | this.Pass.TabIndex = 5;
92 | this.Pass.Text = "Pass";
93 | //
94 | // btnLogin
95 | //
96 | this.btnLogin.Location = new System.Drawing.Point(402, 12);
97 | this.btnLogin.Name = "btnLogin";
98 | this.btnLogin.Size = new System.Drawing.Size(57, 23);
99 | this.btnLogin.TabIndex = 6;
100 | this.btnLogin.Text = "Login";
101 | this.btnLogin.UseVisualStyleBackColor = true;
102 | this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
103 | //
104 | // UpdateHtmlForm
105 | //
106 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
107 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
108 | this.ClientSize = new System.Drawing.Size(552, 262);
109 | this.Controls.Add(this.btnLogin);
110 | this.Controls.Add(this.Pass);
111 | this.Controls.Add(this.label1);
112 | this.Controls.Add(this.txtPass);
113 | this.Controls.Add(this.txtUser);
114 | this.Controls.Add(this.txtLog);
115 | this.Controls.Add(this.btnUpdate);
116 | this.Name = "UpdateHtmlForm";
117 | this.Text = "UpdateHtmlForm";
118 | this.ResumeLayout(false);
119 | this.PerformLayout();
120 |
121 | }
122 |
123 | #endregion
124 |
125 | private System.Windows.Forms.Button btnUpdate;
126 | private System.Windows.Forms.TextBox txtLog;
127 | private System.Windows.Forms.TextBox txtUser;
128 | private System.Windows.Forms.TextBox txtPass;
129 | private System.Windows.Forms.Label label1;
130 | private System.Windows.Forms.Label Pass;
131 | private System.Windows.Forms.Button btnLogin;
132 | }
133 | }
--------------------------------------------------------------------------------
/Nijie.Test/UpdateHtmlForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Nijie.Test/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | True
35 |
36 |
37 | 3
38 |
39 |
40 | False
41 |
42 |
43 | False
44 |
45 |
46 | False
47 |
48 |
49 | 60
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/DAL/NijieContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Data.Entity;
6 | using NijieDownloader.Library.Model;
7 |
8 | namespace NijieDownloader.Library.DAL
9 | {
10 | public class NijieContext : DbContext
11 | {
12 | public NijieContext()
13 | {
14 | Database.SetInitializer(new MigrateDatabaseToLatestVersion());
15 | }
16 |
17 | public DbSet Images { get; set; }
18 | public DbSet Members { get; set; }
19 | public DbSet Tags { get; set; }
20 | public DbSet MangaInfo { get; set; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Migrations/201402201406506_InitialCreate.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | namespace NijieDownloader.Library.Migrations
3 | {
4 | using System.CodeDom.Compiler;
5 | using System.Data.Entity.Migrations;
6 | using System.Data.Entity.Migrations.Infrastructure;
7 | using System.Resources;
8 |
9 | [GeneratedCode("EntityFramework.Migrations", "6.0.2-21211")]
10 | public sealed partial class InitialCreate : IMigrationMetadata
11 | {
12 | private readonly ResourceManager Resources = new ResourceManager(typeof(InitialCreate));
13 |
14 | string IMigrationMetadata.Id
15 | {
16 | get { return "201402201406506_InitialCreate"; }
17 | }
18 |
19 | string IMigrationMetadata.Source
20 | {
21 | get { return null; }
22 | }
23 |
24 | string IMigrationMetadata.Target
25 | {
26 | get { return Resources.GetString("Target"); }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Migrations/201402201406506_InitialCreate.cs:
--------------------------------------------------------------------------------
1 | namespace NijieDownloader.Library.Migrations
2 | {
3 | using System;
4 | using System.Data.Entity.Migrations;
5 |
6 | public partial class InitialCreate : DbMigration
7 | {
8 | public override void Up()
9 | {
10 | CreateTable(
11 | "dbo.NijieImages",
12 | c => new
13 | {
14 | ImageId = c.Int(nullable: false),
15 | BigImageUrl = c.String(maxLength: 4000),
16 | MediumImageUrl = c.String(maxLength: 4000),
17 | ThumbImageUrl = c.String(maxLength: 4000),
18 | Title = c.String(maxLength: 4000),
19 | Description = c.String(maxLength: 4000),
20 | WorkDate = c.DateTime(nullable: false),
21 | IsManga = c.Boolean(nullable: false),
22 | Referer = c.String(maxLength: 4000),
23 | IsFriendOnly = c.Boolean(nullable: false),
24 | IsGoldenMember = c.Boolean(nullable: false),
25 | NuitaCount = c.Int(nullable: false),
26 | GoodCount = c.Int(nullable: false),
27 | IsAnimated = c.Boolean(nullable: false),
28 | SavedFilename = c.String(maxLength: 4000),
29 | Member_MemberId = c.Int(),
30 | })
31 | .PrimaryKey(t => t.ImageId)
32 | .ForeignKey("dbo.NijieMembers", t => t.Member_MemberId)
33 | .Index(t => t.Member_MemberId);
34 |
35 | CreateTable(
36 | "dbo.NijieMembers",
37 | c => new
38 | {
39 | MemberId = c.Int(nullable: false),
40 | UserName = c.String(maxLength: 4000),
41 | AvatarUrl = c.String(maxLength: 4000),
42 | })
43 | .PrimaryKey(t => t.MemberId);
44 |
45 | }
46 |
47 | public override void Down()
48 | {
49 | DropForeignKey("dbo.NijieImages", "Member_MemberId", "dbo.NijieMembers");
50 | DropIndex("dbo.NijieImages", new[] { "Member_MemberId" });
51 | DropTable("dbo.NijieMembers");
52 | DropTable("dbo.NijieImages");
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Migrations/201403061411087_AddNijieTags.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | namespace NijieDownloader.Library.Migrations
3 | {
4 | using System.CodeDom.Compiler;
5 | using System.Data.Entity.Migrations;
6 | using System.Data.Entity.Migrations.Infrastructure;
7 | using System.Resources;
8 |
9 | [GeneratedCode("EntityFramework.Migrations", "6.0.2-21211")]
10 | public sealed partial class AddNijieTags : IMigrationMetadata
11 | {
12 | private readonly ResourceManager Resources = new ResourceManager(typeof(AddNijieTags));
13 |
14 | string IMigrationMetadata.Id
15 | {
16 | get { return "201403061411087_AddNijieTags"; }
17 | }
18 |
19 | string IMigrationMetadata.Source
20 | {
21 | get { return null; }
22 | }
23 |
24 | string IMigrationMetadata.Target
25 | {
26 | get { return Resources.GetString("Target"); }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Migrations/201403061411087_AddNijieTags.cs:
--------------------------------------------------------------------------------
1 | namespace NijieDownloader.Library.Migrations
2 | {
3 | using System;
4 | using System.Data.Entity.Migrations;
5 |
6 | public partial class AddNijieTags : DbMigration
7 | {
8 | public override void Up()
9 | {
10 | CreateTable(
11 | "dbo.NijieTags",
12 | c => new
13 | {
14 | Name = c.String(nullable: false, maxLength: 4000),
15 | })
16 | .PrimaryKey(t => t.Name);
17 |
18 | CreateTable(
19 | "dbo.NijieTagNijieImages",
20 | c => new
21 | {
22 | NijieTag_Name = c.String(nullable: false, maxLength: 4000),
23 | NijieImage_ImageId = c.Int(nullable: false),
24 | })
25 | .PrimaryKey(t => new { t.NijieTag_Name, t.NijieImage_ImageId })
26 | .ForeignKey("dbo.NijieTags", t => t.NijieTag_Name, cascadeDelete: true)
27 | .ForeignKey("dbo.NijieImages", t => t.NijieImage_ImageId, cascadeDelete: true)
28 | .Index(t => t.NijieTag_Name)
29 | .Index(t => t.NijieImage_ImageId);
30 |
31 | }
32 |
33 | public override void Down()
34 | {
35 | DropForeignKey("dbo.NijieTagNijieImages", "NijieImage_ImageId", "dbo.NijieImages");
36 | DropForeignKey("dbo.NijieTagNijieImages", "NijieTag_Name", "dbo.NijieTags");
37 | DropIndex("dbo.NijieTagNijieImages", new[] { "NijieImage_ImageId" });
38 | DropIndex("dbo.NijieTagNijieImages", new[] { "NijieTag_Name" });
39 | DropTable("dbo.NijieTagNijieImages");
40 | DropTable("dbo.NijieTags");
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Migrations/201404021353243_1.0.3.1.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | namespace NijieDownloader.Library.Migrations
3 | {
4 | using System.CodeDom.Compiler;
5 | using System.Data.Entity.Migrations;
6 | using System.Data.Entity.Migrations.Infrastructure;
7 | using System.Resources;
8 |
9 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")]
10 | public sealed partial class _1031 : IMigrationMetadata
11 | {
12 | private readonly ResourceManager Resources = new ResourceManager(typeof(_1031));
13 |
14 | string IMigrationMetadata.Id
15 | {
16 | get { return "201404021353243_1.0.3.1"; }
17 | }
18 |
19 | string IMigrationMetadata.Source
20 | {
21 | get { return null; }
22 | }
23 |
24 | string IMigrationMetadata.Target
25 | {
26 | get { return Resources.GetString("Target"); }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Migrations/201404021353243_1.0.3.1.cs:
--------------------------------------------------------------------------------
1 | namespace NijieDownloader.Library.Migrations
2 | {
3 | using System;
4 | using System.Data.Entity.Migrations;
5 |
6 | public partial class _1031 : DbMigration
7 | {
8 | public override void Up()
9 | {
10 | //CreateIndex("dbo.NijieImages", "Member_MemberId");
11 | //CreateIndex("dbo.NijieTagNijieImages", "NijieTag_Name");
12 | //CreateIndex("dbo.NijieTagNijieImages", "NijieImage_ImageId");
13 | }
14 |
15 | public override void Down()
16 | {
17 | //DropIndex("dbo.NijieTagNijieImages", new[] { "NijieImage_ImageId" });
18 | //DropIndex("dbo.NijieTagNijieImages", new[] { "NijieTag_Name" });
19 | //DropIndex("dbo.NijieImages", new[] { "Member_MemberId" });
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Migrations/Configuration.cs:
--------------------------------------------------------------------------------
1 | namespace NijieDownloader.Library.Migrations
2 | {
3 | using System;
4 | using System.Data.Entity;
5 | using System.Data.Entity.Migrations;
6 | using System.Linq;
7 |
8 | internal sealed class Configuration : DbMigrationsConfiguration
9 | {
10 | public Configuration()
11 | {
12 | AutomaticMigrationsEnabled = true;
13 | }
14 |
15 | protected override void Seed(NijieDownloader.Library.DAL.NijieContext context)
16 | {
17 | // This method will be called after migrating to the latest version.
18 |
19 | // You can use the DbSet.AddOrUpdate() helper extension method
20 | // to avoid creating duplicate seed data. E.g.
21 | //
22 | // context.People.AddOrUpdate(
23 | // p => p.FullName,
24 | // new Person { FullName = "Andrew Peters" },
25 | // new Person { FullName = "Brice Lambson" },
26 | // new Person { FullName = "Rowan Miller" }
27 | // );
28 | //
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Model/NijieImage.cs:
--------------------------------------------------------------------------------
1 | using Nandaka.Common;
2 | using NijieDownloader.Library.DAL;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.ComponentModel.DataAnnotations;
6 | using System.ComponentModel.DataAnnotations.Schema;
7 | using System.Data.Entity.Migrations;
8 | using System.Diagnostics;
9 | using System.Linq;
10 |
11 | namespace NijieDownloader.Library.Model
12 | {
13 | public class NijieImage
14 | {
15 | #region ctor
16 |
17 | public NijieImage()
18 | {
19 | this.ImageId = -1;
20 | }
21 |
22 | public NijieImage(int imageId)
23 | {
24 | this.ImageId = imageId;
25 | }
26 |
27 | #endregion ctor
28 |
29 | #region db colums
30 |
31 | [Key]
32 | [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)]
33 | public int ImageId { get; set; }
34 |
35 | public string BigImageUrl { get; set; }
36 |
37 | public string MediumImageUrl { get; set; }
38 |
39 | public string ThumbImageUrl { get; set; }
40 |
41 | public string Title { get; set; }
42 |
43 | public string Description { get; set; }
44 |
45 | // to avoid overflow problem
46 | private DateTime _workDate;
47 |
48 | public DateTime WorkDate
49 | {
50 | get
51 | {
52 | if (_workDate == DateTime.MinValue)
53 | _workDate = System.Data.SqlTypes.SqlDateTime.MinValue.Value;
54 | return _workDate;
55 | }
56 | set
57 | {
58 | _workDate = value;
59 | }
60 | }
61 |
62 | public string Referer { get; set; }
63 |
64 | public bool IsFriendOnly { get; set; }
65 |
66 | public bool IsGoldenMember { get; set; }
67 |
68 | public int NuitaCount { get; set; }
69 |
70 | public int GoodCount { get; set; }
71 |
72 | public bool IsAnimated { get; set; }
73 |
74 | public string SavedFilename { get; set; }
75 |
76 | public string ServerFilename { get; set; }
77 |
78 | public long Filesize { get; set; }
79 |
80 | // manga related
81 | public bool IsManga { get; set; }
82 |
83 | public List ImageUrls { get; set; }
84 |
85 | public virtual ICollection MangaPages { get; set; }
86 |
87 | public virtual ICollection Tags { get; set; }
88 |
89 | public NijieMember Member { get; set; }
90 |
91 | #endregion db colums
92 |
93 | #region not mapped
94 |
95 | [NotMapped]
96 | public string ViewUrl
97 | {
98 | get
99 | {
100 | return Util.FixUrl("//nijie.info/view.php?id=" + ImageId, Nijie.ROOT_DOMAIN, Properties.Settings.Default.UseHttps);
101 | }
102 | private set { }
103 | }
104 |
105 | private bool _isDownloaded;
106 |
107 | [NotMapped]
108 | public bool IsDownloaded
109 | {
110 | get
111 | {
112 | if (_workDate == System.Data.SqlTypes.SqlDateTime.MinValue.Value || !_isDownloaded)
113 | return false;
114 | return _isDownloaded;
115 | }
116 | set
117 | {
118 | _isDownloaded = value;
119 | }
120 | }
121 |
122 | [NotMapped]
123 | public NijieMember BookmarkedBy { get; set; }
124 |
125 | #endregion not mapped
126 |
127 | public void SaveToDb(NijieContext dao, bool suppressSave = false)
128 | {
129 | var member = (from x in dao.Members
130 | where x.MemberId == this.Member.MemberId
131 | select x).FirstOrDefault();
132 | if (member != null)
133 | {
134 | this.Member = member;
135 | }
136 |
137 | var temp = new List();
138 | for (int i = 0; i < this.Tags.Count; ++i)
139 | {
140 | var t = this.Tags.ElementAt(i);
141 | var x = (from a in dao.Tags
142 | where a.Name == t.Name
143 | select a).FirstOrDefault();
144 | if (x != null)
145 | {
146 | temp.Add(x);
147 | }
148 | else
149 | {
150 | temp.Add(t);
151 | }
152 | }
153 | this.Tags = temp;
154 |
155 | dao.Images.AddOrUpdate(this);
156 |
157 | if (!suppressSave)
158 | {
159 | dao.SaveChanges();
160 | }
161 |
162 | Debug.Assert(this.WorkDate != DateTime.MinValue, "Works Date cannot be set to DateTime.MinValue");
163 | }
164 |
165 | public static bool IsDownloadedInDB(int imageId)
166 | {
167 | using (var dao = new NijieContext())
168 | {
169 | var image = (from i in dao.Images
170 | where i.ImageId == imageId
171 | select i).FirstOrDefault();
172 | if (image != null)
173 | {
174 | if (!string.IsNullOrWhiteSpace(image.SavedFilename))
175 | return true;
176 | }
177 | }
178 | return false;
179 | }
180 |
181 | public bool IsDoujin { get; set; }
182 | public bool IsVideo { get; set; }
183 | }
184 | }
--------------------------------------------------------------------------------
/NijieDownloader.Library/Model/NijieLoginInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace NijieDownloader.Library.Model
7 | {
8 | public class NijieLoginInfo
9 | {
10 | public String UserName { get; set; }
11 | public String Password { get; set; }
12 | public String ReturnUrl { get; set; }
13 | public String Ticket { get; set; }
14 | public bool RememberLogin { get; set; }
15 |
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Model/NijieMangaInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.ComponentModel.DataAnnotations;
6 | using System.ComponentModel.DataAnnotations.Schema;
7 |
8 | namespace NijieDownloader.Library.Model
9 | {
10 | public class NijieMangaInfo
11 | {
12 | public NijieImage Image { get; set; }
13 |
14 | [Key, Column(Order = 0)]
15 | [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)]
16 | public int ImageId { get; set; }
17 |
18 | [Key, Column(Order = 1)]
19 | [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)]
20 | public int Page { get; set; }
21 |
22 | public string SavedFilename { get; set; }
23 | public string ServerFilename { get; set; }
24 | public long Filesize { get; set; }
25 | public string ImageUrl { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Model/NijieMember.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.DataAnnotations;
3 | using System.ComponentModel.DataAnnotations.Schema;
4 |
5 | using Nandaka.Common;
6 |
7 | namespace NijieDownloader.Library.Model
8 | {
9 | public enum MemberMode
10 | {
11 | Images = 0,
12 | Doujin = 1,
13 | Bookmark = 2
14 | };
15 |
16 | public class NijieMember
17 | {
18 | [Key]
19 | [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)]
20 | public int MemberId { get; set; }
21 |
22 | public string UserName { get; set; }
23 |
24 | public string AvatarUrl { get; set; }
25 |
26 | public virtual ICollection Images { get; set; }
27 |
28 | [NotMapped]
29 | public MemberMode Mode { get; set; }
30 |
31 | [NotMapped]
32 | public string MemberUrl
33 | {
34 | get
35 | {
36 | return GenerateMemberUrl(MemberId, Mode, Page);
37 | }
38 | private set { }
39 | }
40 |
41 | [NotMapped]
42 | public int Page { get; set; }
43 |
44 | [NotMapped]
45 | public string Status { get; set; }
46 |
47 | [NotMapped]
48 | public bool UseHttps { get; set; }
49 |
50 | public NijieMember()
51 | {
52 | this.MemberId = -1;
53 | }
54 |
55 | public NijieMember(int memberId, MemberMode mode, int page = 0)
56 | {
57 | this.MemberId = memberId;
58 | this.Mode = mode;
59 | this.Page = page;
60 | }
61 |
62 | public static string GenerateMemberUrl(int memberId, MemberMode mode, int page)
63 | {
64 | var prefix = "";
65 | switch (mode)
66 | {
67 | case MemberMode.Images:
68 | prefix = "//nijie.info/members_illust.php?p=" + page + "&id=";
69 | break;
70 |
71 | case MemberMode.Doujin:
72 | prefix = "//nijie.info/members_dojin.php?id=";
73 | break;
74 |
75 | case MemberMode.Bookmark:
76 | prefix = "//nijie.info/user_like_illust_view.php?p=" + page + "&id=";
77 | break;
78 | }
79 |
80 | return Util.FixUrl(prefix + memberId, Nijie.ROOT_DOMAIN, Properties.Settings.Default.UseHttps);
81 | }
82 |
83 | [NotMapped]
84 | public bool IsNextAvailable { get; set; }
85 |
86 | [NotMapped]
87 | public int TotalImages { get; set; }
88 |
89 | }
90 | }
--------------------------------------------------------------------------------
/NijieDownloader.Library/Model/NijieSearch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | using Nandaka.Common;
7 |
8 | namespace NijieDownloader.Library.Model
9 | {
10 | public class NijieSearch
11 | {
12 | public NijieSearch(NijieSearchOption option)
13 | {
14 | this.Option = option;
15 | }
16 |
17 | public NijieSearchOption Option { get; set; }
18 |
19 | public string QueryUrl
20 | {
21 | get
22 | {
23 | return GenerateQueryUrl(Option);
24 | }
25 | private set { }
26 | }
27 |
28 | public List Images { get; set; }
29 |
30 | public bool IsNextAvailable { get; set; }
31 |
32 | public bool IsPrevAvailable
33 | {
34 | get
35 | {
36 | if (Option != null)
37 | return Option.Page > 1;
38 | return false;
39 | }
40 | }
41 |
42 | public static string GenerateQueryUrl(NijieSearchOption option)
43 | {
44 | var url = String.Format(@"//nijie.info/search.php?type={0}&word={1}&p={2}&mode={3}&illust_type={4}&sort={5}"
45 | , option.SearchTypeStr
46 | , option.Query
47 | , (int)option.Page
48 | , (int)option.SearchBy
49 | , ""
50 | , (int)option.Sort);
51 | return Util.FixUrl(url, Nijie.ROOT_DOMAIN, Properties.Settings.Default.UseHttps);
52 | }
53 |
54 | public int TotalImages { get; set; }
55 | }
56 | }
--------------------------------------------------------------------------------
/NijieDownloader.Library/Model/NijieSearchOption.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace NijieDownloader.Library.Model
7 | {
8 | public class NijieSearchOption
9 | {
10 | public string Query { get; set; }
11 |
12 | private int _page = 1;
13 | public int Page
14 | {
15 | get
16 | {
17 | return _page;
18 | }
19 | set
20 | {
21 | _page = value;
22 | }
23 | }
24 |
25 | public SortType Sort { get; set; }
26 | public SearchMode SearchBy { get; set; }
27 | public SearchType Matching { get; set; }
28 |
29 | public string SearchTypeStr
30 | {
31 | get
32 | {
33 | return GetStringValue(this.Matching);
34 | }
35 | private set { }
36 | }
37 |
38 | private static string GetStringValue(SearchType type)
39 | {
40 | var result = "";
41 | switch (type)
42 | {
43 | case SearchType.ExactMatch:
44 | result = "coincident";
45 | break;
46 | case SearchType.PartialMatch:
47 | result = "partial";
48 | break;
49 | default:
50 | result = "coincident";
51 | break;
52 | }
53 | return result;
54 | }
55 | }
56 |
57 | public enum SortType
58 | {
59 | Latest = 0,
60 | Popularity = 1,
61 | Overtake = 2,
62 | Oldest = 3
63 | }
64 |
65 | public enum SearchMode
66 | {
67 | Tag = 0,
68 | Title = 1
69 | }
70 |
71 | public enum SearchType
72 | {
73 | ExactMatch,
74 | PartialMatch
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Model/NijieTag.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.ComponentModel.DataAnnotations;
6 | using System.ComponentModel.DataAnnotations.Schema;
7 |
8 | namespace NijieDownloader.Library.Model
9 | {
10 | public class NijieTag
11 | {
12 | [Key]
13 | [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)]
14 | public string Name { get; set; }
15 | public virtual ICollection Images { get; set; }
16 |
17 | public override string ToString()
18 | {
19 | return Name;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Nijie.Bookmark.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Text.RegularExpressions;
6 | using HtmlAgilityPack;
7 | using Nandaka.Common;
8 | using NijieDownloader.Library.Model;
9 |
10 | namespace NijieDownloader.Library
11 | {
12 | public partial class Nijie
13 | {
14 | private Regex re_member = new Regex(@"id=(\d+)");
15 | public const string ROOT_DOMAIN = "nijie.info";
16 |
17 | public Tuple, bool> ParseMyMemberBookmark(int page)
18 | {
19 | canOperate();
20 | List members = new List();
21 |
22 | HtmlDocument doc = null;
23 | bool isNextPageAvailable = false;
24 | try
25 | {
26 | var url = Util.FixUrl(String.Format("//nijie.info/like_my.php?p={0}", page), ROOT_DOMAIN, Properties.Settings.Default.UseHttps);
27 | var result = getPage(url);
28 | doc = result.Item1;
29 |
30 | var membersDiv = doc.DocumentNode.SelectNodes("//div[@class='nijie-okini']");
31 | if (membersDiv != null)
32 | {
33 | foreach (var memberDiv in membersDiv)
34 | {
35 | var memberUrl = memberDiv.SelectSingleNode("//div[@class='nijie-okini']//a").Attributes["href"].Value;
36 | var res = re_member.Match(memberUrl);
37 | if (res.Success)
38 | {
39 | var member = new NijieMember(Int32.Parse(res.Groups[1].Value), 0);
40 | member.UserName = memberDiv.SelectSingleNode("//div[@class='nijie-okini']//p[@class='sougo']").InnerText;
41 | member.AvatarUrl = memberDiv.SelectSingleNode("//div[@class='nijie-okini']//a//img").Attributes["src"].Value;
42 | members.Add(member);
43 | }
44 | memberDiv.Remove();
45 | }
46 | }
47 |
48 | var nextPageButton = doc.DocumentNode.SelectNodes("//p[@class='page_button']//a");
49 | if (nextPageButton != null)
50 | {
51 | foreach (var item in nextPageButton)
52 | {
53 | if (item.InnerText.StartsWith("次へ"))
54 | {
55 | isNextPageAvailable = true;
56 | break;
57 | }
58 | }
59 | }
60 | }
61 | catch (Exception ex)
62 | {
63 | if (doc != null)
64 | {
65 | var filename = "Dump for My Member Bookmark.html";
66 | Log.Debug("Dumping My Member Bookmark page to: " + filename);
67 | doc.Save(filename);
68 | }
69 |
70 | throw new NijieException(String.Format("Error when processing my member bookmark ==> {0}", ex.Message), ex, NijieException.IMAGE_UNKNOWN_ERROR);
71 | }
72 |
73 | return new Tuple, bool>(members, isNextPageAvailable);
74 | }
75 |
76 | public Tuple, bool> ParseMyImageBookmark(int page)
77 | {
78 | canOperate();
79 | List images = new List();
80 |
81 | HtmlDocument doc = null;
82 | bool isNextPageAvailable = false;
83 | try
84 | {
85 | var url = Util.FixUrl(String.Format("//nijie.info/okiniiri.php?p={0}", page), ROOT_DOMAIN, Properties.Settings.Default.UseHttps);
86 | var result = getPage(url);
87 | doc = result.Item1;
88 |
89 | var imagesDiv = doc.DocumentNode.SelectNodes("//div[@class='nijie-bookmark']");
90 | if (imagesDiv != null)
91 | {
92 | foreach (var imageDivx in imagesDiv)
93 | {
94 | var tmp = imageDivx.InnerHtml;
95 | HtmlDocument imageDiv = new HtmlDocument();
96 | imageDiv.LoadHtml(tmp);
97 |
98 | var imageUrl = imageDiv.DocumentNode.SelectSingleNode("//a").Attributes["href"].Value;
99 | var res = re_image.Match(imageUrl);
100 | if (res.Success)
101 | {
102 | var image = new NijieImage(Int32.Parse(res.Groups[1].Value));
103 | image.Title = imageDiv.DocumentNode.SelectSingleNode("//p[@class='title']").InnerText;
104 | var tempThumb = imageDiv.DocumentNode.SelectSingleNode("//p[@class='nijiedao']//img").Attributes["src"].Value;
105 | image.ThumbImageUrl = Util.FixUrl(tempThumb, ROOT_DOMAIN, Properties.Settings.Default.UseHttps);
106 |
107 | // check if image is friend only
108 | // img src="//img.nijie.info/pic/common_icon/illust/friends.png"
109 | image.IsFriendOnly = false;
110 | if (image.ThumbImageUrl.EndsWith("friends.png"))
111 | {
112 | image.IsFriendOnly = true;
113 | }
114 |
115 | //"//img.nijie.info/pic/common_icon/illust/golden.png"
116 | image.IsGoldenMember = false;
117 | if (image.ThumbImageUrl.EndsWith("golden.png"))
118 | {
119 | image.IsGoldenMember = true;
120 | }
121 |
122 | // check manga icon
123 | image.IsManga = false;
124 | var icon = imageDiv.DocumentNode.SelectSingleNode("//div[@class='thumbnail-icon']/img");
125 | if (icon != null)
126 | {
127 | if (icon.Attributes["src"].Value.EndsWith("thumbnail_comic.png"))
128 | image.IsManga = true;
129 | }
130 |
131 | // check animation icon
132 | image.IsAnimated = false;
133 | var animeIcon = imageDiv.DocumentNode.SelectSingleNode("//div[@class='thumbnail-anime-icon']/img");
134 | if (animeIcon != null)
135 | {
136 | if (animeIcon.Attributes["src"].Value.EndsWith("thumbnail_anime.png"))
137 | image.IsAnimated = true;
138 | }
139 |
140 | images.Add(image);
141 | }
142 | imageDivx.Remove();
143 | }
144 | }
145 |
146 | var nextPageButton = doc.DocumentNode.SelectNodes("//p[@class='page_button']//a");
147 | if (nextPageButton != null)
148 | {
149 | foreach (var item in nextPageButton)
150 | {
151 | if (item.InnerText.StartsWith("次へ"))
152 | {
153 | isNextPageAvailable = true;
154 | break;
155 | }
156 | }
157 | }
158 | }
159 | catch (Exception ex)
160 | {
161 | if (doc != null)
162 | {
163 | var filename = "Dump for My Image Bookmark.html";
164 | Log.Debug("Dumping My Image Bookmark page to: " + filename);
165 | doc.Save(filename);
166 | }
167 |
168 | throw new NijieException(String.Format("Error when processing my image bookmark ==> {0}", ex.Message), ex, NijieException.IMAGE_UNKNOWN_ERROR);
169 | }
170 |
171 | return new Tuple, bool>(images, isNextPageAvailable);
172 | }
173 | }
174 | }
--------------------------------------------------------------------------------
/NijieDownloader.Library/Nijie.Login.cs:
--------------------------------------------------------------------------------
1 | using HtmlAgilityPack;
2 | using Nandaka.Common;
3 | using NijieDownloader.Library.Model;
4 | using System;
5 | using System.Collections.Specialized;
6 | using System.Diagnostics;
7 | using System.Net;
8 | using System.Threading.Tasks;
9 |
10 | namespace NijieDownloader.Library
11 | {
12 | public partial class Nijie
13 | {
14 | public static event NijieEventHandler LoggingEventHandler;
15 |
16 | public delegate void NijieEventHandler(object sender, bool result);
17 |
18 | private static string NijieSessionID { get; set; }
19 |
20 | private static bool _isLoggedIn;
21 |
22 | public static bool IsLoggedIn
23 | {
24 | get
25 | {
26 | return Nijie._isLoggedIn;
27 | }
28 | private set
29 | {
30 | Nijie._isLoggedIn = value;
31 | if (LoggingEventHandler != null)
32 | {
33 | LoggingEventHandler(null, value);
34 | }
35 | }
36 | }
37 |
38 | public bool Login(string userName, string password, bool retryLoop = false)
39 | {
40 | var info = PrepareLoginInfo(userName, password);
41 | return DoLogin(info, retryLoop);
42 | }
43 |
44 | public void Logout()
45 | {
46 | ExtendedWebClient.ClearCookie();
47 | IsLoggedIn = false;
48 | }
49 |
50 | public void LoginAsync(string userName, string password, Action callback)
51 | {
52 | var task = Task.Factory.StartNew(() => Login(userName, password));
53 | task.ContinueWith(x =>
54 | {
55 | try
56 | {
57 | if (x.Result)
58 | callback(x.Result, "Login Success.");
59 | else
60 | callback(x.Result, "Invalid username or password or require age verification.");
61 | }
62 | catch (AggregateException ex)
63 | {
64 | callback(false, "Error: " + ex.InnerException.Message);
65 | }
66 | }, TaskScheduler.FromCurrentSynchronizationContext());
67 | }
68 |
69 | private void PrintCookie(string header)
70 | {
71 | Debug.WriteLine(header);
72 | var uri = new Uri(Util.FixUrl("//nijie.info", ROOT_DOMAIN, Properties.Settings.Default.UseHttps));
73 | foreach (Cookie item in ExtendedWebClient.CookieJar.GetCookies(uri))
74 | {
75 | Debug.WriteLine("\tSite: {0} ==> {1}: {2}", item.Domain, item.Name, item.Value);
76 | }
77 | }
78 |
79 | private NijieLoginInfo PrepareLoginInfo(string userName, string password)
80 | {
81 | ExtendedWebClient client = new ExtendedWebClient();
82 |
83 | // not really used
84 | var uri = new Uri(Util.FixUrl("//nijie.info", ROOT_DOMAIN, Properties.Settings.Default.UseHttps));
85 | var tick = ((int)Util.DateTimeToUnixTimestamp(DateTime.Now)).ToString();
86 | ExtendedWebClient.CookieJar.Add(uri, new Cookie("nijie_token_secret", tick));
87 | ExtendedWebClient.CookieJar.Add(uri, new Cookie("nijie_token", tick));
88 |
89 | NijieLoginInfo info = new NijieLoginInfo() { UserName = userName, Password = password, ReturnUrl = "", Ticket = "", RememberLogin = true };
90 |
91 | HtmlDocument doc = getPage(Util.FixUrl(NijieConstants.NIJIE_LOGIN_URL, ROOT_DOMAIN, Properties.Settings.Default.UseHttps)).Item1;
92 |
93 | var tickets = doc.DocumentNode.SelectNodes("//input[@name='ticket']");
94 | if (tickets != null && tickets.Count > 0)
95 | info.Ticket = tickets[0].Attributes["value"].Value;
96 |
97 | var returnUrls = doc.DocumentNode.SelectNodes("//input[@name='url']");
98 | if (returnUrls != null && returnUrls.Count > 0)
99 | info.ReturnUrl = returnUrls[0].Attributes["value"].Value;
100 |
101 | PrintCookie("Prepare Login:");
102 |
103 | return info;
104 | }
105 |
106 | private bool DoLogin(NijieLoginInfo info, bool retryLoop = false)
107 | {
108 | IsLoggedIn = false;
109 | ExtendedWebClient client = new ExtendedWebClient();
110 | NameValueCollection loginInfo = new NameValueCollection();
111 | loginInfo.Add("email", info.UserName);
112 | loginInfo.Add("password", info.Password);
113 | if (info.RememberLogin)
114 | loginInfo.Add("save", "on");
115 | loginInfo.Add("ticket", info.Ticket);
116 | loginInfo.Add("url", info.ReturnUrl);
117 |
118 | var result = client.UploadValues(Util.FixUrl(NijieConstants.NIJIE_LOGIN_URL2, ROOT_DOMAIN, Properties.Settings.Default.UseHttps), "POST", loginInfo);
119 | //String data = Encoding.UTF8.GetString(result);
120 |
121 | var location = client.Response.ResponseUri.ToString();
122 | if (!String.IsNullOrWhiteSpace(location))
123 | {
124 | if (location.Contains(@"//nijie.info/login.php?"))
125 | {
126 | IsLoggedIn = false;
127 | }
128 | else if (location.Contains(@"//nijie.info/age_ver.php?"))
129 | {
130 | Debug.WriteLine("Please perform age verification");
131 | IsLoggedIn = false;
132 | if (!retryLoop)
133 | {
134 | Login(info.UserName, info.Password, true);
135 | }
136 | }
137 | else
138 | {
139 | IsLoggedIn = true;
140 | }
141 | }
142 |
143 | var uri = new Uri(Util.FixUrl("//nijie.info", ROOT_DOMAIN, Properties.Settings.Default.UseHttps));
144 | ExtendedWebClient.CookieJar.Add(uri, new Cookie("R18", "1"));
145 | var cookies = ExtendedWebClient.CookieJar.GetCookies(uri);
146 | foreach (Cookie item in cookies)
147 | {
148 | //Cookie: NIJIEIJIEID=lp1ffmjc9gi7a3u9qkj8p566u3
149 | if (item.Name == "NIJIEIJIEID")
150 | {
151 | NijieSessionID = item.Value;
152 | item.Expires = DateTime.MaxValue;
153 | break;
154 | }
155 | }
156 |
157 | PrintCookie("Login:");
158 |
159 | return IsLoggedIn;
160 | }
161 | }
162 | }
--------------------------------------------------------------------------------
/NijieDownloader.Library/NijieConstants.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace NijieDownloader.Library
7 | {
8 | public class NijieConstants
9 | {
10 | public const String NIJIE_URLx = "//nijie.info/";
11 | public const String NIJIE_INDEXx = "//nijie.info/index.php";
12 |
13 | public const String NIJIE_LOGIN_URL = "//nijie.info/login.php";
14 | public const String NIJIE_LOGIN_URL2 = "//nijie.info/login_int.php";
15 |
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/NijieException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace NijieDownloader.Library
7 | {
8 | public class NijieException : Exception
9 | {
10 | public const int OK = 0;
11 | public const int CANCELLED = 1;
12 | public const int NOT_LOGGED_IN = 1000;
13 | public const int DOWNLOAD_ERROR = 1001;
14 | public const int INVALID_SAVE_FILENAME_FORMAT = 1002;
15 | public const int RENAME_ERROR = 1003;
16 | public const int DOWNLOAD_SKIPPED = 1004;
17 | public const int DB_ERROR = 1005;
18 | public const int DOWNLOAD_CANCELLED = 1006;
19 | public const int DOWNLOAD_UNKNOWN_ERROR = 1999;
20 |
21 | public const int MEMBER_REDIR = 2000;
22 | public const int MEMBER_UNKNOWN_ERROR = 2999;
23 |
24 | public const int IMAGE_UNKNOWN_ERROR = 3999;
25 | public const int IMAGE_NOT_FOUND = 3001;
26 | public const int IMAGE_BIG_PARSE_ERROR = 3002;
27 |
28 | public const int SEARCH_UNKNOWN_ERROR = 4999;
29 |
30 | #region ctor
31 |
32 | public NijieException(string message, int errorCode)
33 | : base(message)
34 | {
35 | this.ErrorCode = errorCode;
36 | }
37 |
38 | public NijieException(string message, Exception innerException, int errorCode)
39 | : base(message, innerException)
40 | {
41 | this.ErrorCode = errorCode;
42 | }
43 |
44 | #endregion ctor
45 |
46 | public int ErrorCode { get; set; }
47 |
48 | public int MemberId { get; set; }
49 |
50 | public int ImageId { get; set; }
51 |
52 | public string Query { get; set; }
53 |
54 | public override string ToString()
55 | {
56 | return string.Format("[{0}] {1}", ErrorCode, Message);
57 | }
58 |
59 | public string Url { get; set; }
60 |
61 | public string Filename { get; set; }
62 | }
63 | }
--------------------------------------------------------------------------------
/NijieDownloader.Library/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("NijieDownloader.Library")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("NijieDownloader.Library")]
13 | [assembly: AssemblyCopyright("Copyright © Nandaka 2014-2021")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("16ddf404-4554-480a-93c2-af1b36d416ee")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.9.6")]
36 | [assembly: AssemblyFileVersion("1.0.9.6")]
37 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace NijieDownloader.Library.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
16 | public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
29 | public bool UseHttps {
30 | get {
31 | return ((bool)(this["UseHttps"]));
32 | }
33 | set {
34 | this["UseHttps"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("3")]
41 | public int RetryCount {
42 | get {
43 | return ((int)(this["RetryCount"]));
44 | }
45 | set {
46 | this["RetryCount"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.UserScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
53 | public bool MakeBackup {
54 | get {
55 | return ((bool)(this["MakeBackup"]));
56 | }
57 | set {
58 | this["MakeBackup"] = value;
59 | }
60 | }
61 |
62 | [global::System.Configuration.UserScopedSettingAttribute()]
63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
64 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
65 | public bool Overwrite {
66 | get {
67 | return ((bool)(this["Overwrite"]));
68 | }
69 | set {
70 | this["Overwrite"] = value;
71 | }
72 | }
73 |
74 | [global::System.Configuration.UserScopedSettingAttribute()]
75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
76 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
77 | public bool OverwriteOnlyIfDifferentSize {
78 | get {
79 | return ((bool)(this["OverwriteOnlyIfDifferentSize"]));
80 | }
81 | set {
82 | this["OverwriteOnlyIfDifferentSize"] = value;
83 | }
84 | }
85 |
86 | [global::System.Configuration.UserScopedSettingAttribute()]
87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
88 | [global::System.Configuration.DefaultSettingValueAttribute("60")]
89 | public int RetryDelay {
90 | get {
91 | return ((int)(this["RetryDelay"]));
92 | }
93 | set {
94 | this["RetryDelay"] = value;
95 | }
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | True
7 |
8 |
9 | 3
10 |
11 |
12 | False
13 |
14 |
15 | False
16 |
17 |
18 | False
19 |
20 |
21 | 60
22 |
23 |
24 |
--------------------------------------------------------------------------------
/NijieDownloader.Library/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NijieDownloader.UI/App.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
41 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/NijieDownloader.UI/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Configuration;
5 | using System.Data;
6 | using System.Linq;
7 | using System.Windows;
8 |
9 | namespace NijieDownloader.UI
10 | {
11 | ///
12 | /// Interaction logic for App.xaml
13 | ///
14 | public partial class App : Application
15 | {
16 | }
17 | }
--------------------------------------------------------------------------------
/NijieDownloader.UI/ImageLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Specialized;
3 | using System.IO;
4 | using System.Runtime.Caching;
5 | using System.Threading.Tasks;
6 | using System.Windows.Media.Imaging;
7 | using Nandaka.Common;
8 | using NijieDownloader.Library;
9 | using NijieDownloader.UI.ViewModel;
10 |
11 | namespace NijieDownloader.UI
12 | {
13 | public class ImageLoader
14 | {
15 | private static ObjectCache cache;
16 | private static TaskFactory _imageFactory;
17 |
18 | public const string IMAGE_LOADING = "Loading";
19 | public const string IMAGE_LOADED = "Done";
20 | public const string IMAGE_ERROR = "Error";
21 | public const string IMAGE_QUEUED = "Queued";
22 |
23 | ///
24 | /// Init the ImageLoader, changes on these settings require app restart:
25 | /// - ConcurrentImageLoad
26 | /// - cacheMemoryLimitMegabytes
27 | ///
28 | static ImageLoader()
29 | {
30 | configureCache();
31 | _imageFactory = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(Properties.Settings.Default.ConcurrentImageLoad, 8));
32 | }
33 |
34 | private static void configureCache()
35 | {
36 | var config = new NameValueCollection();
37 | config.Add("pollingInterval", "00:05:00");
38 | config.Add("physicalMemoryLimitPercentage", "0");
39 | config.Add("cacheMemoryLimitMegabytes", Properties.Settings.Default.cacheMemoryLimitMegabytes);
40 | cache = new MemoryCache("CustomCache", config);
41 | }
42 |
43 | ///
44 | /// Load image from cache if available, else start new task to download the image.
45 | ///
46 | ///
47 | ///
48 | ///
49 | public static void LoadImage(string url, string referer, Action action)
50 | {
51 | if (String.IsNullOrWhiteSpace(url)) return;
52 | url = Util.FixUrl(url, Nijie.ROOT_DOMAIN);
53 | referer = Util.FixUrl(referer, Nijie.ROOT_DOMAIN);
54 |
55 | if (!cache.Contains(url))
56 | {
57 | _imageFactory.StartNew(() =>
58 | {
59 | try
60 | {
61 | action(ViewModelHelper.Loading, IMAGE_LOADING);
62 |
63 | MainWindow.Log.Debug("Loading image: " + url);
64 | #if DEBUG
65 | var result = File.ReadAllBytes(@"../../Resources/error_icon.png");
66 | #else
67 | var result = MainWindow.Bot.DownloadData(url, referer);
68 | #endif
69 | using (var ms = new MemoryStream(result))
70 | {
71 | var t = new BitmapImage();
72 | t.BeginInit();
73 | t.CacheOption = BitmapCacheOption.OnLoad;
74 | t.StreamSource = ms;
75 | t.EndInit();
76 | t.Freeze();
77 | action(t, IMAGE_LOADED);
78 |
79 | CacheItemPolicy policy = new CacheItemPolicy();
80 | policy.SlidingExpiration = new TimeSpan(1, 0, 0);
81 |
82 | cache.Set(url, t, policy);
83 | }
84 | }
85 | catch (Exception ex)
86 | {
87 | action(null, IMAGE_ERROR);
88 |
89 | MainWindow.Log.Error(String.Format("Error when loading image: {0}", ex.Message), ex);
90 | if (ex.InnerException != null)
91 | MainWindow.Log.Error(ex.InnerException.Message, ex.InnerException);
92 | }
93 | });
94 | }
95 | else
96 | {
97 | MainWindow.Log.Debug("Loaded from cache: " + url);
98 | action((BitmapImage)cache.Get(url), IMAGE_LOADED);
99 | }
100 | }
101 | }
102 | }
--------------------------------------------------------------------------------
/NijieDownloader.UI/JobStatusToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows.Data;
6 | using NijieDownloader.UI.ViewModel;
7 | using System.Windows;
8 |
9 | namespace NijieDownloader.UI
10 | {
11 | public class JobStatusToVisibilityConverter : IValueConverter
12 | {
13 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
14 | {
15 | JobStatus val = (JobStatus)value;
16 |
17 | if (targetType == typeof(Visibility))
18 | {
19 | if (val == JobStatus.Running || val == JobStatus.Canceling)
20 | return Visibility.Visible;
21 | else
22 | return Visibility.Collapsed;
23 | }
24 | return Visibility.Collapsed;
25 | }
26 |
27 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
28 | {
29 | throw new NotImplementedException();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/NijieDownloader.UI/JobTypeToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows.Data;
6 | using NijieDownloader.UI.ViewModel;
7 | using System.Windows;
8 |
9 | namespace NijieDownloader.UI
10 | {
11 | public class JobTypeToVisibilityConverter: IValueConverter
12 | {
13 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
14 | {
15 | JobType val = (JobType)value;
16 |
17 | if (targetType == typeof(Visibility))
18 | {
19 | if (val.ToString() == parameter.ToString())
20 | return Visibility.Visible;
21 | else
22 | return Visibility.Collapsed;
23 | }
24 | return Visibility.Collapsed;
25 | }
26 |
27 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
28 | {
29 | throw new NotImplementedException();
30 | }
31 | }
32 |
33 | public class IsMangaToVisibilityConverter : IValueConverter
34 | {
35 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
36 | {
37 | bool isManga = (bool)value;
38 |
39 | if (targetType == typeof(Visibility))
40 | {
41 | if (isManga)
42 | return Visibility.Visible;
43 | else
44 | return Visibility.Collapsed;
45 | }
46 | return Visibility.Collapsed;
47 | }
48 |
49 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
50 | {
51 | throw new NotImplementedException();
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/NijieDownloader.UI/Main/BookmarkPage.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
22 |
25 |
28 |
31 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
45 |
47 |
49 |
50 |
51 |
53 |
54 |
56 |
57 |
58 |
59 |
60 |
63 |
64 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/NijieDownloader.UI/Main/ImagePage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 | using FirstFloor.ModernUI.Windows;
16 | using FirstFloor.ModernUI.Windows.Controls;
17 | using FirstFloor.ModernUI.Windows.Navigation;
18 | using NijieDownloader.Library;
19 | using NijieDownloader.Library.DAL;
20 | using NijieDownloader.UI.ViewModel;
21 | using System.Windows.Threading;
22 | using System.Windows.Media.Animation;
23 |
24 | namespace NijieDownloader.UI
25 | {
26 | ///
27 | /// Interaction logic for ImagePage.xaml
28 | ///
29 | public partial class ImagePage : Page, IContent
30 | {
31 | public NijieImageViewModel ViewData { get; set; }
32 |
33 | private DispatcherTimer timer;
34 |
35 | public ImagePage()
36 | {
37 | ViewData = new NijieImageViewModel();
38 | InitializeComponent();
39 | #if DEBUG
40 |
41 | //iewData.ImageId = 15880;
42 | ViewData.ImageId = 67940;
43 | #endif
44 | this.DataContext = ViewData;
45 |
46 | timer = new DispatcherTimer();
47 | timer.Interval = TimeSpan.FromSeconds(1);
48 | timer.Tick += timer_Tick;
49 |
50 | //if (ViewData.IsVideo != Visibility.Collapsed)
51 | //{
52 | video.MediaEnded += Video_MediaEnded;
53 | video.MediaOpened += Video_MediaOpened;
54 | //}
55 | //else
56 | //{
57 | // video.MediaEnded -= Video_MediaEnded;
58 | // video.MediaOpened -= Video_MediaOpened;
59 | //}
60 | }
61 |
62 | #region navigation
63 |
64 | public void OnFragmentNavigation(FirstFloor.ModernUI.Windows.Navigation.FragmentNavigationEventArgs e)
65 | {
66 | if (!String.IsNullOrWhiteSpace(e.Fragment))
67 | {
68 | var uri = new Uri("http://localhost/?" + e.Fragment);
69 | var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
70 |
71 | txtImageID.Text = query.Get("ImageId");
72 | ViewData.ImageId = Int32.Parse(txtImageID.Text);
73 | GetImageCommand.Execute(null, btnFetch);
74 | }
75 | }
76 |
77 | public void OnNavigatedFrom(FirstFloor.ModernUI.Windows.Navigation.NavigationEventArgs e)
78 | {
79 | }
80 |
81 | public void OnNavigatedTo(FirstFloor.ModernUI.Windows.Navigation.NavigationEventArgs e)
82 | {
83 | }
84 |
85 | public void OnNavigatingFrom(FirstFloor.ModernUI.Windows.Navigation.NavigatingCancelEventArgs e)
86 | {
87 | }
88 |
89 | #endregion navigation
90 |
91 | #region UI events
92 |
93 | private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
94 | {
95 | var h = MainWindow.GetWindow(imgBigImage).Height - 200;
96 | if (h <= 0) h = 1;
97 | imgBigImage.Height = h;
98 | lbxMangaThumb.Height = h;
99 | }
100 |
101 | private void lblMember_MouseDown(object sender, MouseButtonEventArgs e)
102 | {
103 | e.Handled = MainWindow.NavigateTo(this, "/Main/MemberPage.xaml#memberId=" + lblMember.Content);
104 | }
105 |
106 | private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
107 | {
108 | e.Handled = MainWindow.NavigateTo(this, "/Main/SearchPage.xaml#query=" + e.Uri.OriginalString);
109 | }
110 |
111 | #endregion UI events
112 |
113 | #region Commands
114 |
115 | public static RoutedCommand GetImageCommand = new RoutedCommand();
116 |
117 | private void ExecuteGetImageCommand(object sender, ExecutedRoutedEventArgs e)
118 | {
119 | ViewData = new NijieImageViewModel() { ImageId = ViewData.ImageId };
120 | ModernDialog d = new ModernDialog();
121 | d.Content = "Loading data...";
122 | //d.Closed += new EventHandler((s, ex) => { ViewData.Message = "Still loading..."; });
123 | System.Threading.ThreadPool.QueueUserWorkItem(
124 | (x) =>
125 | {
126 | ViewData.GetImage();
127 | this.Dispatcher.BeginInvoke(
128 | new Action((y) =>
129 | {
130 | this.DataContext = ViewData;
131 | d.Close();
132 | //ViewData.Message = "Image(s) Loaded";
133 | }),
134 | new object[] { this }
135 | );
136 | }, null
137 | );
138 |
139 | d.ShowDialog();
140 | }
141 |
142 | public static RoutedCommand AddToBatchCommand = new RoutedCommand();
143 |
144 | private void ExecuteAddToBatchCommand(object sender, ExecutedRoutedEventArgs e)
145 | {
146 | e.Handled = MainWindow.NavigateTo(this, "/Main/BatchDownloadPage.xaml#type=image&imageId=" + ViewData.ImageId);
147 | }
148 |
149 | private void CanExecuteImageCommand(object sender, CanExecuteRoutedEventArgs e)
150 | {
151 | e.CanExecute = !Validation.GetHasError(txtImageID) && ViewData.ImageId > 0 ? true : false;
152 | }
153 |
154 | public static RoutedCommand MangaPrevCommand = new RoutedCommand();
155 |
156 | private void ExecuteMangaPrevCommand(object sender, ExecutedRoutedEventArgs e)
157 | {
158 | lbxMangaThumb.SelectedIndex = ViewData.Prev();
159 | }
160 |
161 | public static RoutedCommand MangaNextCommand = new RoutedCommand();
162 |
163 | private void ExecuteMangaNextCommand(object sender, ExecutedRoutedEventArgs e)
164 | {
165 | lbxMangaThumb.SelectedIndex = ViewData.Next();
166 | }
167 |
168 | private void CanExecuteMangaCommand(object sender, CanExecuteRoutedEventArgs e)
169 | {
170 | e.CanExecute = ViewData.IsManga;
171 | }
172 |
173 | private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
174 | {
175 | ViewData.JumpTo(lbxMangaThumb.SelectedIndex);
176 | }
177 |
178 | // video related
179 | private void Video_MediaOpened(object sender, RoutedEventArgs e)
180 | {
181 | video.LoadedBehavior = MediaState.Manual;
182 | video.Play();
183 | timer.Start();
184 | }
185 |
186 | private void Video_MediaEnded(object sender, RoutedEventArgs e)
187 | {
188 | if (chkRepeat.IsChecked.Value)
189 | video.Position = TimeSpan.FromMilliseconds(1);
190 | }
191 |
192 | private void btnPlay_Click(object sender, RoutedEventArgs e)
193 | {
194 | video.Play();
195 | timer.Start();
196 | }
197 |
198 | private void timer_Tick(object sender, EventArgs e)
199 | {
200 | if (video.Source != null)
201 | {
202 | if (video.NaturalDuration.HasTimeSpan)
203 | lblStatus.Content = String.Format("{0} / {1}", video.Position.ToString(@"mm\:ss"), video.NaturalDuration.TimeSpan.ToString(@"mm\:ss"));
204 | }
205 | else
206 | lblStatus.Content = "";
207 | }
208 |
209 | private void btnPause_Click(object sender, RoutedEventArgs e)
210 | {
211 | video.Pause();
212 | }
213 |
214 | private void btnStop_Click(object sender, RoutedEventArgs e)
215 | {
216 | video.Stop();
217 | timer.Stop();
218 | }
219 |
220 | #endregion Commands
221 | }
222 | }
--------------------------------------------------------------------------------
/NijieDownloader.UI/Main/Popup/AddJobPopup.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows;
6 | using System.Windows.Controls;
7 | using System.Windows.Data;
8 | using System.Windows.Documents;
9 | using System.Windows.Input;
10 | using System.Windows.Media;
11 | using System.Windows.Media.Imaging;
12 | using System.Windows.Navigation;
13 | using System.Windows.Shapes;
14 | using FirstFloor.ModernUI.Windows.Controls;
15 | using NijieDownloader.UI.ViewModel;
16 |
17 | namespace NijieDownloader.UI.Main.Popup
18 | {
19 | ///
20 | /// Interaction logic for AddJob.xaml
21 | ///
22 | public partial class AddJob : Page
23 | {
24 | public JobDownloadViewModel NewJob { get; private set; }
25 |
26 | public List