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:
hikerstk
2011-01-17 05:44:33 +00:00
parent 80c85a7bb8
commit a4ee467c49
7 changed files with 85 additions and 52 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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)