Skip to content

Commit

Permalink
add https://fanficus.com/ support
Browse files Browse the repository at this point in the history
  • Loading branch information
OnlyFart committed Oct 14, 2024
1 parent 19054ce commit 897254d
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Core/Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latestmajor</LangVersion>
<PackageId>Core</PackageId>
<Version>2.3.3</Version>
<Version>2.4.0</Version>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
</PropertyGroup>

Expand Down
112 changes: 112 additions & 0 deletions Core/Logic/Getters/FanFicusGetter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Core.Configs;
using Core.Extensions;
using Core.Types.Book;
using Core.Types.Common;
using Core.Types.FanFicus;
using HtmlAgilityPack;
using Microsoft.Extensions.Logging;

namespace Core.Logic.Getters;

public class FanFicusGetter : GetterBase {
public FanFicusGetter(BookGetterConfig config) : base(config) { }

protected override Uri SystemUrl => new("https://fanficus.com/");

private readonly Uri _apiHost = new("https://fanficus-server-mirror-879c30cd977f.herokuapp.com/");

protected override string GetId(Uri url) {
return url.GetSegment(2);
}

public override async Task Authorize() {
if (!Config.HasCredentials) {
return;
}

var response = await Config.Client.PostAsJsonAsync(_apiHost.MakeRelativeUri("api/v1/user/login"), GenerateAuthData());
if (response.StatusCode == HttpStatusCode.OK) {
var user = await response.Content.ReadFromJsonAsync<FanFicusApiResponse<FanFicusUser>>();
Config.Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", user.Value.Token);
Config.Logger.LogInformation("Успешно авторизовались");
} else {
throw new Exception("Не удалось авторизоваться. Неверный пароль или имейл");
}
}

private object GenerateAuthData() {
return new {
username = Config.Options.Login,
password = Config.Options.Password,
};
}

public override async Task<Book> Get(Uri url) {
var bookId = GetId(url);

url = SystemUrl.MakeRelativeUri($"/post/{bookId}");
var response = await Config.Client.GetFromJsonWithTriesAsync<FanFicusApiResponse<FanFicusBook>>(_apiHost.MakeRelativeUri($"api/v1/post/{bookId}"));

var book = new Book(url) {
Cover = await GetCover(response.Value, url),
Chapters = await FillChapters(bookId),
Title = response.Value.Title,
Author = GetAuthor(response.Value),
Annotation = response.Value.Description
};

return book;
}

private Author GetAuthor(FanFicusBook book) {
var creator = book.Creators.FirstOrDefault();
return creator == default ? new Author("FanFicus") : new Author(creator.NickName, SystemUrl.MakeRelativeUri($"/user/{creator.Id}"));
}

private async Task<IEnumerable<FanFicusPart>> GetToc(string bookId) {
var response = await Config.Client.GetFromJsonWithTriesAsync<FanFicusApiResponse<FanFicusPart[]>>(_apiHost.MakeRelativeUri($"/api/v1/post/{bookId}/post-part"));
return SliceToc(response.Value, c => c.Title);
}

private async Task<IEnumerable<Chapter>> FillChapters(string bookId) {
var result = new List<Chapter>();
if (Config.Options.NoChapters) {
return result;
}

foreach (var fanFicusPart in await GetToc(bookId)) {
var chapter = new Chapter {
Title = fanFicusPart.Title
};

Config.Logger.LogInformation($"Загружаю главу {fanFicusPart.Title.CoverQuotes()}");

var chapterDoc = await GetChapter(bookId, fanFicusPart);
if (chapterDoc != default) {
chapter.Images = await GetImages(chapterDoc, SystemUrl);
chapter.Content = chapterDoc.DocumentNode.InnerHtml;
}

result.Add(chapter);
}

return result;
}

private async Task<HtmlDocument> GetChapter(string bookId, FanFicusPart fanFicusPart) {
var response = await Config.Client.GetFromJsonWithTriesAsync<FanFicusApiResponse<FanFicusChapter>>(_apiHost.MakeRelativeUri($"api/v1/post/{bookId}/post-part/{fanFicusPart.Id}"));
return response.Value.Text.AsHtmlDoc();
}

private Task<TempFile> GetCover(FanFicusBook doc, Uri uri) {
var imagePath = doc.Images.FirstOrDefault()?.Url;
return !string.IsNullOrWhiteSpace(imagePath) ? SaveImage(uri.MakeRelativeUri(imagePath)) : Task.FromResult(default(TempFile));
}
}
8 changes: 8 additions & 0 deletions Core/Types/FanFicus/FanFicusApiResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Text.Json.Serialization;

namespace Core.Types.FanFicus;

public class FanFicusApiResponse<T> {
[JsonPropertyName("value")]
public T Value { get; set; }
}
17 changes: 17 additions & 0 deletions Core/Types/FanFicus/FanFicusBook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Text.Json.Serialization;

namespace Core.Types.FanFicus;

public class FanFicusBook {
[JsonPropertyName("title")]
public string Title { get; set; }

[JsonPropertyName("description")]
public string Description { get; set; }

[JsonPropertyName("creatorId")]
public FanFicusCreator[] Creators { get; set; }

[JsonPropertyName("images")]
public FanFicusImage[] Images { get; set; }
}
8 changes: 8 additions & 0 deletions Core/Types/FanFicus/FanFicusChapter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Text.Json.Serialization;

namespace Core.Types.FanFicus;

public class FanFicusChapter {
[JsonPropertyName("text")]
public string Text { get; set; }
}
11 changes: 11 additions & 0 deletions Core/Types/FanFicus/FanFicusCreator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Text.Json.Serialization;

namespace Core.Types.FanFicus;

public class FanFicusCreator {
[JsonPropertyName("_id")]
public string Id { get; set; }

[JsonPropertyName("nickName")]
public string NickName { get; set; }
}
8 changes: 8 additions & 0 deletions Core/Types/FanFicus/FanFicusImage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Text.Json.Serialization;

namespace Core.Types.FanFicus;

public class FanFicusImage {
[JsonPropertyName("url")]
public string Url { get; set; }
}
11 changes: 11 additions & 0 deletions Core/Types/FanFicus/FanFicusPart.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Text.Json.Serialization;

namespace Core.Types.FanFicus;

public class FanFicusPart {
[JsonPropertyName("_id")]
public string Id { get; set; }

[JsonPropertyName("title")]
public string Title { get; set; }
}
8 changes: 8 additions & 0 deletions Core/Types/FanFicus/FanFicusUser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Text.Json.Serialization;

namespace Core.Types.FanFicus;

public class FanFicusUser {
[JsonPropertyName("token")]
public string Token { get; set; }
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
* https://dreame.com/
* https://erolate.com/
* https://eznovels.com/
* https://fanficus.com/
* https://fb2.top/
* https://ficbook.net/
* https://fictionbook.ru/
Expand Down

0 comments on commit 897254d

Please sign in to comment.