mirror of
https://github.com/C9Glax/tranga.git
synced 2025-07-01 16:34:17 +02:00
Compare commits
4 Commits
1.4.1
...
5fa0c98d05
Author | SHA1 | Date | |
---|---|---|---|
5fa0c98d05 | |||
b166013770 | |||
02fe849046 | |||
d42393c83a |
23
README.md
23
README.md
@ -36,6 +36,7 @@
|
|||||||
<li>
|
<li>
|
||||||
<a href="#getting-started">Getting Started</a>
|
<a href="#getting-started">Getting Started</a>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><a href="#prerequisites">Usage</a></li>
|
||||||
<li><a href="#prerequisites">Prerequisites</a></li>
|
<li><a href="#prerequisites">Prerequisites</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@ -109,6 +110,28 @@ Download [docker-compose.yaml](https://git.bernloehr.eu/glax/Tranga/src/branch/m
|
|||||||
|
|
||||||
Wherever you are mounting `/usr/share/Tranga-API` you also need to mount that same path + `/imageCache` in the webserver container.
|
Wherever you are mounting `/usr/share/Tranga-API` you also need to mount that same path + `/imageCache` in the webserver container.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
There is two ways to download Mangas:
|
||||||
|
- Downloading everything and monitor for new Chapters
|
||||||
|
- Selecting specific Volumes/Chapters
|
||||||
|
|
||||||
|
On the website you add new tasks, by selecting the blue '+' field. Next select the connector/site you want to use, and enter a search term.
|
||||||
|
After pressing 'Search', the results will be presented below - this might, depending on the result-size, take a while.
|
||||||
|
Next select the publication and a new popup will open with two options:
|
||||||
|
- "Monitor" - Download all chapters and monitor for new ones
|
||||||
|
- "Download Chapter" - Download specific chapters only
|
||||||
|
|
||||||
|
When selecting `Monitor` you will be presented with a new window and the selection of the interval you want to check for new chapters.
|
||||||
|
When selecting `Download Chapter` a list will open with all available chapters from which you can then select a range.
|
||||||
|
|
||||||
|
The syntax for selecting chapters is as follows:
|
||||||
|
- To download a single Chapter enter either the index number (the number at the very start of the line) or its absolute number like so: `c(h)(apter)[number]`, spaces are allowed.
|
||||||
|
- To download a range of chapters enter either a range of index numbers (`3-6`) or chapters (`ch 12-23`).
|
||||||
|
- For volumes the syntax is as follows: `v(ol)[number](-[number])`, again spaces allowed.
|
||||||
|
|
||||||
|
Examples: `2-12`, `c1`, `ch 2`, `chapter 3`, `v 2`, `vol3-4`, `v2c4` (note: you can only specify a single chapter with this syntax).
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
[.NET-Core 7.0 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/7.0)
|
[.NET-Core 7.0 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/7.0)
|
||||||
|
@ -119,21 +119,10 @@ app.MapPost("/Tasks/CreateDownloadChaptersTask", (string connectorName, string i
|
|||||||
if (publication is null)
|
if (publication is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Chapter[] availableChapters = connector.GetChapters((Publication)publication, language??"en");;
|
IEnumerable<Chapter> toDownload = connector.SearchChapters((Publication)publication, chapters, language ?? "en");
|
||||||
|
foreach(Chapter chapter in toDownload)
|
||||||
if (chapters.Contains('-'))
|
|
||||||
{
|
|
||||||
int start = Convert.ToInt32(chapters.Split('-')[0]);
|
|
||||||
int end = Convert.ToInt32(chapters.Split('-')[1]) + 1;
|
|
||||||
foreach (Chapter chapter in availableChapters[start..end])
|
|
||||||
{
|
|
||||||
taskManager.AddTask(new DownloadChapterTask(TrangaTask.Task.DownloadChapter, connectorName,
|
|
||||||
(Publication)publication, chapter, "en"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
taskManager.AddTask(new DownloadChapterTask(TrangaTask.Task.DownloadChapter, connectorName,
|
taskManager.AddTask(new DownloadChapterTask(TrangaTask.Task.DownloadChapter, connectorName,
|
||||||
(Publication)publication, availableChapters[Convert.ToInt32(chapters)], "en"));
|
(Publication)publication, chapter, "en"));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.MapDelete("/Tasks/Delete", (string taskType, string? connectorName, string? publicationId) =>
|
app.MapDelete("/Tasks/Delete", (string taskType, string? connectorName, string? publicationId) =>
|
||||||
|
@ -499,22 +499,7 @@ public static class Tranga_Cli
|
|||||||
while(selectedChapters is null || selectedChapters.Length < 1)
|
while(selectedChapters is null || selectedChapters.Length < 1)
|
||||||
selectedChapters = Console.ReadLine();
|
selectedChapters = Console.ReadLine();
|
||||||
|
|
||||||
if (selectedChapters.Length == 1 && selectedChapters.ToLower() == "q")
|
return connector.SearchChapters(publication, selectedChapters);
|
||||||
{
|
|
||||||
Console.Clear();
|
|
||||||
Console.WriteLine("aborted.");
|
|
||||||
logger.WriteLine("Tranga_CLI", "aborted.");
|
|
||||||
return Array.Empty<Chapter>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedChapters.Contains('-'))
|
|
||||||
{
|
|
||||||
int start = Convert.ToInt32(selectedChapters.Split('-')[0]);
|
|
||||||
int end = Convert.ToInt32(selectedChapters.Split('-')[1]) + 1;
|
|
||||||
return availableChapters[start..end];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return new Chapter[] { availableChapters[Convert.ToInt32(selectedChapters)] };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Connector? SelectConnector(Connector[] connectors, Logger logger)
|
private static Connector? SelectConnector(Connector[] connectors, Logger logger)
|
||||||
|
@ -54,6 +54,72 @@ public abstract class Connector
|
|||||||
/// <returns>Array of Chapters matching Publication and Language</returns>
|
/// <returns>Array of Chapters matching Publication and Language</returns>
|
||||||
public abstract Chapter[] GetChapters(Publication publication, string language = "");
|
public abstract Chapter[] GetChapters(Publication publication, string language = "");
|
||||||
|
|
||||||
|
public Chapter[] SearchChapters(Publication publication, string searchTerm, string? language = null)
|
||||||
|
{
|
||||||
|
Chapter[] availableChapters = this.GetChapters(publication, language??"en");
|
||||||
|
Regex volumeRegex = new ("((v(ol)*(olume)*)+ *([0-9]+(-[0-9]+)?){1})", RegexOptions.IgnoreCase);
|
||||||
|
Regex chapterRegex = new ("((c(h)*(hapter)*)+ *([0-9]+(-[0-9]+)?){1})", RegexOptions.IgnoreCase);
|
||||||
|
Regex singleResultRegex = new("([0-9]+)", RegexOptions.IgnoreCase);
|
||||||
|
Regex rangeResultRegex = new("([0-9]+(-[0-9]+))", RegexOptions.IgnoreCase);
|
||||||
|
if (volumeRegex.IsMatch(searchTerm) && chapterRegex.IsMatch(searchTerm))
|
||||||
|
{
|
||||||
|
string volume = singleResultRegex.Match(volumeRegex.Match(searchTerm).Value).Value;
|
||||||
|
string chapter = singleResultRegex.Match(chapterRegex.Match(searchTerm).Value).Value;
|
||||||
|
return availableChapters.Where(aCh => aCh.volumeNumber is not null && aCh.chapterNumber is not null &&
|
||||||
|
aCh.volumeNumber.Equals(volume, StringComparison.InvariantCultureIgnoreCase) &&
|
||||||
|
aCh.chapterNumber.Equals(chapter, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
else if (volumeRegex.IsMatch(searchTerm))
|
||||||
|
{
|
||||||
|
string volume = volumeRegex.Match(searchTerm).Value;
|
||||||
|
if (rangeResultRegex.IsMatch(volume))
|
||||||
|
{
|
||||||
|
string range = rangeResultRegex.Match(volume).Value;
|
||||||
|
int start = Convert.ToInt32(range.Split('-')[0]);
|
||||||
|
int end = Convert.ToInt32(range.Split('-')[1]);
|
||||||
|
return availableChapters.Where(aCh => aCh.volumeNumber is not null &&
|
||||||
|
Convert.ToInt32(aCh.volumeNumber) >= start &&
|
||||||
|
Convert.ToInt32(aCh.volumeNumber) <= end).ToArray();
|
||||||
|
}
|
||||||
|
else if(singleResultRegex.IsMatch(volume))
|
||||||
|
return availableChapters.Where(aCh =>
|
||||||
|
aCh.volumeNumber is not null &&
|
||||||
|
aCh.volumeNumber.Equals(volume, StringComparison.InvariantCultureIgnoreCase)).ToArray();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (chapterRegex.IsMatch(searchTerm))
|
||||||
|
{
|
||||||
|
string chapter = volumeRegex.Match(searchTerm).Value;
|
||||||
|
if (rangeResultRegex.IsMatch(chapter))
|
||||||
|
{
|
||||||
|
string range = rangeResultRegex.Match(chapter).Value;
|
||||||
|
int start = Convert.ToInt32(range.Split('-')[0]);
|
||||||
|
int end = Convert.ToInt32(range.Split('-')[1]);
|
||||||
|
return availableChapters.Where(aCh => aCh.chapterNumber is not null &&
|
||||||
|
Convert.ToInt32(aCh.chapterNumber) >= start &&
|
||||||
|
Convert.ToInt32(aCh.chapterNumber) <= end).ToArray();
|
||||||
|
}
|
||||||
|
else if(singleResultRegex.IsMatch(chapter))
|
||||||
|
return availableChapters.Where(aCh =>
|
||||||
|
aCh.chapterNumber is not null &&
|
||||||
|
aCh.chapterNumber.Equals(chapter, StringComparison.InvariantCultureIgnoreCase)).ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rangeResultRegex.IsMatch(searchTerm))
|
||||||
|
{
|
||||||
|
int start = Convert.ToInt32(searchTerm.Split('-')[0]);
|
||||||
|
int end = Convert.ToInt32(searchTerm.Split('-')[1]);
|
||||||
|
return availableChapters[start..(end + 1)];
|
||||||
|
}
|
||||||
|
else if(singleResultRegex.IsMatch(searchTerm))
|
||||||
|
return new [] { availableChapters[Convert.ToInt32(searchTerm)] };
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.Empty<Chapter>();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the Chapter (+Images) from the website.
|
/// Retrieves the Chapter (+Images) from the website.
|
||||||
/// Should later call DownloadChapterImages to retrieve the individual Images of the Chapter and create .cbz archive.
|
/// Should later call DownloadChapterImages to retrieve the individual Images of the Chapter and create .cbz archive.
|
||||||
|
@ -63,7 +63,7 @@ createMonitorTaskButton.addEventListener("click", () => {
|
|||||||
createDownloadChapterTaskButton.addEventListener("click", () => {
|
createDownloadChapterTaskButton.addEventListener("click", () => {
|
||||||
HidePublicationPopup();
|
HidePublicationPopup();
|
||||||
OpenDownloadChapterTaskPopup();
|
OpenDownloadChapterTaskPopup();
|
||||||
})
|
});
|
||||||
publicationTaskStart.addEventListener("click", () => StartTaskClick());
|
publicationTaskStart.addEventListener("click", () => StartTaskClick());
|
||||||
settingApiUri.addEventListener("keypress", (event) => {
|
settingApiUri.addEventListener("keypress", (event) => {
|
||||||
if(event.key === "Enter"){
|
if(event.key === "Enter"){
|
||||||
@ -156,6 +156,8 @@ function AddMonitorTask(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function OpenDownloadChapterTaskPopup(){
|
function OpenDownloadChapterTaskPopup(){
|
||||||
|
selectedChapters.value = "";
|
||||||
|
chapterOutput.replaceChildren();
|
||||||
createDownloadChaptersTask.style.display = "block";
|
createDownloadChaptersTask.style.display = "block";
|
||||||
GetChapters(toEditId, connectorSelect.value, "en").then((json) => {
|
GetChapters(toEditId, connectorSelect.value, "en").then((json) => {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
@ -261,6 +263,7 @@ function HidePublicationPopup(){
|
|||||||
|
|
||||||
function ShowNewTaskWindow(){
|
function ShowNewTaskWindow(){
|
||||||
selectPublication.replaceChildren();
|
selectPublication.replaceChildren();
|
||||||
|
searchPublicationQuery.value = "";
|
||||||
selectPublicationPopup.style.display = "flex";
|
selectPublicationPopup.style.display = "flex";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user