Added ability to exclude inventory items or folders when saving IAR files.

0.7.4.1
Kevin Cozens 2012-02-10 14:09:46 -05:00 committed by Justin Clark-Casey (justincc)
parent eced091689
commit a366c05ae2
2 changed files with 128 additions and 84 deletions

View File

@ -91,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// Constructor /// Constructor
/// </summary> /// </summary>
public InventoryArchiveWriteRequest( public InventoryArchiveWriteRequest(
Guid id, InventoryArchiverModule module, Scene scene, Guid id, InventoryArchiverModule module, Scene scene,
UserAccount userInfo, string invPath, string savePath) UserAccount userInfo, string invPath, string savePath)
: this( : this(
id, id,
@ -107,7 +107,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// Constructor /// Constructor
/// </summary> /// </summary>
public InventoryArchiveWriteRequest( public InventoryArchiveWriteRequest(
Guid id, InventoryArchiverModule module, Scene scene, Guid id, InventoryArchiverModule module, Scene scene,
UserAccount userInfo, string invPath, Stream saveStream) UserAccount userInfo, string invPath, Stream saveStream)
{ {
m_id = id; m_id = id;
@ -125,7 +125,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{ {
Exception reportedException = null; Exception reportedException = null;
bool succeeded = true; bool succeeded = true;
try try
{ {
m_archiveWriter.Close(); m_archiveWriter.Close();
@ -146,6 +146,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService) protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
{ {
if (options.ContainsKey("exclude"))
{
if (((List<String>)options["exclude"]).Contains(inventoryItem.Name) ||
((List<String>)options["exclude"]).Contains(inventoryItem.ID.ToString()))
{
if (options.ContainsKey("verbose"))
{
m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}",
inventoryItem.Name, inventoryItem.ID, path);
}
return;
}
}
if (options.ContainsKey("verbose")) if (options.ContainsKey("verbose"))
m_log.InfoFormat( m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}", "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}",
@ -175,12 +190,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// <param name="options"></param> /// <param name="options"></param>
/// <param name="userAccountService"></param> /// <param name="userAccountService"></param>
protected void SaveInvFolder( protected void SaveInvFolder(
InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself,
Dictionary<string, object> options, IUserAccountService userAccountService) Dictionary<string, object> options, IUserAccountService userAccountService)
{ {
if (options.ContainsKey("excludefolders"))
{
if (((List<String>)options["excludefolders"]).Contains(inventoryFolder.Name) ||
((List<String>)options["excludefolders"]).Contains(inventoryFolder.ID.ToString()))
{
if (options.ContainsKey("verbose"))
{
m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Skipping folder {0} at {1}",
inventoryFolder.Name, path);
}
return;
}
}
if (options.ContainsKey("verbose")) if (options.ContainsKey("verbose"))
m_log.InfoFormat("[INVENTORY ARCHIVER]: Saving folder {0}", inventoryFolder.Name); m_log.InfoFormat("[INVENTORY ARCHIVER]: Saving folder {0}", inventoryFolder.Name);
if (saveThisFolderItself) if (saveThisFolderItself)
{ {
path += CreateArchiveFolderName(inventoryFolder); path += CreateArchiveFolderName(inventoryFolder);
@ -189,7 +219,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_archiveWriter.WriteDir(path); m_archiveWriter.WriteDir(path);
} }
InventoryCollection contents InventoryCollection contents
= m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID); = m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID);
foreach (InventoryFolderBase childFolder in contents.Folders) foreach (InventoryFolderBase childFolder in contents.Folders)
@ -216,16 +246,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
InventoryFolderBase inventoryFolder = null; InventoryFolderBase inventoryFolder = null;
InventoryItemBase inventoryItem = null; InventoryItemBase inventoryItem = null;
InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID);
bool saveFolderContentsOnly = false; bool saveFolderContentsOnly = false;
// Eliminate double slashes and any leading / on the path. // Eliminate double slashes and any leading / on the path.
string[] components string[] components
= m_invPath.Split( = m_invPath.Split(
new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries);
int maxComponentIndex = components.Length - 1; int maxComponentIndex = components.Length - 1;
// If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the
// folder itself. This may get more sophisicated later on // folder itself. This may get more sophisicated later on
if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD)
@ -233,13 +263,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
saveFolderContentsOnly = true; saveFolderContentsOnly = true;
maxComponentIndex--; maxComponentIndex--;
} }
m_invPath = String.Empty; m_invPath = String.Empty;
for (int i = 0; i <= maxComponentIndex; i++) for (int i = 0; i <= maxComponentIndex; i++)
{ {
m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER; m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER;
} }
// Annoyingly Split actually returns the original string if the input string consists only of delimiters // Annoyingly Split actually returns the original string if the input string consists only of delimiters
// Therefore if we still start with a / after the split, then we need the root folder // Therefore if we still start with a / after the split, then we need the root folder
if (m_invPath.Length == 0) if (m_invPath.Length == 0)
@ -249,25 +279,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
else else
{ {
m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
List<InventoryFolderBase> candidateFolders List<InventoryFolderBase> candidateFolders
= InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath);
if (candidateFolders.Count > 0) if (candidateFolders.Count > 0)
inventoryFolder = candidateFolders[0]; inventoryFolder = candidateFolders[0];
} }
// The path may point to an item instead // The path may point to an item instead
if (inventoryFolder == null) if (inventoryFolder == null)
inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
if (null == inventoryFolder && null == inventoryItem) if (null == inventoryFolder && null == inventoryItem)
{ {
// We couldn't find the path indicated // We couldn't find the path indicated
string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath);
Exception e = new InventoryArchiverException(errorMessage); Exception e = new InventoryArchiverException(errorMessage);
m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e); m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e);
throw e; throw e;
} }
m_archiveWriter = new TarArchiveWriter(m_saveStream); m_archiveWriter = new TarArchiveWriter(m_saveStream);
m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive."); m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive.");
@ -281,10 +311,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}",
inventoryFolder.Name, inventoryFolder.Name,
inventoryFolder.ID, inventoryFolder.ID,
m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath); m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath);
//recurse through all dirs getting dirs and files //recurse through all dirs getting dirs and files
SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService); SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService);
} }
@ -293,10 +323,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_log.DebugFormat( m_log.DebugFormat(
"[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
inventoryItem.Name, inventoryItem.ID, m_invPath); inventoryItem.Name, inventoryItem.ID, m_invPath);
SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService); SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService);
} }
// Don't put all this profile information into the archive right now. // Don't put all this profile information into the archive right now.
//SaveUsers(); //SaveUsers();
@ -355,7 +385,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// ///
/// These names are prepended with an inventory folder's UUID so that more than one folder can have the /// These names are prepended with an inventory folder's UUID so that more than one folder can have the
/// same name /// same name
/// ///
/// <param name="folder"></param> /// <param name="folder"></param>
/// <returns></returns> /// <returns></returns>
public static string CreateArchiveFolderName(InventoryFolderBase folder) public static string CreateArchiveFolderName(InventoryFolderBase folder)
@ -369,7 +399,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// ///
/// These names are prepended with an inventory item's UUID so that more than one item can have the /// These names are prepended with an inventory item's UUID so that more than one item can have the
/// same name /// same name
/// ///
/// <param name="item"></param> /// <param name="item"></param>
/// <returns></returns> /// <returns></returns>
public static string CreateArchiveItemName(InventoryItemBase item) public static string CreateArchiveItemName(InventoryItemBase item)
@ -415,7 +445,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
public string CreateControlFile(Dictionary<string, object> options) public string CreateControlFile(Dictionary<string, object> options)
{ {
int majorVersion, minorVersion; int majorVersion, minorVersion;
if (options.ContainsKey("home")) if (options.ContainsKey("home"))
{ {
majorVersion = 1; majorVersion = 1;
@ -425,10 +455,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{ {
majorVersion = 0; majorVersion = 0;
minorVersion = 3; minorVersion = 3;
} }
m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion);
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
XmlTextWriter xtw = new XmlTextWriter(sw); XmlTextWriter xtw = new XmlTextWriter(sw);
xtw.Formatting = Formatting.Indented; xtw.Formatting = Formatting.Indented;
@ -450,4 +480,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return s; return s;
} }
} }
} }

View File

@ -47,18 +47,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public string Name { get { return "Inventory Archiver Module"; } } public string Name { get { return "Inventory Archiver Module"; } }
public bool IsSharedModule { get { return true; } } public bool IsSharedModule { get { return true; } }
/// <value> /// <value>
/// Enable or disable checking whether the iar user is actually logged in /// Enable or disable checking whether the iar user is actually logged in
/// </value> /// </value>
// public bool DisablePresenceChecks { get; set; } // public bool DisablePresenceChecks { get; set; }
public event InventoryArchiveSaved OnInventoryArchiveSaved; public event InventoryArchiveSaved OnInventoryArchiveSaved;
/// <summary> /// <summary>
/// The file to load and save inventory if no filename has been specified /// The file to load and save inventory if no filename has been specified
/// </summary> /// </summary>
@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// Pending save completions initiated from the console /// Pending save completions initiated from the console
/// </value> /// </value>
protected List<Guid> m_pendingConsoleSaves = new List<Guid>(); protected List<Guid> m_pendingConsoleSaves = new List<Guid>();
/// <value> /// <value>
/// All scenes that this module knows about /// All scenes that this module knows about
/// </value> /// </value>
@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{ {
scene.RegisterModuleInterface<IInventoryArchiverModule>(this); scene.RegisterModuleInterface<IInventoryArchiverModule>(this);
OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
scene.AddCommand( scene.AddCommand(
"Archiving", this, "load iar", "Archiving", this, "load iar",
"load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]", "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]",
@ -119,11 +119,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
+ "<IAR path> is the filesystem path or URI from which to load the IAR." + "<IAR path> is the filesystem path or URI from which to load the IAR."
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
HandleLoadInvConsoleCommand); HandleLoadInvConsoleCommand);
scene.AddCommand( scene.AddCommand(
"Archiving", this, "save iar", "Archiving", this, "save iar",
"save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]", "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-e|--exclude=<name/uuid>] [-f|--excludefolder=<foldername/uuid>] [-v|--verbose]",
"Save user inventory archive (IAR).", "Save user inventory archive (IAR).",
"<first> is the user's first name.\n" "<first> is the user's first name.\n"
+ "<last> is the user's last name.\n" + "<last> is the user's last name.\n"
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n" + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n"
@ -131,32 +131,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
+ string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME) + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME)
+ "-h|--home=<url> adds the url of the profile service to the saved user information.\n" + "-h|--home=<url> adds the url of the profile service to the saved user information.\n"
+ "-c|--creators preserves information about foreign creators.\n" + "-c|--creators preserves information about foreign creators.\n"
+ "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine
+ "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine
+ "-v|--verbose extra debug messages.\n" + "-v|--verbose extra debug messages.\n"
+ "--noassets stops assets being saved to the IAR.", + "--noassets stops assets being saved to the IAR.",
HandleSaveInvConsoleCommand); HandleSaveInvConsoleCommand);
m_aScene = scene; m_aScene = scene;
} }
m_scenes[scene.RegionInfo.RegionID] = scene; m_scenes[scene.RegionInfo.RegionID] = scene;
} }
public void PostInitialise() {} public void PostInitialise() {}
public void Close() {} public void Close() {}
/// <summary> /// <summary>
/// Trigger the inventory archive saved event. /// Trigger the inventory archive saved event.
/// </summary> /// </summary>
protected internal void TriggerInventoryArchiveSaved( protected internal void TriggerInventoryArchiveSaved(
Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
Exception reportedException) Exception reportedException)
{ {
InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved; InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved;
if (handlerInventoryArchiveSaved != null) if (handlerInventoryArchiveSaved != null)
handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException);
} }
public bool ArchiveInventory( public bool ArchiveInventory(
Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
{ {
@ -164,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
} }
public bool ArchiveInventory( public bool ArchiveInventory(
Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
Dictionary<string, object> options) Dictionary<string, object> options)
{ {
if (m_scenes.Count > 0) if (m_scenes.Count > 0)
@ -188,7 +190,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return false; return false;
} }
return true; return true;
// } // }
// else // else
@ -202,15 +204,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return false; return false;
} }
public bool ArchiveInventory( public bool ArchiveInventory(
Guid id, string firstName, string lastName, string invPath, string pass, string savePath, Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
Dictionary<string, object> options) Dictionary<string, object> options)
{ {
if (m_scenes.Count > 0) if (m_scenes.Count > 0)
{ {
UserAccount userInfo = GetUserInfo(firstName, lastName, pass); UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
if (userInfo != null) if (userInfo != null)
{ {
// if (CheckPresence(userInfo.PrincipalID)) // if (CheckPresence(userInfo.PrincipalID))
@ -228,7 +230,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return false; return false;
} }
return true; return true;
// } // }
// else // else
@ -239,7 +241,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// } // }
} }
} }
return false; return false;
} }
@ -247,9 +249,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{ {
return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
} }
public bool DearchiveInventory( public bool DearchiveInventory(
string firstName, string lastName, string invPath, string pass, Stream loadStream, string firstName, string lastName, string invPath, string pass, Stream loadStream,
Dictionary<string, object> options) Dictionary<string, object> options)
{ {
if (m_scenes.Count > 0) if (m_scenes.Count > 0)
@ -295,22 +297,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return false; return false;
} }
public bool DearchiveInventory( public bool DearchiveInventory(
string firstName, string lastName, string invPath, string pass, string loadPath, string firstName, string lastName, string invPath, string pass, string loadPath,
Dictionary<string, object> options) Dictionary<string, object> options)
{ {
if (m_scenes.Count > 0) if (m_scenes.Count > 0)
{ {
UserAccount userInfo = GetUserInfo(firstName, lastName, pass); UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
if (userInfo != null) if (userInfo != null)
{ {
// if (CheckPresence(userInfo.PrincipalID)) // if (CheckPresence(userInfo.PrincipalID))
// { // {
InventoryArchiveReadRequest request; InventoryArchiveReadRequest request;
bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
try try
{ {
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge);
@ -324,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return false; return false;
} }
UpdateClientWithLoadedNodes(userInfo, request.Execute()); UpdateClientWithLoadedNodes(userInfo, request.Execute());
return true; return true;
@ -340,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return false; return false;
} }
/// <summary> /// <summary>
/// Load inventory from an inventory file archive /// Load inventory from an inventory file archive
/// </summary> /// </summary>
@ -351,26 +353,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{ {
Dictionary<string, object> options = new Dictionary<string, object>(); Dictionary<string, object> options = new Dictionary<string, object>();
OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; });
List<string> mainParams = optionSet.Parse(cmdparams); List<string> mainParams = optionSet.Parse(cmdparams);
if (mainParams.Count < 6) if (mainParams.Count < 6)
{ {
m_log.Error( m_log.Error(
"[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] <first name> <last name> <inventory path> <user password> [<load file path>]"); "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] <first name> <last name> <inventory path> <user password> [<load file path>]");
return; return;
} }
string firstName = mainParams[2]; string firstName = mainParams[2];
string lastName = mainParams[3]; string lastName = mainParams[3];
string invPath = mainParams[4]; string invPath = mainParams[4];
string pass = mainParams[5]; string pass = mainParams[5];
string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
m_log.InfoFormat( m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}",
loadPath, invPath, firstName, lastName); loadPath, invPath, firstName, lastName);
if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options))
m_log.InfoFormat( m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}",
@ -381,7 +383,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
} }
} }
/// <summary> /// <summary>
/// Save inventory to a file archive /// Save inventory to a file archive
/// </summary> /// </summary>
@ -398,6 +400,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; });
ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); ops.Add("c|creators", delegate(string v) { options["creators"] = v; });
ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
ops.Add("e|exclude=", delegate(string v)
{
if (!options.ContainsKey("exclude"))
options["exclude"] = new List<String>();
((List<String>)options["exclude"]).Add(v);
});
ops.Add("f|excludefolder=", delegate(string v)
{
if (!options.ContainsKey("excludefolders"))
options["excludefolders"] = new List<String>();
((List<String>)options["excludefolders"]).Add(v);
});
List<string> mainParams = ops.Parse(cmdparams); List<string> mainParams = ops.Parse(cmdparams);
@ -406,10 +420,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (mainParams.Count < 6) if (mainParams.Count < 6)
{ {
m_log.Error( m_log.Error(
"[INVENTORY ARCHIVER]: usage is save iar [-h|--home=<url>] [--noassets] <first name> <last name> <inventory path> <user password> [<save file path>] [-c|--creators] [-v|--verbose]"); "[INVENTORY ARCHIVER]: save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-e|--exclude=<name/uuid>] [-f|--excludefolder=<foldername/uuid>] [-v|--verbose]");
return; return;
} }
if (options.ContainsKey("home")) if (options.ContainsKey("home"))
m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR"); m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR");
@ -418,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
string invPath = mainParams[4]; string invPath = mainParams[4];
string pass = mainParams[5]; string pass = mainParams[5];
string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
m_log.InfoFormat( m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
savePath, invPath, firstName, lastName); savePath, invPath, firstName, lastName);
@ -433,9 +447,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
} }
} }
private void SaveInvConsoleCommandCompleted( private void SaveInvConsoleCommandCompleted(
Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
Exception reportedException) Exception reportedException)
{ {
lock (m_pendingConsoleSaves) lock (m_pendingConsoleSaves)
@ -445,7 +459,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
else else
return; return;
} }
if (succeeded) if (succeeded)
{ {
m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName); m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName);
@ -453,11 +467,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
else else
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}", "[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}",
userInfo.FirstName, userInfo.LastName, reportedException.Message); userInfo.FirstName, userInfo.LastName, reportedException.Message);
} }
} }
/// <summary> /// <summary>
/// Get user information for the given name. /// Get user information for the given name.
/// </summary> /// </summary>
@ -467,13 +481,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// <returns></returns> /// <returns></returns>
protected UserAccount GetUserInfo(string firstName, string lastName, string pass) protected UserAccount GetUserInfo(string firstName, string lastName, string pass)
{ {
UserAccount account UserAccount account
= m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, firstName, lastName); = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, firstName, lastName);
if (null == account) if (null == account)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}", "[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}",
firstName, lastName); firstName, lastName);
return null; return null;
} }
@ -488,7 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
else else
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.", "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.",
firstName, lastName); firstName, lastName);
return null; return null;
} }
@ -499,7 +513,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return null; return null;
} }
} }
/// <summary> /// <summary>
/// Notify the client of loaded nodes if they are logged in /// Notify the client of loaded nodes if they are logged in
/// </summary> /// </summary>
@ -508,22 +522,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{ {
if (loadedNodes.Count == 0) if (loadedNodes.Count == 0)
return; return;
foreach (Scene scene in m_scenes.Values) foreach (Scene scene in m_scenes.Values)
{ {
ScenePresence user = scene.GetScenePresence(userInfo.PrincipalID); ScenePresence user = scene.GetScenePresence(userInfo.PrincipalID);
if (user != null && !user.IsChildAgent) if (user != null && !user.IsChildAgent)
{ {
foreach (InventoryNodeBase node in loadedNodes) foreach (InventoryNodeBase node in loadedNodes)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", // "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}",
// user.Name, node.Name); // user.Name, node.Name);
user.ControllingClient.SendBulkUpdateInventory(node); user.ControllingClient.SendBulkUpdateInventory(node);
} }
break; break;
} }
} }
@ -538,7 +552,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// { // {
// if (DisablePresenceChecks) // if (DisablePresenceChecks)
// return true; // return true;
// //
// foreach (Scene scene in m_scenes.Values) // foreach (Scene scene in m_scenes.Values)
// { // {
// ScenePresence p; // ScenePresence p;