implement yande.re source
This commit is contained in:
		| @@ -4,6 +4,8 @@ using Xamarin.Essentials; | |||||||
| using Gallery.Resources; | using Gallery.Resources; | ||||||
| using Gallery.Util; | using Gallery.Util; | ||||||
| using Gallery.Resources.Theme; | using Gallery.Resources.Theme; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using Gallery.Util.Interface; | ||||||
|  |  | ||||||
| namespace Gallery | namespace Gallery | ||||||
| { | { | ||||||
| @@ -12,8 +14,19 @@ namespace Gallery | |||||||
|         public static AppTheme CurrentTheme { get; private set; } |         public static AppTheme CurrentTheme { get; private set; } | ||||||
|         public static PlatformCulture CurrentCulture { get; private set; } |         public static PlatformCulture CurrentCulture { get; private set; } | ||||||
|  |  | ||||||
|  |         public static List<IGallerySource> GallerySources { get; } = new() | ||||||
|  |         { | ||||||
|  |             new Yandere.GallerySource(),    // https://yande.re | ||||||
|  |             new Danbooru.GallerySource(),   // https://danbooru.donmai.us | ||||||
|  |             new Gelbooru.GallerySource()    // https://gelbooru.com | ||||||
|  |         }; | ||||||
|  |  | ||||||
|         public App() |         public App() | ||||||
|         { |         { | ||||||
|  |             Preferences.Set(Config.IsProxiedKey, true); | ||||||
|  |             Preferences.Set(Config.ProxyHostKey, "192.168.25.9"); | ||||||
|  |             Preferences.Set(Config.ProxyPortKey, 1081); | ||||||
|  |  | ||||||
|             DependencyService.Register<MockDataStore>(); |             DependencyService.Register<MockDataStore>(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -25,7 +38,33 @@ namespace Gallery | |||||||
|  |  | ||||||
|         private void InitPreference() |         private void InitPreference() | ||||||
|         { |         { | ||||||
|  |             Config.Proxy = null; | ||||||
|  |  | ||||||
|  |             var isProxied = Preferences.Get(Config.IsProxiedKey, false); | ||||||
|  |             if (isProxied) | ||||||
|  |             { | ||||||
|  |                 var host = Preferences.Get(Config.ProxyHostKey, null); | ||||||
|  |                 var port = Preferences.Get(Config.ProxyPortKey, 0); | ||||||
|  |                 if (!string.IsNullOrEmpty(host) && port > 0) | ||||||
|  |                 { | ||||||
|  |                     try | ||||||
|  |                     { | ||||||
|  |                         if (host.IndexOf(':') >= 0) | ||||||
|  |                         { | ||||||
|  |                             host = $"[{host}]"; | ||||||
|  |                         } | ||||||
|  |                         var uri = new System.Uri($"http://{host}:{port}"); | ||||||
|  |                         Config.Proxy = new System.Net.WebProxy(uri, true); | ||||||
|  | #if DEBUG | ||||||
|  |                         Log.Print($"load proxy: {uri}"); | ||||||
|  | #endif | ||||||
|  |                     } | ||||||
|  |                     catch (System.Exception ex) | ||||||
|  |                     { | ||||||
|  |                         Log.Error("preferences.init", $"failed to parse proxy: {host}:{port}, error: {ex.Message}"); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void InitLanguage() |         private void InitLanguage() | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| using System; | using System; | ||||||
| using System.ComponentModel; | using System.ComponentModel; | ||||||
|  | using Gallery.Util; | ||||||
| using Xamarin.Forms; | using Xamarin.Forms; | ||||||
| using Xamarin.Forms.Xaml; | using Xamarin.Forms.Xaml; | ||||||
|  |  | ||||||
| @@ -11,5 +12,20 @@ namespace Gallery.Views | |||||||
|         { |         { | ||||||
|             InitializeComponent(); |             InitializeComponent(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         protected override async void OnAppearing() | ||||||
|  |         { | ||||||
|  |             base.OnAppearing(); | ||||||
|  |  | ||||||
|  |             var result = await App.GallerySources[0].GetRecentItemsAsync(1); | ||||||
|  |             if (result != null) | ||||||
|  |             { | ||||||
|  |                 for (var i = 0; i < result.Length; i++) | ||||||
|  |                 { | ||||||
|  |                     var item = result[i]; | ||||||
|  |                     Log.Print($"id: {item.Id}, url: {item.RawUrl}"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -95,5 +95,17 @@ namespace Gallery.Util | |||||||
|             } |             } | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public static DateTime ToLocalTime(this long time) | ||||||
|  |         { | ||||||
|  |             //return new DateTime(1970, 1, 1, 0, 0, 0).AddMilliseconds(time).ToLocalTime(); | ||||||
|  |             return new DateTime(621355968000000000L + time * 10000).ToLocalTime(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static long ToTimestamp(this DateTime datetime) | ||||||
|  |         { | ||||||
|  |             var ticks = datetime.Ticks; | ||||||
|  |             return (ticks - 621355968000000000L) / 10000; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -17,10 +17,12 @@ | |||||||
|     <None Remove="Xamarin.Forms" /> |     <None Remove="Xamarin.Forms" /> | ||||||
|     <None Remove="Interface\" /> |     <None Remove="Interface\" /> | ||||||
|     <None Remove="Model\" /> |     <None Remove="Model\" /> | ||||||
|  |     <None Remove="Xamarin.Essentials" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="System.Text.Json" Version="5.0.2" /> |     <PackageReference Include="System.Text.Json" Version="5.0.2" /> | ||||||
|     <PackageReference Include="Xamarin.Forms" Version="5.0.0.2083" /> |     <PackageReference Include="Xamarin.Forms" Version="5.0.0.2083" /> | ||||||
|  |     <PackageReference Include="Xamarin.Essentials" Version="1.7.0" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <Folder Include="Interface\" /> |     <Folder Include="Interface\" /> | ||||||
|   | |||||||
| @@ -1,11 +1,16 @@ | |||||||
| using Gallery.Util.Model; | using System.Threading.Tasks; | ||||||
|  | using Gallery.Util.Model; | ||||||
|  |  | ||||||
| namespace Gallery.Util.Interface | namespace Gallery.Util.Interface | ||||||
| { | { | ||||||
|     public interface IGallerySource |     public interface IGallerySource | ||||||
|     { |     { | ||||||
|  |         string Name { get; } | ||||||
|  |  | ||||||
|  |         string HomePage { get; } | ||||||
|  |  | ||||||
|         void SetCookie(); |         void SetCookie(); | ||||||
|  |  | ||||||
|         GalleryItem[] GetRecentItems(int page); |         Task<GalleryItem[]> GetRecentItemsAsync(int page); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -75,5 +75,18 @@ namespace Gallery.Util.Model | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         internal GalleryItem() { } | ||||||
|  |  | ||||||
|  |         public GalleryItem(long id) | ||||||
|  |         { | ||||||
|  |             Id = id; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override string ToString() | ||||||
|  |         { | ||||||
|  |             var source = string.IsNullOrEmpty(Source) ? RawUrl : Source; | ||||||
|  |             return $"{Id}, {source}"; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										149
									
								
								Gallery.Util/NetHelper.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								Gallery.Util/NetHelper.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | |||||||
|  | using System; | ||||||
|  | using System.Net.Http; | ||||||
|  | using System.Net.Http.Headers; | ||||||
|  | using System.Text.Json; | ||||||
|  | using System.Threading; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | using Xamarin.Essentials; | ||||||
|  |  | ||||||
|  | namespace Gallery.Util | ||||||
|  | { | ||||||
|  |     public static class NetHelper | ||||||
|  |     { | ||||||
|  |         public static bool NetworkAvailable | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 try | ||||||
|  |                 { | ||||||
|  |                     return Connectivity.NetworkAccess == NetworkAccess.Internet | ||||||
|  |                         || Connectivity.NetworkAccess == NetworkAccess.ConstrainedInternet; | ||||||
|  |                 } | ||||||
|  |                 catch | ||||||
|  |                 { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static async Task<(T result, string error)> RequestObject<T>(string url, | ||||||
|  |             string referer = null, | ||||||
|  |             HttpContent post = null, | ||||||
|  |             Action<HttpRequestHeaders> headerHandler = null, | ||||||
|  |             Func<string, string> contentHandler = null, | ||||||
|  |             Func<string, T> @return = null) | ||||||
|  |         { | ||||||
|  |             var response = await Request(url, headers => | ||||||
|  |             { | ||||||
|  |                 if (referer != null) | ||||||
|  |                 { | ||||||
|  |                     headers.Referrer = new Uri(referer); | ||||||
|  |                 } | ||||||
|  |                 headers.Add("User-Agent", Config.UserAgent); | ||||||
|  |                 headerHandler?.Invoke(headers); | ||||||
|  |             }, post); | ||||||
|  |             if (response == null) | ||||||
|  |             { | ||||||
|  |                 return (default, "response is null"); | ||||||
|  |             } | ||||||
|  |             if (!response.IsSuccessStatusCode) | ||||||
|  |             { | ||||||
|  |                 Log.Print($"http failed with code: {(int)response.StatusCode} - {response.StatusCode}"); | ||||||
|  |                 return (default, response.StatusCode.ToString()); | ||||||
|  |             } | ||||||
|  |             string content; | ||||||
|  |             using (response) | ||||||
|  |             { | ||||||
|  |                 try | ||||||
|  |                 { | ||||||
|  |                     content = await response.Content.ReadAsStringAsync(); | ||||||
|  |                     if (contentHandler != null) | ||||||
|  |                     { | ||||||
|  |                         content = contentHandler(content); | ||||||
|  |                     } | ||||||
|  |                     if (@return != null) | ||||||
|  |                     { | ||||||
|  |                         return (@return(content), null); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 catch (Exception ex) | ||||||
|  |                 { | ||||||
|  |                     Log.Error("stream.load", $"failed to read stream, error: {ex.Message}"); | ||||||
|  |                     return (default, ex.Message); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (content == null) | ||||||
|  |             { | ||||||
|  |                 content = string.Empty; | ||||||
|  |             } | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 var result = JsonSerializer.Deserialize<T>(content); | ||||||
|  |                 return (result, null); | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                 var memo = content.Length < 20 ? content : content[0..20] + "..."; | ||||||
|  |                 Log.Error("content.deserialize", $"failed to parse JSON object, content: {memo}, error: {ex.Message}"); | ||||||
|  |                 return (default, content); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static async Task<HttpResponseMessage> Request(string url, Action<HttpRequestHeaders> headerHandler, HttpContent post = null) | ||||||
|  |         { | ||||||
|  | #if DEBUG | ||||||
|  |             var method = post == null ? "GET" : "POST"; | ||||||
|  |             Log.Print($"{method}: {url}"); | ||||||
|  | #endif | ||||||
|  |             var uri = new Uri(url); | ||||||
|  |             var proxy = Config.Proxy; | ||||||
|  |             var handler = new HttpClientHandler | ||||||
|  |             { | ||||||
|  |                 AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate, | ||||||
|  |                 UseCookies = false | ||||||
|  |             }; | ||||||
|  |             if (proxy != null) | ||||||
|  |             { | ||||||
|  |                 handler.Proxy = proxy; | ||||||
|  |                 handler.UseProxy = true; | ||||||
|  |             } | ||||||
|  |             var client = new HttpClient(handler, true) | ||||||
|  |             { | ||||||
|  |                 BaseAddress = new Uri($"{uri.Scheme}://{uri.Host}:{uri.Port}"), | ||||||
|  |                 Timeout = Config.Timeout | ||||||
|  |             }; | ||||||
|  |             return await TryCount(() => | ||||||
|  |             { | ||||||
|  |                 using var request = new HttpRequestMessage(post == null ? HttpMethod.Get : HttpMethod.Post, uri.PathAndQuery); | ||||||
|  |                 var headers = request.Headers; | ||||||
|  |                 headerHandler?.Invoke(headers); | ||||||
|  |                 headers.Add("Accept-Language", Config.AcceptLanguage); | ||||||
|  |                 if (post != null) | ||||||
|  |                 { | ||||||
|  |                     request.Content = post; | ||||||
|  |                 } | ||||||
|  |                 return client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static T TryCount<T>(Func<T> func, int tryCount = 2) | ||||||
|  |         { | ||||||
|  |             int tries = 0; | ||||||
|  |             while (tries < tryCount) | ||||||
|  |             { | ||||||
|  |                 try | ||||||
|  |                 { | ||||||
|  |                     return func(); | ||||||
|  |                 } | ||||||
|  |                 catch (Exception ex) | ||||||
|  |                 { | ||||||
|  |                     tries++; | ||||||
|  |                     Thread.Sleep(1000); | ||||||
|  |                     Log.Error("try.do", $"tries: {tries}, error: {ex.Message}"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return default; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								Gallery.Util/Store.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Gallery.Util/Store.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | using System; | ||||||
|  | using System.Net; | ||||||
|  | using Xamarin.Essentials; | ||||||
|  |  | ||||||
|  | namespace Gallery.Util | ||||||
|  | { | ||||||
|  |     public static class Store | ||||||
|  |     { | ||||||
|  |         public static readonly string PersonalFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal); | ||||||
|  |         public static readonly string CacheFolder = FileSystem.CacheDirectory; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static class Config | ||||||
|  |     { | ||||||
|  |         public static readonly TimeSpan Timeout = TimeSpan.FromSeconds(30); | ||||||
|  |  | ||||||
|  |         public const string IsProxiedKey = "is_proxied"; | ||||||
|  |         public const string ProxyHostKey = "proxy_host"; | ||||||
|  |         public const string ProxyPortKey = "proxy_port"; | ||||||
|  |  | ||||||
|  |         public const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"; | ||||||
|  |         public const string AcceptLanguage = "zh-cn"; | ||||||
|  |  | ||||||
|  |         public static WebProxy Proxy; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -155,6 +155,18 @@ | |||||||
|       <Project>{222C22EC-3A47-4CF5-B9FB-CA28DE9F4BC8}</Project> |       <Project>{222C22EC-3A47-4CF5-B9FB-CA28DE9F4BC8}</Project> | ||||||
|       <Name>Gallery.Util</Name> |       <Name>Gallery.Util</Name> | ||||||
|     </ProjectReference> |     </ProjectReference> | ||||||
|  |     <ProjectReference Include="..\GallerySources\Gallery.Yandere\Gallery.Yandere.csproj"> | ||||||
|  |       <Project>{F7ECCC03-28AC-4326-B0D1-F24C08808B9F}</Project> | ||||||
|  |       <Name>Gallery.Yandere</Name> | ||||||
|  |     </ProjectReference> | ||||||
|  |     <ProjectReference Include="..\GallerySources\Gallery.Gelbooru\Gallery.Gelbooru.csproj"> | ||||||
|  |       <Project>{83760017-F2A6-4450-A4F8-8E143E800C2F}</Project> | ||||||
|  |       <Name>Gallery.Gelbooru</Name> | ||||||
|  |     </ProjectReference> | ||||||
|  |     <ProjectReference Include="..\GallerySources\Gallery.Danbooru\Gallery.Danbooru.csproj"> | ||||||
|  |       <Project>{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}</Project> | ||||||
|  |       <Name>Gallery.Danbooru</Name> | ||||||
|  |     </ProjectReference> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <Import Project="..\Gallery.Share\Gallery.Share.projitems" Label="Shared" Condition="Exists('..\Gallery.Share\Gallery.Share.projitems')" /> |   <Import Project="..\Gallery.Share\Gallery.Share.projitems" Label="Shared" Condition="Exists('..\Gallery.Share\Gallery.Share.projitems')" /> | ||||||
|   <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" /> |   <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" /> | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										30
									
								
								Gallery.sln
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								Gallery.sln
									
									
									
									
									
								
							| @@ -13,6 +13,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GallerySources", "GallerySo | |||||||
| EndProject | EndProject | ||||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gallery.Yandere", "GallerySources\Gallery.Yandere\Gallery.Yandere.csproj", "{F7ECCC03-28AC-4326-B0D1-F24C08808B9F}" | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gallery.Yandere", "GallerySources\Gallery.Yandere\Gallery.Yandere.csproj", "{F7ECCC03-28AC-4326-B0D1-F24C08808B9F}" | ||||||
| EndProject | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gallery.Danbooru", "GallerySources\Gallery.Danbooru\Gallery.Danbooru.csproj", "{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}" | ||||||
|  | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gallery.Gelbooru", "GallerySources\Gallery.Gelbooru\Gallery.Gelbooru.csproj", "{83760017-F2A6-4450-A4F8-8E143E800C2F}" | ||||||
|  | EndProject | ||||||
| Global | Global | ||||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
| 		Debug|iPhoneSimulator = Debug|iPhoneSimulator | 		Debug|iPhoneSimulator = Debug|iPhoneSimulator | ||||||
| @@ -59,6 +63,30 @@ Global | |||||||
| 		{F7ECCC03-28AC-4326-B0D1-F24C08808B9F}.Debug|Any CPU.Build.0 = Debug|Any CPU | 		{F7ECCC03-28AC-4326-B0D1-F24C08808B9F}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
| 		{F7ECCC03-28AC-4326-B0D1-F24C08808B9F}.Release|Any CPU.ActiveCfg = Release|Any CPU | 		{F7ECCC03-28AC-4326-B0D1-F24C08808B9F}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
| 		{F7ECCC03-28AC-4326-B0D1-F24C08808B9F}.Release|Any CPU.Build.0 = Release|Any CPU | 		{F7ECCC03-28AC-4326-B0D1-F24C08808B9F}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Release|iPhoneSimulator.Build.0 = Release|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Debug|iPhone.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Debug|iPhone.Build.0 = Debug|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Release|iPhone.ActiveCfg = Release|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Release|iPhone.Build.0 = Release|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Debug|iPhone.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Debug|iPhone.Build.0 = Debug|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Release|iPhone.ActiveCfg = Release|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Release|iPhone.Build.0 = Release|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
| 	EndGlobalSection | 	EndGlobalSection | ||||||
| 	GlobalSection(SolutionProperties) = preSolution | 	GlobalSection(SolutionProperties) = preSolution | ||||||
| 		HideSolutionNode = FALSE | 		HideSolutionNode = FALSE | ||||||
| @@ -68,5 +96,7 @@ Global | |||||||
| 	EndGlobalSection | 	EndGlobalSection | ||||||
| 	GlobalSection(NestedProjects) = preSolution | 	GlobalSection(NestedProjects) = preSolution | ||||||
| 		{F7ECCC03-28AC-4326-B0D1-F24C08808B9F} = {F37B4FEC-D2B1-4289-BA6D-A154F783572A} | 		{F7ECCC03-28AC-4326-B0D1-F24C08808B9F} = {F37B4FEC-D2B1-4289-BA6D-A154F783572A} | ||||||
|  | 		{F9187AE4-BC64-4906-9CAF-89BE43CD4A34} = {F37B4FEC-D2B1-4289-BA6D-A154F783572A} | ||||||
|  | 		{83760017-F2A6-4450-A4F8-8E143E800C2F} = {F37B4FEC-D2B1-4289-BA6D-A154F783572A} | ||||||
| 	EndGlobalSection | 	EndGlobalSection | ||||||
| EndGlobal | EndGlobal | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								GallerySources/Gallery.Danbooru/Gallery.Danbooru.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								GallerySources/Gallery.Danbooru/Gallery.Danbooru.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
|  |  | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <TargetFramework>netstandard2.1</TargetFramework> | ||||||
|  |   </PropertyGroup> | ||||||
|  |  | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||||
|  |     <LangVersion>9.0</LangVersion> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||||||
|  |     <LangVersion>9.0</LangVersion> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ProjectReference Include="..\..\Gallery.Util\Gallery.Util.csproj" /> | ||||||
|  |   </ItemGroup> | ||||||
|  | </Project> | ||||||
							
								
								
									
										24
									
								
								GallerySources/Gallery.Danbooru/GallerySource.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								GallerySources/Gallery.Danbooru/GallerySource.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | using System; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | using Gallery.Util.Interface; | ||||||
|  | using Gallery.Util.Model; | ||||||
|  |  | ||||||
|  | namespace Gallery.Danbooru | ||||||
|  | { | ||||||
|  |     public class GallerySource : IGallerySource | ||||||
|  |     { | ||||||
|  |         public string Name => "Danbooru"; | ||||||
|  |  | ||||||
|  |         public string HomePage => "https://danbooru.donmai.us"; | ||||||
|  |  | ||||||
|  |         public Task<GalleryItem[]> GetRecentItemsAsync(int page) | ||||||
|  |         { | ||||||
|  |             throw new NotImplementedException(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void SetCookie() | ||||||
|  |         { | ||||||
|  |             throw new NotImplementedException(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								GallerySources/Gallery.Gelbooru/Gallery.Gelbooru.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								GallerySources/Gallery.Gelbooru/Gallery.Gelbooru.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
|  |  | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <TargetFramework>netstandard2.1</TargetFramework> | ||||||
|  |   </PropertyGroup> | ||||||
|  |  | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||||
|  |     <LangVersion>9.0</LangVersion> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||||||
|  |     <LangVersion>9.0</LangVersion> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ProjectReference Include="..\..\Gallery.Util\Gallery.Util.csproj" /> | ||||||
|  |   </ItemGroup> | ||||||
|  | </Project> | ||||||
							
								
								
									
										24
									
								
								GallerySources/Gallery.Gelbooru/GallerySource.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								GallerySources/Gallery.Gelbooru/GallerySource.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | using System; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | using Gallery.Util.Interface; | ||||||
|  | using Gallery.Util.Model; | ||||||
|  |  | ||||||
|  | namespace Gallery.Gelbooru | ||||||
|  | { | ||||||
|  |     public class GallerySource : IGallerySource | ||||||
|  |     { | ||||||
|  |         public string Name => "Gelbooru"; | ||||||
|  |  | ||||||
|  |         public string HomePage => "https://gelbooru.com"; | ||||||
|  |  | ||||||
|  |         public Task<GalleryItem[]> GetRecentItemsAsync(int page) | ||||||
|  |         { | ||||||
|  |             throw new NotImplementedException(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void SetCookie() | ||||||
|  |         { | ||||||
|  |             throw new NotImplementedException(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -4,6 +4,12 @@ | |||||||
|     <TargetFramework>netstandard2.1</TargetFramework> |     <TargetFramework>netstandard2.1</TargetFramework> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|  |  | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||||
|  |     <LangVersion>9.0</LangVersion> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||||||
|  |     <LangVersion>9.0</LangVersion> | ||||||
|  |   </PropertyGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ProjectReference Include="..\..\Gallery.Util\Gallery.Util.csproj" /> |     <ProjectReference Include="..\..\Gallery.Util\Gallery.Util.csproj" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   | |||||||
							
								
								
									
										65
									
								
								GallerySources/Gallery.Yandere/GallerySource.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								GallerySources/Gallery.Yandere/GallerySource.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | using System; | ||||||
|  | using System.Text.RegularExpressions; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | using Gallery.Util; | ||||||
|  | using Gallery.Util.Interface; | ||||||
|  | using Gallery.Util.Model; | ||||||
|  |  | ||||||
|  | namespace Gallery.Yandere | ||||||
|  | { | ||||||
|  |     public class GallerySource : IGallerySource | ||||||
|  |     { | ||||||
|  |         public string Name => "Yande.re"; | ||||||
|  |         public string HomePage => "https://yande.re"; | ||||||
|  |  | ||||||
|  |         public async Task<GalleryItem[]> GetRecentItemsAsync(int page) | ||||||
|  |         { | ||||||
|  |             var url = $"https://yande.re/post?page={page}"; | ||||||
|  |             var (result, error) = await NetHelper.RequestObject<YandereItem[]>(url, contentHandler: ContentHandler); | ||||||
|  |  | ||||||
|  |             if (result == null || !string.IsNullOrEmpty(error)) | ||||||
|  |             { | ||||||
|  |                 Log.Error("yandere.content.load", $"failed to load content array, error: {error}"); | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             var items = new GalleryItem[result.Length]; | ||||||
|  |             for (var i = 0; i < items.Length; i++) | ||||||
|  |             { | ||||||
|  |                 var y = result[i]; | ||||||
|  |                 var item = new GalleryItem(y.id) | ||||||
|  |                 { | ||||||
|  |                     Tags = y.tags?.Split(' '), | ||||||
|  |                     CreatedTime = y.created_at.ToLocalTime(), | ||||||
|  |                     UpdatedTime = y.updated_at.ToLocalTime(), | ||||||
|  |                     UserId = y.creator_id.ToString(), | ||||||
|  |                     UserName = y.author, | ||||||
|  |                     Source = y.source, | ||||||
|  |                     PreviewUrl = y.preview_url, | ||||||
|  |                     RawUrl = y.file_url, | ||||||
|  |                     Width = y.width, | ||||||
|  |                     Height = y.height | ||||||
|  |                 }; | ||||||
|  |                 items[i] = item; | ||||||
|  |             } | ||||||
|  |             return items; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private string ContentHandler(string content) | ||||||
|  |         { | ||||||
|  |             var regex = new Regex(@"Post\.register\((\{.+\})\)\s*$", RegexOptions.Multiline); | ||||||
|  |             var matches = regex.Matches(content); | ||||||
|  |             var array = new string[matches.Count]; | ||||||
|  |             for (var i = 0; i < array.Length; i++) | ||||||
|  |             { | ||||||
|  |                 array[i] = matches[i].Groups[1].Value; | ||||||
|  |             } | ||||||
|  |             return $"[{string.Join(',', array)}]"; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void SetCookie() | ||||||
|  |         { | ||||||
|  |             throw new NotImplementedException(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								GallerySources/Gallery.Yandere/YandereItem.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								GallerySources/Gallery.Yandere/YandereItem.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | using System; | ||||||
|  |  | ||||||
|  | namespace Gallery.Yandere | ||||||
|  | { | ||||||
|  |     public class YandereItem | ||||||
|  |     { | ||||||
|  | #pragma warning disable IDE1006 // Naming Styles | ||||||
|  |  | ||||||
|  |         public long id { get; set; } | ||||||
|  |         public string tags { get; set; } | ||||||
|  |         public long created_at { get; set; } | ||||||
|  |         public long updated_at { get; set; } | ||||||
|  |         public long creator_id { get; set; } | ||||||
|  |         public string author { get; set; } | ||||||
|  |         public string source { get; set; } | ||||||
|  |         public int score { get; set; } | ||||||
|  |         public int file_size { get; set; } | ||||||
|  |         public string file_ext { get; set; } | ||||||
|  |         public string file_url { get; set; } | ||||||
|  |         public string preview_url { get; set; } | ||||||
|  |         public int actual_preview_width { get; set; } | ||||||
|  |         public int actual_preview_height { get; set; } | ||||||
|  |         public string rating { get; set; } | ||||||
|  |         public int width { get; set; } | ||||||
|  |         public int height { get; set; } | ||||||
|  |  | ||||||
|  | #pragma warning restore IDE1006 // Naming Styles | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user