Imported Upstream version 14.29.4
[platform/upstream/libzypp.git] / zypp / repo / RepoMirrorList.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/repo/RepoMirrorList.cc
10  *
11 */
12
13 #include <iostream>
14 #include <vector>
15 #include <time.h>
16 #include "zypp/repo/RepoMirrorList.h"
17 #include "zypp/media/MetaLinkParser.h"
18 #include "zypp/MediaSetAccess.h"
19 #include "zypp/base/LogTools.h"
20 #include "zypp/ZConfig.h"
21 #include "zypp/PathInfo.h"
22
23 using namespace std;
24
25 ///////////////////////////////////////////////////////////////////
26 namespace zypp
27 { /////////////////////////////////////////////////////////////////
28   ///////////////////////////////////////////////////////////////////
29   namespace repo
30   { /////////////////////////////////////////////////////////////////
31
32     RepoMirrorList::RepoMirrorList( const Url &url, const Pathname &metadatapath )
33     {
34       std::vector<Url> my_urls;
35       Pathname tmpfile, cachefile;
36
37       if ( url.asString().find("/metalink") != string::npos )
38         cachefile = metadatapath / "mirrorlist.xml";
39       else
40         cachefile = metadatapath / "mirrorlist.txt";
41         //cachefile = ZConfig::instance().repoMetadataPath() / Pathname(escaped_alias) / "mirrorlist.txt";
42
43       zypp::filesystem::PathInfo cacheinfo (cachefile);
44
45       if ( !cacheinfo.isFile() || cacheinfo.mtime() < time(NULL) - (long) ZConfig::instance().repo_refresh_delay() * 60 )
46       {
47         Pathname filepath (url.getPathName());
48         Url abs_url (url);
49
50         DBG << "Getting MirrorList from URL: " << abs_url << endl;
51
52         abs_url.setPathName("");
53         abs_url.setQueryParam("mediahandler", "curl");
54
55         MediaSetAccess access (abs_url);
56         tmpfile = access.provideFile(filepath);
57
58         // Create directory, if not existing
59         zypp::filesystem::assert_dir(metadatapath);
60
61         DBG << "Copy MirrorList file to " << cachefile << endl;
62         zypp::filesystem::copy(tmpfile, cachefile);
63       }
64
65       if ( url.asString().find("/metalink") != string::npos )
66       {
67         my_urls = parseXML(cachefile);
68       }
69       else
70       {
71         my_urls = parseTXT(cachefile);
72       }
73
74       setUrls( my_urls );
75       if( urls.empty() )
76       {
77         DBG << "Removing Cachefile as it contains no URLs" << endl;
78         zypp::filesystem::unlink(cachefile);
79       }
80     }
81
82     RepoMirrorList::RepoMirrorList( const Url &url )
83     {
84       std::vector<Url> my_urls;
85       Pathname tmpfile;
86
87       Pathname filepath (url.getPathName());
88       Url abs_url (url);
89
90       DBG << "Getting MirrorList from URL: " << abs_url << endl;
91
92       abs_url.setPathName("");
93       abs_url.setQueryParam("mediahandler", "curl");
94
95       MediaSetAccess access (abs_url);
96       tmpfile = access.provideFile(filepath);
97
98       if ( url.asString().find("/metalink") != string::npos )
99       {
100         my_urls = parseXML(tmpfile);
101       }
102       else
103       {
104         my_urls = parseTXT(tmpfile);
105       }
106
107       setUrls( my_urls );
108     }
109
110     void RepoMirrorList::setUrls( std::vector<Url> my_urls )
111     {
112       int valid_urls = 0;
113       for (std::vector<Url>::iterator it = my_urls.begin() ; it != my_urls.end() and valid_urls < 4 ; ++it)
114       {
115         if ( it->getScheme() != "rsync" )
116         {
117           size_t delpos = it->getPathName().find("repodata/repomd.xml");
118           if( delpos != string::npos )
119           {
120             it->setPathName( it->getPathName().erase(delpos)  );
121           }
122           urls.push_back(*it);
123           ++valid_urls;
124         }
125       }
126     }
127
128     std::vector<Url> RepoMirrorList::parseXML( const Pathname &tmpfile ) const
129     {
130       InputStream tmpfstream (tmpfile);
131       media::MetaLinkParser metalink;
132       metalink.parse(tmpfstream);
133       return metalink.getUrls();
134     }
135
136     std::vector<Url> RepoMirrorList::parseTXT( const Pathname &tmpfile ) const
137     {
138       InputStream tmpfstream (tmpfile);
139       std::vector<Url> my_urls;
140       string tmpurl;
141       while (getline(tmpfstream.stream(), tmpurl))
142       {
143         my_urls.push_back(Url(tmpurl));
144       }
145       return my_urls;
146     }
147     
148     std::vector<Url> RepoMirrorList::getUrls() const
149     {
150       return urls;
151     }
152
153     RepoMirrorList::~RepoMirrorList()
154     {}
155
156    /////////////////////////////////////////////////////////////////
157   } // namespace repo
158   ///////////////////////////////////////////////////////////////////
159   /////////////////////////////////////////////////////////////////
160 } // namespace zypp
161 ///////////////////////////////////////////////////////////////////