Started to add some error handling, fixed handling of zip files
with directories in them. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7467 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -275,7 +275,13 @@ int AddonsManager::getAddonIndex(const std::string &id) const
|
||||
} // getAddonIndex
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void AddonsManager::install(const Addon &addon)
|
||||
/** Installs or updates (i.e. = install on top of an existing installation) an
|
||||
* addon. It checks for the directories and then unzips the file (which must
|
||||
* already have been downloaded).
|
||||
* \param addon Addon data for the addon to install.
|
||||
* \return true if installation was successful.
|
||||
*/
|
||||
bool AddonsManager::install(const Addon &addon)
|
||||
{
|
||||
bool success=true;
|
||||
const std::string &id = addon.getId();
|
||||
@@ -293,7 +299,7 @@ void AddonsManager::install(const Addon &addon)
|
||||
// TODO: show a message in the interface
|
||||
std::cerr << "[Addons] Failed to unzip '" << from << "' to '"
|
||||
<< to << "'\n";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = getAddonIndex(addon.getId());
|
||||
@@ -317,8 +323,35 @@ void AddonsManager::install(const Addon &addon)
|
||||
}
|
||||
}
|
||||
saveInstalled(addon.getType());
|
||||
return true;
|
||||
} // install
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Removes all files froma login.
|
||||
* \param addon The addon to be removed.
|
||||
* \return True if uninstallation was successful.
|
||||
*/
|
||||
bool AddonsManager::uninstall(const Addon &addon)
|
||||
{
|
||||
std::cout << "[Addons] Uninstalling <"
|
||||
<< addon.getName() << ">\n";
|
||||
|
||||
// addon is a const reference, and to avoid removing the const, we
|
||||
// find the proper index again to modify the installed state
|
||||
int index = getAddonIndex(addon.getId());
|
||||
assert(index>=0 && index < (int)m_addons_list.getData().size());
|
||||
m_addons_list.getData()[index].setInstalled(false);
|
||||
|
||||
//write the xml file with the informations about installed karts
|
||||
std::string name = addon.getType()+"s/"+addon.getId();
|
||||
std::string dest_file = file_manager->getAddonsFile(name);
|
||||
|
||||
//remove the addons directory
|
||||
bool error = !file_manager->removeDirectory(dest_file);
|
||||
saveInstalled(addon.getType());
|
||||
return !error;
|
||||
} // uninstall
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void AddonsManager::saveInstalled(const std::string &type)
|
||||
{
|
||||
@@ -346,30 +379,5 @@ void AddonsManager::saveInstalled(const std::string &type)
|
||||
track_manager->loadTrackList();
|
||||
} // saveInstalled
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Removes all files froma login.
|
||||
\param addon The addon to be removed.
|
||||
*/
|
||||
void AddonsManager::uninstall(const Addon &addon)
|
||||
{
|
||||
std::cout << "[Addons] Uninstalling <"
|
||||
<< addon.getName() << ">\n";
|
||||
|
||||
// addon is a const reference, and to avoid removing the const, we
|
||||
// find the proper index again to modify the installed state
|
||||
int index = getAddonIndex(addon.getId());
|
||||
assert(index>=0 && index < (int)m_addons_list.getData().size());
|
||||
m_addons_list.getData()[index].setInstalled(false);
|
||||
|
||||
//write the xml file with the informations about installed karts
|
||||
std::string name=addon.getType()+"s/"+addon.getId();
|
||||
std::string dest_file = file_manager->getAddonsFile(name);
|
||||
|
||||
//remove the addons directory
|
||||
file_manager->removeDirectory(dest_file);
|
||||
saveInstalled(addon.getType());
|
||||
|
||||
} // uninstall
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -77,12 +77,11 @@ public:
|
||||
const Addon* getAddon(const std::string &id) const;
|
||||
int getAddonIndex(const std::string &id) const;
|
||||
|
||||
/** Install or upgrade the selected addon. */
|
||||
void install(const Addon &addon);
|
||||
bool install(const Addon &addon);
|
||||
|
||||
/** Uninstall the selected addon. This method will remove all the
|
||||
* directory of the addon.*/
|
||||
void uninstall(const Addon &addon);
|
||||
bool uninstall(const Addon &addon);
|
||||
|
||||
/** Get the install state (if it is the download, unzip...)*/
|
||||
const std::string& getDownloadStateAsStr() const;
|
||||
|
||||
@@ -174,6 +174,7 @@ void NetworkHttp::checkNewServer(const XMLNode *xml)
|
||||
*/
|
||||
void NetworkHttp::updateNews(const XMLNode *xml)
|
||||
{
|
||||
bool error = true;
|
||||
for(unsigned int i=0; i<xml->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode *node = xml->getNode(i);
|
||||
@@ -181,7 +182,11 @@ void NetworkHttp::updateNews(const XMLNode *xml)
|
||||
std::string news;
|
||||
node->get("text", &news);
|
||||
m_news.set(news);
|
||||
error = false;
|
||||
}
|
||||
if(error)
|
||||
m_news.set("Can't access stkaddons server...");
|
||||
|
||||
} // updateNews
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -238,7 +243,8 @@ bool NetworkHttp::downloadFileInternal(const std::string &file,
|
||||
const std::string &save_filename,
|
||||
bool is_asynchron)
|
||||
{
|
||||
printf("Downloading %s\n", file.c_str());
|
||||
if(UserConfigParams::m_verbosity>=3)
|
||||
printf("Downloading %s\n", file.c_str());
|
||||
CURL *session = curl_easy_init();
|
||||
std::string full_url = (std::string)UserConfigParams::m_server_addons
|
||||
+ "/" + file;
|
||||
|
||||
@@ -57,7 +57,8 @@ bool extract_zip(const std::string &from, const std::string &to)
|
||||
{
|
||||
//Add the zip to the file system
|
||||
IFileSystem *file_system = irr_driver->getDevice()->getFileSystem();
|
||||
file_system->addZipFileArchive(from.c_str(), /*ignoreCase*/false, false);
|
||||
file_system->addZipFileArchive(from.c_str(), /*ignoreCase*/false,
|
||||
/*ignorePath*/true);
|
||||
|
||||
// Get the recently added archive, which is necessary to get a
|
||||
// list of file in the zip archive.
|
||||
@@ -65,12 +66,14 @@ bool extract_zip(const std::string &from, const std::string &to)
|
||||
file_system->getFileArchive(file_system->getFileArchiveCount()-1);
|
||||
const io::IFileList *zip_file_list = zip_archive->getFileList();
|
||||
// Copy all files from the zip archive to the destination
|
||||
bool error = false;
|
||||
for(unsigned int i=0; i<zip_file_list->getFileCount(); i++)
|
||||
{
|
||||
const std::string current_file=zip_file_list->getFileName(i).c_str();
|
||||
std::cout << current_file << std::endl;
|
||||
if(zip_file_list->isDirectory(i)) continue;
|
||||
if(current_file[0]=='.') continue;
|
||||
const std::string base = StringUtils::getBasename(current_file);
|
||||
|
||||
IReadFile* src_file =
|
||||
file_system->createAndOpenFile(current_file.c_str());
|
||||
@@ -78,17 +81,19 @@ bool extract_zip(const std::string &from, const std::string &to)
|
||||
{
|
||||
printf("Can't read file '%s'.\n", current_file.c_str());
|
||||
printf("This is ignored, but the addon might not work.\n");
|
||||
error = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
IWriteFile* dst_file =
|
||||
file_system->createAndWriteFile((to+"/"+current_file).c_str());
|
||||
file_system->createAndWriteFile((to+"/"+base).c_str());
|
||||
if(dst_file == NULL)
|
||||
{
|
||||
printf("Couldn't create the file '%s'.\n",
|
||||
(to+"/"+current_file).c_str());
|
||||
printf("The directory might not exist.\n");
|
||||
printf("This is ignored, but the addon might not work.\n");
|
||||
error = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -97,6 +102,7 @@ bool extract_zip(const std::string &from, const std::string &to)
|
||||
printf("Could not copy '%s' from archive '%s'.\n",
|
||||
current_file.c_str(), from.c_str());
|
||||
printf("This is ignored, but the addon might not work.\n");
|
||||
error = true;
|
||||
}
|
||||
dst_file->drop();
|
||||
src_file->drop();
|
||||
@@ -109,6 +115,6 @@ bool extract_zip(const std::string &from, const std::string &to)
|
||||
// on removing it. getAbsolutePath will convert all \ to /.
|
||||
file_system->removeFileArchive(file_system->getAbsolutePath(from.c_str()));
|
||||
|
||||
return true;
|
||||
return !error;
|
||||
} // extract_zip
|
||||
#endif
|
||||
|
||||
@@ -724,6 +724,7 @@ bool FileManager::removeFile(const std::string &name) const
|
||||
* easily recursively delete further subdirectories, but this is commented
|
||||
* out atm (to limit the amount of damage in case of a bug).
|
||||
* \param name Directory name to remove.
|
||||
* \param return True if removal was successful.
|
||||
*/
|
||||
bool FileManager::removeDirectory(const std::string &name) const
|
||||
{
|
||||
@@ -750,7 +751,7 @@ bool FileManager::removeDirectory(const std::string &name) const
|
||||
#ifdef WIN32
|
||||
return ::RemoveDirectory(name.c_str())==TRUE;
|
||||
#else
|
||||
return remove(name.c_str());
|
||||
return remove(name.c_str())==0;
|
||||
#endif
|
||||
} // remove directory
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@ AddonsLoading::AddonsLoading(const float w, const float h,
|
||||
m_icon = getWidget<IconButtonWidget> ("icon" );
|
||||
m_progress = getWidget<ProgressBarWidget>("progress");
|
||||
m_install_button = getWidget<ButtonWidget> ("install" );
|
||||
m_back_button = getWidget<ButtonWidget> ("cancel" );
|
||||
m_state = getWidget<LabelWidget> ("state" );
|
||||
|
||||
if(m_progress)
|
||||
m_progress->setVisible(false);
|
||||
|
||||
@@ -91,6 +94,8 @@ GUIEngine::EventPropagation
|
||||
{
|
||||
m_progress->setValue(0);
|
||||
m_progress->setVisible(true);
|
||||
// Change the 'back' button into a 'cancel' button.
|
||||
m_back_button->setText(_("Cancel"));
|
||||
//m_progress->m_h = m_install_button->m_h;
|
||||
//m_progress->m_x = m_install_button->m_x;
|
||||
//m_progress->m_y = m_install_button->m_y;
|
||||
@@ -116,15 +121,15 @@ void AddonsLoading::onUpdate(float delta)
|
||||
m_progress->setValue((int)(progress*100.0f));
|
||||
if(progress<0)
|
||||
{
|
||||
// TODO: show a message in the interface
|
||||
fprintf(stderr, "[Addons] Failed to download '%s'\n",
|
||||
m_addon.getZipFileName().c_str());
|
||||
dismiss();
|
||||
m_state->setText(_("Donwload failed.\n"));
|
||||
m_back_button->setText(_("Back"));
|
||||
return;
|
||||
}
|
||||
else if(progress>=1.0f)
|
||||
{
|
||||
printf("Download finished.\n");
|
||||
m_back_button->setText(_("Back"));
|
||||
// No sense to update state text, since it all
|
||||
// happens before the GUI is refrehsed.
|
||||
doInstall();
|
||||
return;
|
||||
}
|
||||
@@ -157,17 +162,30 @@ void AddonsLoading::startDownload()
|
||||
*/
|
||||
void AddonsLoading::doInstall()
|
||||
{
|
||||
bool error=false;
|
||||
if(!m_addon.isInstalled() || m_addon.needsUpdate())
|
||||
{
|
||||
addons_manager->install(m_addon);
|
||||
error = !addons_manager->install(m_addon);
|
||||
}
|
||||
else
|
||||
{
|
||||
addons_manager->uninstall(m_addon);
|
||||
error = !addons_manager->uninstall(m_addon);
|
||||
}
|
||||
if(error)
|
||||
{
|
||||
core::stringw msg = StringUtils::insertValues(
|
||||
_("Problems installing the addon '%s', it might not work."),
|
||||
core::stringw(m_addon.getName().c_str()));
|
||||
m_state->setText(msg.c_str());
|
||||
m_progress->setVisible(false);
|
||||
m_install_button->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The list of the addon screen needs to be updated to correctly
|
||||
// display the newly (un)installed addon.
|
||||
AddonsScreen::getInstance()->loadList();
|
||||
dismiss();
|
||||
}
|
||||
// The list of the addon screen needs to be updated to correctly
|
||||
// display the newly (un)installed addon.
|
||||
AddonsScreen::getInstance()->loadList();
|
||||
dismiss();
|
||||
} // doInstall
|
||||
#endif
|
||||
|
||||
@@ -118,12 +118,7 @@ void MainMenuScreen::onUpdate(float delta, irr::video::IVideoDriver* driver)
|
||||
|
||||
LabelWidget* w = this->getWidget<LabelWidget>("info_addons");
|
||||
const std::string &news_text = network_http->getNewsMessage();
|
||||
if(news_text == "")
|
||||
{
|
||||
w->setText("Can't access stkaddons server...");
|
||||
}
|
||||
else
|
||||
w->setText(news_text.c_str());
|
||||
w->setText(news_text.c_str());
|
||||
|
||||
IconButtonWidget* lang_combo = this->getWidget<IconButtonWidget>("lang_combo");
|
||||
if (lang_combo != NULL)
|
||||
|
||||
Reference in New Issue
Block a user