From a4ee467c495ce8501530d65184532f7fbdda4e10 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Mon, 17 Jan 2011 05:44:33 +0000 Subject: [PATCH] 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 --- src/addons/addons_manager.cpp | 62 +++++++++++-------- src/addons/addons_manager.hpp | 5 +- src/addons/network_http.cpp | 8 ++- src/addons/zip.cpp | 12 +++- src/io/file_manager.cpp | 3 +- src/states_screens/dialogs/addons_loading.cpp | 40 ++++++++---- src/states_screens/main_menu_screen.cpp | 7 +-- 7 files changed, 85 insertions(+), 52 deletions(-) diff --git a/src/addons/addons_manager.cpp b/src/addons/addons_manager.cpp index e401b7742..58885cc35 100644 --- a/src/addons/addons_manager.cpp +++ b/src/addons/addons_manager.cpp @@ -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 diff --git a/src/addons/addons_manager.hpp b/src/addons/addons_manager.hpp index 9c10335a7..9ecf9332b 100644 --- a/src/addons/addons_manager.hpp +++ b/src/addons/addons_manager.hpp @@ -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; diff --git a/src/addons/network_http.cpp b/src/addons/network_http.cpp index a1930e02f..bb103e3de 100644 --- a/src/addons/network_http.cpp +++ b/src/addons/network_http.cpp @@ -174,6 +174,7 @@ void NetworkHttp::checkNewServer(const XMLNode *xml) */ void NetworkHttp::updateNews(const XMLNode *xml) { + bool error = true; for(unsigned int i=0; igetNumNodes(); 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; diff --git a/src/addons/zip.cpp b/src/addons/zip.cpp index 5fda1771b..7fde6b433 100644 --- a/src/addons/zip.cpp +++ b/src/addons/zip.cpp @@ -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; igetFileCount(); 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 diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 8f44e0ab3..3329d4d30 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -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 diff --git a/src/states_screens/dialogs/addons_loading.cpp b/src/states_screens/dialogs/addons_loading.cpp index 0e25806dd..c00311e51 100644 --- a/src/states_screens/dialogs/addons_loading.cpp +++ b/src/states_screens/dialogs/addons_loading.cpp @@ -48,6 +48,9 @@ AddonsLoading::AddonsLoading(const float w, const float h, m_icon = getWidget ("icon" ); m_progress = getWidget("progress"); m_install_button = getWidget ("install" ); + m_back_button = getWidget ("cancel" ); + m_state = getWidget ("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 diff --git a/src/states_screens/main_menu_screen.cpp b/src/states_screens/main_menu_screen.cpp index 8782388ec..52c1db33f 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -118,12 +118,7 @@ void MainMenuScreen::onUpdate(float delta, irr::video::IVideoDriver* driver) LabelWidget* w = this->getWidget("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("lang_combo"); if (lang_combo != NULL)