libzypp  10.5.0
RepoMirrorList.cc
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00013 #include <iostream>
00014 #include <vector>
00015 #include <time.h>
00016 #include "zypp/repo/RepoMirrorList.h"
00017 #include "zypp/media/MetaLinkParser.h"
00018 #include "zypp/MediaSetAccess.h"
00019 #include "zypp/base/LogTools.h"
00020 #include "zypp/ZConfig.h"
00021 #include "zypp/PathInfo.h"
00022 
00023 using namespace std;
00024 
00026 namespace zypp
00027 { 
00028 
00029   namespace repo
00030   { 
00031 
00032     RepoMirrorList::RepoMirrorList( const Url &url, const Pathname &metadatapath )
00033     {
00034       std::vector<Url> my_urls;
00035       Pathname tmpfile, cachefile;
00036 
00037       if ( url.asString().find("/metalink") != string::npos )
00038         cachefile = metadatapath / "mirrorlist.xml";
00039       else
00040         cachefile = metadatapath / "mirrorlist.txt";
00041         //cachefile = ZConfig::instance().repoMetadataPath() / Pathname(escaped_alias) / "mirrorlist.txt";
00042 
00043       zypp::filesystem::PathInfo cacheinfo (cachefile);
00044 
00045       if ( !cacheinfo.isFile() || cacheinfo.mtime() < time(NULL) - (long) ZConfig::instance().repo_refresh_delay() * 60 )
00046       {
00047         Pathname filepath (url.getPathName());
00048         Url abs_url (url);
00049 
00050         DBG << "Getting MirrorList from URL: " << abs_url << endl;
00051 
00052         abs_url.setPathName("");
00053         abs_url.setQueryParam("mediahandler", "curl");
00054 
00055         MediaSetAccess access (abs_url);
00056         tmpfile = access.provideFile(filepath);
00057 
00058         // Create directory, if not existing
00059         zypp::filesystem::assert_dir(metadatapath);
00060 
00061         DBG << "Copy MirrorList file to " << cachefile << endl;
00062         zypp::filesystem::copy(tmpfile, cachefile);
00063       }
00064 
00065       if ( url.asString().find("/metalink") != string::npos )
00066       {
00067         my_urls = parseXML(cachefile);
00068       }
00069       else
00070       {
00071         my_urls = parseTXT(cachefile);
00072       }
00073 
00074       setUrls( my_urls );
00075       if( urls.empty() )
00076       {
00077         DBG << "Removing Cachefile as it contains no URLs" << endl;
00078         zypp::filesystem::unlink(cachefile);
00079       }
00080     }
00081 
00082     RepoMirrorList::RepoMirrorList( const Url &url )
00083     {
00084       std::vector<Url> my_urls;
00085       Pathname tmpfile;
00086 
00087       Pathname filepath (url.getPathName());
00088       Url abs_url (url);
00089 
00090       DBG << "Getting MirrorList from URL: " << abs_url << endl;
00091 
00092       abs_url.setPathName("");
00093       abs_url.setQueryParam("mediahandler", "curl");
00094 
00095       MediaSetAccess access (abs_url);
00096       tmpfile = access.provideFile(filepath);
00097 
00098       if ( url.asString().find("/metalink") != string::npos )
00099       {
00100         my_urls = parseXML(tmpfile);
00101       }
00102       else
00103       {
00104         my_urls = parseTXT(tmpfile);
00105       }
00106 
00107       setUrls( my_urls );
00108     }
00109 
00110     void RepoMirrorList::setUrls( std::vector<Url> my_urls )
00111     {
00112       int valid_urls = 0;
00113       for (std::vector<Url>::iterator it = my_urls.begin() ; it != my_urls.end() and valid_urls < 4 ; ++it)
00114       {
00115         if ( it->getScheme() != "rsync" )
00116         {
00117           size_t delpos = it->getPathName().find("repodata/repomd.xml");
00118           if( delpos != string::npos )
00119           {
00120             it->setPathName( it->getPathName().erase(delpos)  );
00121           }
00122           urls.push_back(*it);
00123           ++valid_urls;
00124         }
00125       }
00126     }
00127 
00128     std::vector<Url> RepoMirrorList::parseXML( const Pathname &tmpfile ) const
00129     {
00130       InputStream tmpfstream (tmpfile);
00131       media::MetaLinkParser metalink;
00132       metalink.parse(tmpfstream);
00133       return metalink.getUrls();
00134     }
00135 
00136     std::vector<Url> RepoMirrorList::parseTXT( const Pathname &tmpfile ) const
00137     {
00138       InputStream tmpfstream (tmpfile);
00139       std::vector<Url> my_urls;
00140       string tmpurl;
00141       while (getline(tmpfstream.stream(), tmpurl))
00142       {
00143         my_urls.push_back(Url(tmpurl));
00144       }
00145       return my_urls;
00146     }
00147     
00148     std::vector<Url> RepoMirrorList::getUrls() const
00149     {
00150       return urls;
00151     }
00152 
00153     RepoMirrorList::~RepoMirrorList()
00154     {}
00155 
00157   } // namespace repo
00160 } // namespace zypp