pkgdownload.pp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. unit pkgDownload;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, pkghandler, pkgFppkg;
  6. Type
  7. { TBaseDownloader }
  8. TBaseDownloader = Class(TComponent)
  9. Private
  10. FBackupFile : Boolean;
  11. Protected
  12. // Needs overriding.
  13. Procedure FTPDownload(Const URL : String; Dest : TStream); Virtual;
  14. Procedure HTTPDownload(Const URL : String; Dest : TStream); Virtual;
  15. Procedure FileDownload(Const URL : String; Dest : TStream); Virtual;
  16. Public
  17. Procedure Download(Const URL,DestFileName : String);
  18. Procedure Download(Const URL : String; Dest : TStream);
  19. Property BackupFiles : Boolean Read FBackupFile Write FBackupFile;
  20. end;
  21. TBaseDownloaderClass = Class of TBaseDownloader;
  22. { TDownloadPackage }
  23. TDownloadPackage = Class(TPackagehandler)
  24. Public
  25. function Execute: Boolean;override;
  26. end;
  27. procedure RegisterDownloader(const AName:string;Downloaderclass:TBaseDownloaderClass);
  28. function GetDownloader(const AName:string):TBaseDownloaderClass;
  29. procedure DownloadFile(const RemoteFile,LocalFile:String; PackageManager: TpkgFPpkg);
  30. implementation
  31. uses
  32. contnrs,
  33. uriparser,
  34. fprepos,
  35. pkgglobals,
  36. pkgoptions,
  37. pkgmessages,
  38. pkgrepos;
  39. var
  40. DownloaderList : TFPHashList;
  41. procedure RegisterDownloader(const AName:string;Downloaderclass:TBaseDownloaderClass);
  42. begin
  43. if DownloaderList.Find(AName)<>nil then
  44. begin
  45. Error('Downloader already registered');
  46. exit;
  47. end;
  48. DownloaderList.Add(AName,Downloaderclass);
  49. end;
  50. function GetDownloader(const AName:string):TBaseDownloaderClass;
  51. begin
  52. result:=TBaseDownloaderClass(DownloaderList.Find(AName));
  53. if result=nil then
  54. Error('Downloader %s not supported',[AName]);
  55. end;
  56. procedure DownloadFile(const RemoteFile,LocalFile:String; PackageManager: TpkgFPpkg);
  57. var
  58. DownloaderClass : TBaseDownloaderClass;
  59. begin
  60. DownloaderClass:=GetDownloader(PackageManager.Options.GlobalSection.Downloader);
  61. with DownloaderClass.Create(nil) do
  62. try
  63. Download(RemoteFile,LocalFile);
  64. finally
  65. Free;
  66. end;
  67. end;
  68. { TBaseDownloader }
  69. procedure TBaseDownloader.FTPDownload(const URL: String; Dest: TStream);
  70. begin
  71. Error(SErrNoFTPDownload);
  72. end;
  73. procedure TBaseDownloader.HTTPDownload(const URL: String; Dest: TStream);
  74. begin
  75. Error(SErrNoHTTPDownload);
  76. end;
  77. procedure TBaseDownloader.FileDownload(const URL: String; Dest: TStream);
  78. Var
  79. FN : String;
  80. F : TFileStream;
  81. begin
  82. URIToFilename(URL,FN);
  83. If Not FileExists(FN) then
  84. Error(SErrNoSuchFile,[FN]);
  85. F:=TFileStream.Create(FN,fmOpenRead);
  86. Try
  87. Dest.CopyFrom(F,0);
  88. Finally
  89. F.Free;
  90. end;
  91. end;
  92. procedure TBaseDownloader.Download(const URL, DestFileName: String);
  93. Var
  94. F : TFileStream;
  95. begin
  96. If FileExists(DestFileName) and BackupFiles then
  97. BackupFile(DestFileName);
  98. try
  99. F:=TFileStream.Create(DestFileName,fmCreate);
  100. try
  101. Download(URL,F);
  102. finally
  103. F.Free;
  104. end;
  105. except
  106. DeleteFile(DestFileName);
  107. raise;
  108. end;
  109. end;
  110. procedure TBaseDownloader.Download(const URL: String; Dest: TStream);
  111. Var
  112. URI : TURI;
  113. P : String;
  114. begin
  115. URI:=ParseURI(URL);
  116. P:=URI.Protocol;
  117. If CompareText(P,'ftp')=0 then
  118. FTPDownload(URL,Dest)
  119. else if CompareText(P,'http')=0 then
  120. HTTPDownload(URL,Dest)
  121. else if CompareText(P,'file')=0 then
  122. FileDownload(URL,Dest)
  123. else
  124. Error(SErrUnknownProtocol,[P, URL]);
  125. end;
  126. { TDownloadPackage }
  127. function TDownloadPackage.Execute: Boolean;
  128. var
  129. DownloaderClass : TBaseDownloaderClass;
  130. P : TFPPackage;
  131. RemoteArchive: string;
  132. begin
  133. Result := False;
  134. P:=PackageManager.PackageByName(PackageName, pkgpkAvailable);
  135. DownloaderClass:=GetDownloader(PackageManager.Options.GlobalSection.Downloader);
  136. if Assigned(DownloaderClass) then
  137. begin
  138. with DownloaderClass.Create(nil) do
  139. try
  140. RemoteArchive := PackageManager.PackageRemoteArchive(P);
  141. if RemoteArchive <> '' then
  142. begin
  143. Log(llCommands,SLogDownloading,[RemoteArchive,PackageManager.PackageLocalArchive(P)]);
  144. pkgglobals.log(llProgres,SProgrDownloadPackage,[P.Name, P.Version.AsString]);
  145. // Force the existing of the archives-directory if it is being used
  146. if (P.Name<>CurrentDirPackageName) and (P.Name<>CmdLinePackageName) then
  147. ForceDirectories(PackageManager.Options.GlobalSection.ArchivesDir);
  148. Download(RemoteArchive,PackageManager.PackageLocalArchive(P));
  149. Result := True;
  150. end
  151. else
  152. Error(SErrDownloadPackageFailed);
  153. finally
  154. Free;
  155. end;
  156. end;
  157. end;
  158. initialization
  159. DownloaderList:=TFPHashList.Create;
  160. RegisterDownloader('base',TBaseDownloader);
  161. RegisterPkgHandler('downloadpackage',TDownloadPackage);
  162. finalization
  163. FreeAndNil(DownloaderList);
  164. end.