Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
28c5ed6
Changed: GitHub API check to check connection and rate limit separately
NhKPaNdA Aug 19, 2025
572cbfb
Fixed: ImageMagick not working with multiple formats
NhKPaNdA Sep 14, 2025
8a39e7d
Fixed: Max filename path not accommodating extensions with 4 characters
NhKPaNdA Oct 8, 2025
77a02cc
Changed: FQDN List name character limit to prevent failed file creation
NhKPaNdA Nov 3, 2025
f489a5a
Changed: Timeout for imagemagick for larger file amount operations
NhKPaNdA Jan 1, 2026
e1e5e7a
Changed: Status bar refresh interval
NhKPaNdA Jan 1, 2026
bca960d
Fixed: Long paths to truncate at hard limit of 255 per folder/file #2732
NhKPaNdA Feb 2, 2026
56de62b
Fixed: Cover loading gif in dark theme (Credit to @jesuscc1993) #2608
NhKPaNdA Feb 2, 2026
ab1e684
Fixed: Downloads task counter when merging completed tasks #660
NhKPaNdA Feb 2, 2026
a316141
Fixed: Caption not showing exe arguments when changing languages
NhKPaNdA Feb 2, 2026
68d05af
Fixed: Code good practice (mainly if statements)
NhKPaNdA Feb 2, 2026
a696a49
Fixed: Dbl click on favourites status instead of save to opening folder
NhKPaNdA Feb 2, 2026
e6d2b06
Fixed: Downloads popup open not disabling on non existing folder #2696
NhKPaNdA Feb 2, 2026
335ff24
Fixed: More good code practice
NhKPaNdA Feb 2, 2026
7ea753a
Changed: How errors are handled from GitHub API with some more clarity
NhKPaNdA Feb 3, 2026
e4b7616
Added: Error to notify and close FMD if in folder path with unicode char
NhKPaNdA Feb 5, 2026
e668cb9
Changed: Default sorted columns colour to be a subtle shade
NhKPaNdA Feb 5, 2026
09ab2c0
Fixed: Accidental no return if long paths disabled causing chaos
NhKPaNdA Feb 5, 2026
50eda48
Changed: Prefill save to path in manga info to fix unwanted path changes
NhKPaNdA Feb 6, 2026
a805fd9
Changed: Image creation time to use local time
NhKPaNdA Feb 6, 2026
cf92b02
Fixed: Dropbox image rough edges
NhKPaNdA Feb 6, 2026
02c267a
Fixed: Forgotten anchor and image edge blend
NhKPaNdA Feb 6, 2026
8b1d7c8
Added: Save manga info to list when loading info
NhKPaNdA Feb 7, 2026
3601baa
Fixed: Kinks with reloading manga list after editing
NhKPaNdA Feb 9, 2026
4f2c99f
Changed: Read and write to be separate queries
NhKPaNdA Feb 11, 2026
3ba4b1f
Added: Function to normalize decomposed korean text
NhKPaNdA Mar 6, 2026
5bec00e
Removed: Image Magick combobox texts from translation files
NhKPaNdA Mar 25, 2026
c1ab357
Changed: Custom message dialog buttons to translatable texts
NhKPaNdA Mar 26, 2026
e7aef6c
Fixed: Update list not working with new database interactions
NhKPaNdA Mar 26, 2026
a60ca7e
Fixed: Custom message dialog buttons not properly auto sizing
NhKPaNdA Mar 27, 2026
c18a24f
Changed: Custom message dialog button minimum
NhKPaNdA Mar 28, 2026
85bf93d
Changed: Apply options button to show saved text for a second when apply
NhKPaNdA Mar 28, 2026
3cbf2e4
Fixed: Excessive database calls while searching
NhKPaNdA Apr 6, 2026
d3fe1d0
Fixed: Forgotten custom colour change between themes
NhKPaNdA Apr 8, 2026
ecdc63d
Fixed: Sorting and Vacuuming manga list db when updating on view info
NhKPaNdA Apr 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,690 changes: 1,091 additions & 599 deletions baseunits/DBDataProcess.pas

Large diffs are not rendered by default.

18 changes: 15 additions & 3 deletions baseunits/DBUpdater.pas
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,13 @@ procedure TDBUpdaterThread.Execute;

if used then
Synchronize(@SyncCloseUsed)
else
if dataProcess.WebsiteLoaded(FModule.ID) then
else if dataProcess.WebsiteLoaded(FModule.ID) then
begin
Synchronize(@SyncRemoveAttached);
end;

with TProcess.Create(nil) do
begin
try
UpdateStatusText(Format('[%d/%d] ' + RS_Extracting, [FIndex + 1, FItems.Count, FModule.Name]));
Executable := CURRENT_ZIP_EXE;
Expand All @@ -173,16 +176,25 @@ procedure TDBUpdaterThread.Execute;
Options := Options + [poWaitOnExit];
ShowWindow := swoHIDE;
Execute;

cont := ExitStatus = 0;
if cont then
DeleteFile(currentfilename)
begin
DeleteFile(currentfilename);
end
else
begin
FFailedList.Add(RS_FailedExtract, [FModule.Name, ExitStatus]);
end;
finally
Free;
end;
end;

if cont and used then
begin
Synchronize(@SyncReopenUsed);
end;
end;

dataProcess.Open(FModule.ID);
Expand Down
17 changes: 12 additions & 5 deletions baseunits/FMDOptions.pas
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ interface
OptionLetFMDDo: TFMDDo = DO_NOTHING;
OptionDeleteCompletedTasksOnClose: Boolean = False;
OptionSortDownloadsOnNewTasks: Boolean = False;
OptionLongNamePaths: Boolean = False;

// saveto
OptionChangeUnicodeCharacter: Boolean = False;
Expand All @@ -125,6 +126,9 @@ interface
OptionPNGCompressionLevel: Integer = 1;
OptionJPEGQuality: Integer = 80;

// image properties
OptionImageServerTime: Boolean = True;

// connections
OptionConnectionTimeout: Integer = 30;
OptionMaxFavoriteThreads: Integer = 1;
Expand Down Expand Up @@ -176,7 +180,7 @@ interface
CL_BSUnfocesedSelectionText: TColor = clWindowText;
CL_BSOdd: TColor = clBtnFace;
CL_BSEven: TColor = clWindow;
CL_BSSortedColumn: TColor = $F8E6D6;
CL_BSSortedColumn: TColor = $F0F0F0;
CL_BSEnabledWebsiteSettings: TColor = clYellow;

// mangalist color
Expand All @@ -198,7 +202,7 @@ interface

// custom color darkmode
// basiclist
CL_BSSortedColumnDark: TColor = $E19650;
CL_BSSortedColumnDark: TColor = $202020;
CL_BSEnabledWebsiteSettingsDark: TColor = $009696;

// mangalist color
Expand Down Expand Up @@ -306,10 +310,13 @@ procedure doInitialization;
var
i: Integer;
begin
AppParams:=TStringList.Create;
AppParams.Sorted:=False;
for i:=1 to ParamCount do
AppParams := TStringList.Create;
AppParams.Sorted := False;
for i := 1 to ParamCount do
begin
AppParams.Add(ParamStr(i));
end;

GetProgramVersion(FMD_VERSION_NUMBER);
FMD_VERSION_STRING := ProgramversionToStr(FMD_VERSION_NUMBER);
SetFMDdirectory(ExtractFilePath(Application.ExeName));
Expand Down
101 changes: 77 additions & 24 deletions baseunits/GitHubRepoV3.pas
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ TGitHubRepo = class
tree_sha,
tree_etag: String;

APIResetTime: TDateTime;
Tree: TTreeItems;
public
constructor Create(const AConfigFile, AWorkFile: String; const AThread: TBaseThread = nil);
Expand All @@ -47,7 +48,8 @@ TGitHubRepo = class
function GetLastCommitMessage(const FRepoPath: String): String;
function GetTree: Boolean;
function GetUpdate: Boolean;
function CheckRateLimited: Boolean;
function CheckConnection: Boolean;
procedure CheckRateLimited(AThread: TBaseThread);
function GetDownloadURL(const AName: String): String;
end;

Expand Down Expand Up @@ -303,39 +305,89 @@ function TGitHubRepo.GetUpdate: Boolean;
FDirty := Result;
end;

function TGitHubRepo.CheckRateLimited: Boolean;

function TGitHubRepo.CheckConnection: Boolean;
begin
Result := False;
HTTP.ResetBasic;

if HTTP.GET(api_url) then
begin
Result := True;
end;
end;

procedure TGitHubRepo.CheckRateLimited(AThread: TBaseThread);
var
s: String;
d: TJSONData;
AUpdateThread: TCheckUpdateThread;
url, apiMessage: String;
jsonData, jsonCoreData: TJSONData;
coreLimit, coreRemaining, coreReset, coreUsed: Integer;
convertedLocalTime: TDateTime;
begin
Result := True;
HTTP.ResetBasic;
s := AppendURLDelim(api_url) + 'rate_limit';
url := AppendURLDelim(api_url) + 'rate_limit';

if not (AThread is TCheckUpdateThread) then
begin
Exit;
end;

if HTTP.GET(s) then
AUpdateThread := TCheckUpdateThread(AThread);

if not HTTP.GET(url) then
begin
d := GetJSON(HTTP.Document);
if Assigned(d) then
begin
try
if d.JSONType = jtObject then
begin
coreLimit := TJSONObject(d).FindPath('resources.core.limit').AsInteger;
coreRemaining := TJSONObject(d).FindPath('resources.core.remaining').AsInteger;
coreReset := TJSONObject(d).FindPath('resources.core.reset').AsInteger;
coreUsed := TJSONObject(d).FindPath('resources.core.used').AsInteger;
AUpdateThread.DoSyncGitHubConnectFail;
Exit;
end;

convertedLocalTime := UniversalTimeToLocal(UnixToDateTime(coreReset));
Logger.Send(Self.ClassName + ': ' + Format(RS_GitHubRateStats, [coreLimit, coreRemaining, coreUsed, DateTimeToStr(convertedLocalTime)]));
jsonData := GetJSON(HTTP.Document);

Result := coreRemaining = 0;
end;
except
if not Assigned(jsonData) then
begin
AUpdateThread.DoSyncGitHubErrorMessage(False);
Exit;
end;

try
if jsonData.JSONType <> jtObject then
begin
AUpdateThread.DoSyncGitHubErrorMessage(False);
Exit;
end;

jsonCoreData := TJSONObject(jsonData).FindPath('resources.core');
if not Assigned(jsonCoreData) then
begin
apiMessage := TJSONObject(jsonData).Get('message', '');

if apiMessage <> '' then
begin
AUpdateThread.DoSyncGitHubErrorMessage;
Logger.SendWarning(Self.ClassName + ': ' + apiMessage);
end
else
begin
AUpdateThread.DoSyncGitHubErrorMessage(False);
end;
d.Free;

Exit;
end;

coreLimit := TJSONObject(jsonCoreData).Get('limit', 0);
coreRemaining := TJSONObject(jsonCoreData).Get('remaining', 0);
coreReset := TJSONObject(jsonCoreData).Get('reset', 0);
coreUsed := TJSONObject(jsonCoreData).Get('used', 0);

APIResetTime := UniversalTimeToLocal(UnixToDateTime(coreReset));
Logger.Send(Self.ClassName + ': ' + Format(RS_GitHubRateStats, [coreLimit, coreRemaining, coreUsed, DateTimeToStr(APIResetTime)]));

if coreRemaining = 0 then
begin
AUpdateThread.DoSyncGitHubRateLimited;
end;

finally
jsonData.Free;
end;
end;

Expand All @@ -348,6 +400,7 @@ function TGitHubRepo.GetDownloadURL(const AName: String): String;
begin
lpath := lpath + '/';
end;

Result := AppendURLDelim(download_url) + owner + '/' + name + '/' + ref + '/' + lpath + AName;
end;

Expand Down
2 changes: 1 addition & 1 deletion baseunits/StatusBarDownload.pas
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ procedure TStatusBarDownload.SyncCreate;
StatusBarResize(FStatusBar);

FTimerRepaint := TTimer.Create(FStatusBar);
FTimerRepaint.Interval := 500;
FTimerRepaint.Interval := 50;
FTimerRepaint.OnTimer := @TimerRepaintTimer;
FTimerRepaint.Enabled := True;
FNeedRepaint := True;
Expand Down
18 changes: 16 additions & 2 deletions baseunits/imagemagickmanager.pas
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ TImageMagickManager = class
function IdentifyCommand(const QueryCommand: String): TStringList;
procedure CacheSupportedFormats;
procedure CacheCompressionTypes;
function ExecuteMagickCommand(const Params: array of String; TimeoutMS: Cardinal = 300000): Boolean;
function ExecuteMagickCommand(const Params: array of String; TimeoutMS: Cardinal = 600000): Boolean;
function StreamToString(Stream: TMemoryStream): String;
constructor CreatePrivate;

Expand Down Expand Up @@ -501,7 +501,7 @@ function TImageMagickManager.IsFormatSupported(const Format: String): Boolean;
end;
end;

function TImageMagickManager.ExecuteMagickCommand(const Params: array of String; TimeoutMS: Cardinal = 300000): Boolean;
function TImageMagickManager.ExecuteMagickCommand(const Params: array of String; TimeoutMS: Cardinal = 600000): Boolean;
var
Process: TProcess;
Param, ErrorStreamOutput: String;
Expand Down Expand Up @@ -667,6 +667,20 @@ function TImageMagickManager.ConvertImage(InputFile, OutputDir: String): Boolean
OutputFile := QuoteStr((OutputDir + '%[filename:name].' + FSaveAs), '"');
OutputDir := QuoteStr(ExcludeTrailingPathDelimiter(OutputDir), '"');

// if FMogrify then:
// 'mogrify' command first
// 'path' command for OutputDir
// input directory to mogrify

// else:
// input file list first
// 'adjoin' command to treat each file in list as a seperate command
// 'set filename:name' command to set output file name same as input
// output file with directory and file name

// 'quality' command to set output image quality
// 'compress' command for compression type
// 'format' command to set output file format
Result := ExecuteMagickCommand([
IFThen(FMogrify, 'mogrify', InputFile),
'-quality', GetQualityString,
Expand Down
6 changes: 5 additions & 1 deletion baseunits/lua/LuaBase.pas
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,13 @@ function LuaLoadFromStreamOrFile(const L: Plua_State;
const AStream: TMemoryStream; const AFileName: String): Integer;
begin
if (not AlwaysLoadLuaFromFile) and (AStream <> nil) then
Result := luaL_loadbuffer(L, AStream.Memory, AStream.Size, PAnsiChar(AFileName))
begin
Result := luaL_loadbuffer(L, AStream.Memory, AStream.Size, PAnsiChar(AFileName));
end
else
begin
Result := luaL_loadfile(L, PAnsiChar(AFileName));
end;
end;

procedure LuaExecute(const L: Plua_State; const AStream: TMemoryStream;
Expand Down
8 changes: 7 additions & 1 deletion baseunits/lua/LuaHandler.pas
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,20 @@ function TLuaHandler.LoadChunkExecute(const AName: String;
l: Integer;
begin
Result := 0;

l := FLoadedChunks.IndexOf(AName);
if (l <> -1) then
begin
if AlwaysLoadLuaFromFile then
FLoadedChunks.Delete(l)
begin
FLoadedChunks.Delete(l);
end
else
begin
Exit;
end;
end;

Result := LuaLoadFromStreamOrFile(FHandle, AChunk, AName);
if Result = 0 then
begin
Expand Down
Loading