Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / repo / susetags / Downloader.cc
index e83514a..c6b1c58 100644 (file)
@@ -2,8 +2,10 @@
 #include <iostream>
 #include <fstream>
 
-#include "zypp/base/Logger.h"
+#include "zypp/base/LogTools.h"
+#include "zypp/base/Gettext.h"
 #include "zypp/base/String.h"
+#include "zypp/base/Regex.h"
 #include "zypp/OnMediaLocation.h"
 #include "zypp/MediaSetAccess.h"
 #include "zypp/Fetcher.h"
@@ -14,7 +16,6 @@
 #include "zypp/parser/ParseException.h"
 #include "zypp/parser/susetags/RepoIndex.h"
 #include "zypp/base/UserRequestException.h"
-#include "zypp/KeyContext.h" // for SignatureFileChecker
 
 using namespace std;
 using namespace zypp::parser;
@@ -27,8 +28,8 @@ namespace repo
 namespace susetags
 {
 
-Downloader::Downloader( const RepoInfo &repoinfo )
-  : repo::Downloader(repoinfo)
+Downloader::Downloader( const RepoInfo &repoinfo, const Pathname &delta_dir )
+  : repo::Downloader(repoinfo), _delta_dir(delta_dir)
 {
 }
 
@@ -42,50 +43,29 @@ RepoStatus Downloader::status( MediaSetAccess &media )
   return RepoStatus(content) && RepoStatus(mediafile);
 }
 
+// search old repository file file to run the delta algorithm on
+static Pathname search_deltafile( const Pathname &dir, const Pathname &file )
+{
+  Pathname deltafile(dir + file.basename());
+  if (PathInfo(deltafile).isExist())
+    return deltafile;
+  return Pathname();
+}
+
+
+/** \todo: Downloading/sigcheck of master index shoudl be common in base class */
 void Downloader::download( MediaSetAccess &media,
                            const Pathname &dest_dir,
                            const ProgressData::ReceiverFnc & progress )
 {
   downloadMediaInfo( dest_dir, media );
 
-  SignatureFileChecker sigchecker/*(repoInfo().name())*/;
-
-  Pathname sig = repoInfo().path() + "/content.asc";
-
-  this->enqueue( OnMediaLocation( sig, 1 ).setOptional(true) );
-  this->start( dest_dir, media );
-  // only if there is a signature in the destination directory
-  if ( PathInfo(dest_dir / sig ).isExist() )
-      sigchecker = SignatureFileChecker( dest_dir + sig/*, repoInfo().name() */);
-  this->reset();
-
-  Pathname key = repoInfo().path() + "/content.key";
-
-  this->enqueue( OnMediaLocation( key, 1 ).setOptional(true) );
-  this->start( dest_dir, media );
-  // only if there is a key in the destination directory
-  if ( PathInfo(dest_dir / key).isExist() )
-  {
-    KeyContext context;
-    context.setRepoInfo(repoInfo());
-    sigchecker.addPublicKey(dest_dir + key, context);
-  }
-  this->reset();
-
-  if ( ! repoInfo().gpgCheck() )
-  {
-    WAR << "Signature checking disabled in config of repository " << repoInfo().alias() << endl;
-  }
-  this->enqueue( OnMediaLocation( repoInfo().path() + "/content", 1 ),
-                 repoInfo().gpgCheck() ? FileChecker(sigchecker) : FileChecker(NullFileChecker()) );
-  this->start( dest_dir, media );
-  this->reset();
-
-  Pathname descr_dir;
+  Pathname masterIndex( repoInfo().path() / "/content" );
+  defaultDownloadMasterIndex( media, dest_dir, masterIndex );
 
   // Content file first to get the repoindex
   {
-    Pathname inputfile( dest_dir +  repoInfo().path() + "/content" );
+    Pathname inputfile( dest_dir / masterIndex );
     ContentFileReader content;
     content.setRepoIndexConsumer( bind( &Downloader::consumeIndex, this, _1 ) );
     content.parse( inputfile );
@@ -105,37 +85,35 @@ void Downloader::download( MediaSetAccess &media,
   }
 
   // Prepare parsing
-  descr_dir = _repoindex->descrdir; // path below reporoot
+  Pathname descr_dir = _repoindex->descrdir; // path below reporoot
   //_datadir  = _repoIndex->datadir;  // path below reporoot
 
+  std::map<std::string,RepoIndex::FileChecksumMap::const_iterator> availablePackageTranslations;
 
   for_( it, _repoindex->metaFileChecksums.begin(), _repoindex->metaFileChecksums.end() )
   {
     // omit unwanted translations
     if ( str::hasPrefix( it->first, "packages" ) )
     {
-      std::string rest( str::stripPrefix( it->first, "packages" ) );
-      if ( ! (   rest.empty()
-              || rest == ".DU"
-              || rest == ".en"
-              || rest == ".gz"
-              || rest == ".DU.gz"
-              || rest == ".en.gz" ) )
+      static const str::regex rx_packages( "^packages((.gz)?|(.([^.]*))(.gz)?)$" );
+      str::smatch what;
+      if ( str::regex_match( it->first, what, rx_packages ) )
       {
-        // Not 100% correct as we take each fallback of textLocale
-        Locale toParse( ZConfig::instance().textLocale() );
-        while ( toParse != Locale::noCode )
-        {
-          if ( rest == ("."+toParse.code()) || (rest == ("."+toParse.code()+".gz")) )
-            break;
-          toParse = toParse.fallback();
-        }
-        if ( toParse == Locale::noCode )
-        {
-          // discard
-          continue;
-        }
+       if ( what[4].empty() // packages(.gz)?
+         || what[4] == "DU"
+         || what[4] == "en" )
+       { ; /* always downloaded */ }
+       else if ( what[4] == "FL" )
+       { continue; /* never downloaded */ }
+       else
+       {
+         // remember and decide later
+         availablePackageTranslations[what[4]] = it;
+         continue;
+       }
       }
+      else
+       continue; // discard
     }
     else if ( it->first == "patterns.pat"
               || it->first == "patterns.pat.gz" )
@@ -181,7 +159,31 @@ void Downloader::download( MediaSetAccess &media,
     MIL << "adding job " << it->first << endl;
     OnMediaLocation location( repoInfo().path() + descr_dir + it->first, 1 );
     location.setChecksum( it->second );
-    this->enqueueDigested(location);
+    enqueueDigested(location, FileChecker(), search_deltafile(_delta_dir + descr_dir, it->first));
+  }
+
+  // check whether to download more package translations:
+  {
+    auto fnc_checkTransaltions( [&]( const Locale & locale_r ) {
+      for ( Locale toGet( locale_r ); toGet != Locale::noCode; toGet = toGet.fallback() )
+      {
+       auto it( availablePackageTranslations.find( toGet.code() ) );
+       if ( it != availablePackageTranslations.end() )
+       {
+         auto mit( it->second );
+         MIL << "adding job " << mit->first << endl;
+         OnMediaLocation location( repoInfo().path() + descr_dir + mit->first, 1 );
+         location.setChecksum( mit->second );
+         enqueueDigested(location, FileChecker(), search_deltafile(_delta_dir + descr_dir, mit->first));
+         break;
+       }
+      }
+    });
+    for ( const Locale & it : ZConfig::instance().repoRefreshLocales() )
+    {
+      fnc_checkTransaltions( it );
+    }
+    fnc_checkTransaltions( ZConfig::instance().textLocale() );
   }
 
   for_( it, _repoindex->mediaFileChecksums.begin(), _repoindex->mediaFileChecksums.end() )
@@ -193,7 +195,7 @@ void Downloader::download( MediaSetAccess &media,
     MIL << "adding job " << it->first << endl;
     OnMediaLocation location( repoInfo().path() + it->first, 1 );
     location.setChecksum( it->second );
-    this->enqueueDigested(location);
+    enqueueDigested(location, FileChecker(), search_deltafile(_delta_dir, it->first));
   }
 
   for_( it, _repoindex->signingKeys.begin(),_repoindex->signingKeys.end() )
@@ -201,10 +203,10 @@ void Downloader::download( MediaSetAccess &media,
     MIL << "adding job " << it->first << endl;
     OnMediaLocation location( repoInfo().path() + it->first, 1 );
     location.setChecksum( it->second );
-    this->enqueueDigested(location);
+    enqueueDigested(location);
   }
 
-  this->start( dest_dir, media );
+  start( dest_dir, media );
 }
 
 void Downloader::consumeIndex( const RepoIndex_Ptr & data_r )