diff --git a/src/DownloadEngineFactory.cc b/src/DownloadEngineFactory.cc index ee328c5e..ac7048bb 100644 --- a/src/DownloadEngineFactory.cc +++ b/src/DownloadEngineFactory.cc @@ -50,6 +50,7 @@ #include "FillRequestGroupCommand.h" #include "FileAllocationDispatcherCommand.h" #include "AutoSaveCommand.h" +#include "SaveSessionCommand.h" #include "HaveEraseCommand.h" #include "TimedHaltCommand.h" #include "WatchProcessCommand.h" @@ -158,6 +159,11 @@ DownloadEngineFactory::newDownloadEngine (new AutoSaveCommand(e->newCUID(), e.get(), op->getAsInt(PREF_AUTO_SAVE_INTERVAL))); } + if(op->getAsInt(PREF_SAVE_SESSION_INTERVAL) > 0) { + e->addRoutineCommand + (new SaveSessionCommand(e->newCUID(), e.get(), + op->getAsInt(PREF_SAVE_SESSION_INTERVAL))); + } e->addRoutineCommand(new HaveEraseCommand(e->newCUID(), e.get(), 10)); { time_t stopSec = op->getAsInt(PREF_STOP); diff --git a/src/Makefile.am b/src/Makefile.am index b507aea7..bf5805b7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -244,7 +244,8 @@ SRCS = SocketCore.cc SocketCore.h\ WrDiskCache.cc WrDiskCache.h\ WrDiskCacheEntry.cc WrDiskCacheEntry.h\ GroupId.cc GroupId.h\ - IndexedList.h + IndexedList.h\ + SaveSessionCommand.h SaveSessionCommand.cc if MINGW_BUILD SRCS += WinConsoleFile.cc WinConsoleFile.h diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc index 7dfa7dab..c6476197 100644 --- a/src/OptionHandlerFactory.cc +++ b/src/OptionHandlerFactory.cc @@ -728,6 +728,15 @@ std::vector OptionHandlerFactory::createOptionHandlers() op->setChangeGlobalOption(true); handlers.push_back(op); } + { + OptionHandler* op(new NumberOptionHandler + (PREF_SAVE_SESSION_INTERVAL, + TEXT_SAVE_SESSION_INTERVAL, + "0", + 0)); + op->addTag(TAG_ADVANCED); + handlers.push_back(op); + } { OptionHandler* op(new BooleanOptionHandler (PREF_SELECT_LEAST_USED_HOST, diff --git a/src/SaveSessionCommand.cc b/src/SaveSessionCommand.cc new file mode 100644 index 00000000..2d990532 --- /dev/null +++ b/src/SaveSessionCommand.cc @@ -0,0 +1,78 @@ +/* */ +#include "SaveSessionCommand.h" +#include "DownloadEngine.h" +#include "RequestGroupMan.h" +#include "SessionSerializer.h" +#include "prefs.h" +#include "fmt.h" +#include "LogFactory.h" +#include "Option.h" + +namespace aria2 { + +SaveSessionCommand::SaveSessionCommand +(cuid_t cuid, DownloadEngine* e, time_t interval) + : TimeBasedCommand(cuid, e, interval, true) +{} + +SaveSessionCommand::~SaveSessionCommand() {} + +void SaveSessionCommand::preProcess() +{ + if(getDownloadEngine()->getRequestGroupMan()->downloadFinished() || + getDownloadEngine()->isHaltRequested()) { + enableExit(); + } +} + +void SaveSessionCommand::process() +{ + const std::string& filename = getDownloadEngine()->getOption() + ->get(PREF_SAVE_SESSION); + if(!filename.empty()) { + SessionSerializer sessionSerializer(getDownloadEngine()-> + getRequestGroupMan()); + if(sessionSerializer.save(filename)) { + A2_LOG_NOTICE(fmt(_("Serialized session to '%s' successfully."), + filename.c_str())); + } else { + A2_LOG_NOTICE(fmt(_("Failed to serialize session to '%s'."), + filename.c_str())); + } + } +} + +} // namespace aria2 diff --git a/src/SaveSessionCommand.h b/src/SaveSessionCommand.h new file mode 100644 index 00000000..ab4d271f --- /dev/null +++ b/src/SaveSessionCommand.h @@ -0,0 +1,56 @@ +/* */ +#ifndef D_SAVE_SESSION_COMMAND_H +#define D_SAVE_SESSION_COMMAND_H + +#include "TimeBasedCommand.h" + +namespace aria2 { + +class SaveSessionCommand : public TimeBasedCommand +{ +public: + SaveSessionCommand(cuid_t cuid, DownloadEngine* e, time_t interval); + + virtual ~SaveSessionCommand(); + + virtual void preProcess(); + + virtual void process(); +}; + +} // namespace aria2 + +#endif // D_SAVE_SESSION_COMMAND_H diff --git a/src/prefs.cc b/src/prefs.cc index 3b18eeb6..afeee6b5 100644 --- a/src/prefs.cc +++ b/src/prefs.cc @@ -356,6 +356,8 @@ const Pref* PREF_FORCE_SAVE = makePref("force-save"); const Pref* PREF_DISK_CACHE = makePref("disk-cache"); // value: string const Pref* PREF_GID = makePref("gid"); +// values: 1*digit +const Pref* PREF_SAVE_SESSION_INTERVAL = makePref("save-session-interval"); /** * FTP related preferences diff --git a/src/prefs.h b/src/prefs.h index 8b6453a4..9cc5f3bc 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -291,6 +291,8 @@ extern const Pref* PREF_FORCE_SAVE; extern const Pref* PREF_DISK_CACHE; // value: string extern const Pref* PREF_GID; +// values: 1*digit +extern const Pref* PREF_SAVE_SESSION_INTERVAL; /** * FTP related preferences diff --git a/src/usage_text.h b/src/usage_text.h index 6eee9084..69b9efaf 100644 --- a/src/usage_text.h +++ b/src/usage_text.h @@ -944,3 +944,8 @@ " by aria2.") #define TEXT_CONSOLE_LOG_LEVEL \ _(" --console-log-level=LEVEL Set log level to output to console.") +#define TEXT_SAVE_SESSION_INTERVAL \ + _(" --save-session-interval=SEC Save error/unfinished downloads to a file\n" \ + " specified by --save-session option every SEC\n" \ + " seconds. If 0 is given, file will be saved only\n" \ + " when aria2 exits.")