arcspackagemanager.cpp
1 /*
2  name: tools/pkg/arcspackagemanager.cpp
3 
4  This file is part of ARCS - Augmented Reality Component System
5  (version 2-current), written by Jean-Yves Didier
6  for IBISC Laboratory (http://www.ibisc.univ-evry.fr)
7 
8  Copyright (C) 2013 Université d'Evry-Val d'Essonne
9 
10  This program is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 2 of the License, or
13  (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program. If not, see <http://www.gnu.org/licenses/>.
22 
23 
24  Please send bugreports with examples or suggestions to
25  jean-yves.didier__at__ibisc.univ-evry.fr
26 */
27 
28 
29 #include "arcspackagemanager.h"
30 #include "arcsdownloader.h"
31 #include <QSettings>
32 #include <QDir>
33 #include <QFile>
34 #include <QFileInfo>
35 #include <QTextStream>
36 #include <QSettings>
37 #include <QProcess>
38 #include <iostream>
39 #include <QDomDocument>
40 
41 
42 
43 
44 ARCSPackageManager::ARCSPackageManager()
45 {
46  ad = new ARCSDownloader();
47  hS["repositoryPath"]="";
48  hS["repositoryUrl"]="";
49  hS["repositoryFile"]="";
50  hS["sourcePath"]="";
51  hS["archiveExtension"]="";
52  hS["compressCommand"]="";
53  hS["unCompressCommand"]="";
54 }
55 
56 ARCSPackageManager::~ARCSPackageManager()
57 {
58  delete ad;
59 }
60 
61 bool ARCSPackageManager::checkSettings()
62 {
63  fetchSetting("repositoryPath");
64  fetchSetting("repositoryUrl");
65  fetchSetting("repositoryFile","REPOSITORY");
66  fetchSetting("archiveExtension",".zip");
67  fetchSetting("compressCommand","zip -r %a %p");
68  fetchSetting("unCompressCommand","unzip -o %a");
69  if (!settings.contains("pkg/sourcePath"))
70  {
71  char* buildpath = getenv("ARCSBUILDPATH");
72  if (!buildpath)
73  {
74  std::cerr << "You must define a ARCSBUILPATH environment variable" << std::endl;
75  return false;
76  }
77  hS["sourcePath"] = buildpath;
78  }
79  else
80  {
81  fetchSetting("sourcePath");
82  }
83  return true;
84 }
85 
86 
87 void ARCSPackageManager::displaySettings()
88 {
89  std::cout << "Current settings" << std::endl;
90  QHashIterator<QString,QString> i(hS);
91  while(i.hasNext())
92  {
93  i.next();
94  displaySetting(i.key());
95  }
96 }
97 
98 
99 void ARCSPackageManager::storeSettings()
100 {
101  QHashIterator<QString,QString> i(hS);
102  while(i.hasNext())
103  {
104  i.next();
105  storeSetting(i.key());
106  }
107 }
108 
111 {
112  // first parse the REPOSITORY file
113  QFile data(hS["sourcePath"] + QDir::separator() + hS["repositoryFile"]);
114  parseRepositoryFile(data);
115 
116  // copy the REPOSITORY file in repository path
117  data.copy(hS["repositoryPath"] + QDir::separator() + hS["repositoryFile"]);
118 
119  QDir::setCurrent(hS["sourcePath"]);
120  // then compress all files and put them in repositoryPath
121  for (int i=0; i < libs.count() ; i++)
122  {
123  // put a new function here to parse and add files is required
124  if (QFileInfo(libPaths[i]).exists())
125  {
126  QString command = hS["compressCommand"];
127  command.replace("%a",hS["repositoryPath"]+QDir::separator()+libs[i]+hS["archiveExtension"])
128  .replace("%p",libPaths[i]);
129  std::cout << "Performing command: " << qPrintable(command) << std::endl;
130  QProcess::execute(command);
131 
132  QStringList relatedFiles = getRelatedFiles(hS["sourcePath"]+QDir::separator()+libPaths[i]);
133  for (int j=0; j < relatedFiles.count(); j++)
134  {
135  if (QFileInfo(relatedFiles[j]).exists())
136  {
137  QString command = hS["compressCommand"];
138  command.replace("%a",hS["repositoryPath"]+QDir::separator()+libs[i]+hS["archiveExtension"])
139  .replace("%p",relatedFiles[j]);
140  std::cout << "Performing command: " << qPrintable(command) << std::endl;
141  QProcess::execute(command);
142  }
143  }
144  }
145  else
146  std::cerr << "Library '" << qPrintable(libs[i]) << "': path '"
147  << qPrintable(libPaths[i]) << "' does not exist." << std::endl;
148  }
149 }
150 
151 void ARCSPackageManager::installAll()
152 {
153  QDir::setCurrent(hS["sourcePath"]);
154  ad->download(hS["repositoryUrl"]+"/"+hS["repositoryFile"]);
155 
156  if (!QFile::exists(hS["repositoryFile"]))
157  return;
158 
159  QFile data(hS["repositoryFile"]);
160  parseRepositoryFile(data);
161 
162  for (int i=0; i< libs.length(); i++)
163  {
164  installLibrary(libs[i]);
165  }
166 }
167 
168 
169 
170 void ARCSPackageManager::installLibrary(QString libraryName)
171 {
172  QDir::setCurrent(hS["sourcePath"]);
173  QString fullName = libraryName+hS["archiveExtension"];
174  ad->download(hS["repositoryUrl"]+"/"+fullName);
175 
176  if(QFile::exists(fullName))
177  {
178  QString command = hS["unCompressCommand"];
179  command.replace("%a",fullName);
180  if(!QProcess::execute(command))
181  QFile::remove(fullName);
182  else
183  {
184  std::cerr << "Failed to perform command: " << qPrintable(command) << std::endl;
185  }
186  }
187 
188 }
189 
190 
191 void ARCSPackageManager::parseRepositoryFile(QFile& data )
192 {
193  libs.clear();
194  libPaths.clear();
195 
196  if (!data.open(QFile::ReadOnly))
197  {
198  std::cerr << "Failed to open repository file: "
199  << qPrintable(hS["sourcePath"] + QDir::separator() + hS["repositoryFile"]) << std::endl;
200  return;
201  }
202 
203  std::cout << "Parsing repository file: "
204  << qPrintable(hS["repositoryFile"]) << std::endl;
205 
206  QTextStream repos(&data);
207  QString line;
208  do
209  {
210  line = repos.readLine();
211  QStringList sl=line.split(';');
212 
213  if (sl.count() >= 2 && !sl[0].startsWith("#"))
214  {
215  std::cout << "Registering library " << qPrintable(sl[0]) << std::endl;
216  libs << sl[0];
217  libPaths << sl[1];
218  }
219  } while(!line.isNull());
220  data.close();
221 }
222 
223 QStringList ARCSPackageManager::getRelatedFiles(QString libraryPath)
224 {
225  QDir dir(libraryPath);
226  if (!dir.exists())
227  return QStringList();
228 
229  QStringList alxFiles = dir.entryList(QStringList(QString("*.alx")),QDir::Files);
230  QStringList res;
231 
232  for (int i=0; i<alxFiles.count() ; i++)
233  {
234  QDomDocument doc;
235  QFile alxFile(dir.absolutePath()+QDir::separator()+alxFiles[i]);
236  if (alxFile.open(QIODevice::ReadOnly))
237  {
238  if (doc.setContent(&alxFile))
239  {
240  QDomElement root = doc.documentElement();
241  QDomNodeList dnl = root.elementsByTagName("related");
242 
243  for (int j=0; j< dnl.count(); j++)
244  {
245  QDomElement elt = dnl.at(j).toElement();
246  QString s = elt.attribute("path");
247  if (!s.isEmpty())
248  res << s;
249  }
250  }
251  }
252  }
253  return res;
254 }