29 using System.Collections.Generic;
31 using System.IO.Compression;
32 using System.Reflection;
36 using OpenSim.Framework;
37 using OpenSim.Framework.Monitoring;
38 using OpenSim.Framework.Serialization;
39 using OpenSim.Framework.Serialization.External;
40 using OpenSim.Region.CoreModules.World.Archiver;
41 using OpenSim.Region.Framework.Scenes;
42 using OpenSim.Services.Interfaces;
49 namespace OpenSim.
Region.CoreModules.
Avatar.Inventory.Archiver
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58 public bool SaveAssets {
get; set; }
64 public string FilterContent {
get; set; }
69 public int CountItems {
get; set; }
74 public int CountFiltered {
get; set; }
79 private const string STAR_WILDCARD =
"*";
83 private string m_invPath;
100 protected Dictionary<UUID, int> m_userUuids =
new Dictionary<UUID, int>();
105 private Stream m_saveStream;
112 UserAccount userInfo,
string invPath,
string savePath)
128 UserAccount userInfo,
string invPath, Stream saveStream)
133 m_userInfo = userInfo;
135 m_saveStream = saveStream;
136 m_assetGatherer =
new UuidGatherer(m_scene.AssetService);
139 FilterContent = null;
142 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids,
bool timedOut)
144 Exception reportedException = null;
145 bool succeeded =
true;
149 m_archiveWriter.Close();
153 reportedException = e;
158 m_saveStream.Close();
164 reportedException =
new Exception(
"Loading assets timed out");
167 m_module.TriggerInventoryArchiveSaved(
168 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException, CountItems, CountFiltered);
173 if (options.ContainsKey(
"exclude"))
175 if (((List<String>)options[
"exclude"]).Contains(inventoryItem.Name) ||
176 ((List<String>)options[
"exclude"]).Contains(inventoryItem.
ID.ToString()))
178 if (options.ContainsKey(
"verbose"))
181 "[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}",
182 inventoryItem.Name, inventoryItem.ID, path);
192 if (!CanUserArchiveObject(m_userInfo.PrincipalID, inventoryItem))
195 "[INVENTORY ARCHIVER]: Insufficient permissions, skipping inventory item {0} {1} at {2}",
196 inventoryItem.Name, inventoryItem.ID, path);
204 if (options.ContainsKey(
"verbose"))
206 "[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})",
207 inventoryItem.
ID, inventoryItem.
Name, inventoryItem.
AssetID);
209 string filename = path + CreateArchiveItemName(inventoryItem);
212 m_userUuids[inventoryItem.CreatorIdAsUuid] = 1;
214 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem,
options, userAccountService);
215 m_archiveWriter.WriteFile(filename, serialization);
217 AssetType itemAssetType = (AssetType)inventoryItem.AssetType;
223 if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
224 m_assetGatherer.AddForInspection(inventoryItem.AssetID);
239 if (options.ContainsKey(
"excludefolders"))
241 if (((List<String>)options[
"excludefolders"]).Contains(inventoryFolder.Name) ||
242 ((List<String>)options[
"excludefolders"]).Contains(inventoryFolder.
ID.ToString()))
244 if (options.ContainsKey(
"verbose"))
247 "[INVENTORY ARCHIVER]: Skipping folder {0} at {1}",
248 inventoryFolder.Name, path);
254 if (options.ContainsKey(
"verbose"))
255 m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Saving folder {0}", inventoryFolder.
Name);
257 if (saveThisFolderItself)
259 path += CreateArchiveFolderName(inventoryFolder);
262 m_archiveWriter.WriteDir(path);
266 = m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID);
270 SaveInvFolder(childFolder, path,
true,
options, userAccountService);
275 SaveInvItem(item, path,
options, userAccountService);
287 if (FilterContent == null)
290 bool permitted =
true;
292 bool canCopy = (InvItem.CurrentPermissions & (uint)
PermissionMask.Copy) != 0;
293 bool canTransfer = (InvItem.CurrentPermissions & (uint)
PermissionMask.Transfer) != 0;
294 bool canMod = (InvItem.CurrentPermissions & (uint)
PermissionMask.Modify) != 0;
296 if (FilterContent.Contains(
"C") && !canCopy)
299 if (FilterContent.Contains(
"T") && !canTransfer)
302 if (FilterContent.Contains(
"M") && !canMod)
313 if (options.ContainsKey(
"noassets") && (bool)options[
"noassets"])
317 if (options.ContainsKey(
"checkPermissions"))
320 if (options.TryGetValue(
"checkPermissions", out temp))
321 FilterContent = temp.ToString().ToUpper();
328 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID);
330 bool saveFolderContentsOnly =
false;
335 new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries);
337 int maxComponentIndex = components.Length - 1;
341 if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD)
343 saveFolderContentsOnly =
true;
346 else if (maxComponentIndex == -1)
350 saveFolderContentsOnly =
true;
353 m_invPath = String.Empty;
354 for (
int i = 0; i <= maxComponentIndex; i++)
356 m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER;
361 if (m_invPath.Length == 0)
363 inventoryFolder = rootFolder;
367 m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
368 List<InventoryFolderBase> candidateFolders
369 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, rootFolder, m_invPath);
370 if (candidateFolders.Count > 0)
371 inventoryFolder = candidateFolders[0];
375 if (inventoryFolder == null)
376 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
378 if (null == inventoryFolder && null == inventoryItem)
381 string errorMessage = string.Format(
"Aborted save. Could not find inventory path {0}", m_invPath);
383 m_module.TriggerInventoryArchiveSaved(m_id,
false, m_userInfo, m_invPath, m_saveStream, e, 0, 0);
389 m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Adding control file to archive.");
394 m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
396 if (inventoryFolder != null)
399 "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}",
400 inventoryFolder.Name,
402 m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath);
407 else if (inventoryItem != null)
410 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
411 inventoryItem.Name, inventoryItem.ID, m_invPath);
421 m_assetGatherer.GatherAll();
424 "[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetGatherer.GatheredUuids.Count);
429 m_assetGatherer.GatheredUuids, m_scene.AssetService,
430 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
431 options, ReceivedAllAssets);
433 WorkManager.RunInThread(o => ar.Execute(), null,
string.Format(
"AssetsRequest ({0})", m_scene.Name));
437 m_log.DebugFormat(
"[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified");
439 ReceivedAllAssets(
new List<UUID>(),
new List<UUID>(),
false);
444 m_saveStream.Close();
454 m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Saving user information for {0} users", m_userUuids.Count);
456 foreach (UUID creatorId
in m_userUuids.Keys)
459 UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, creatorId);
463 m_archiveWriter.WriteFile(
464 ArchiveConstants.USERS_PATH + creator.FirstName +
" " + creator.LastName +
".xml",
465 UserProfileSerializer.Serialize(creator.PrincipalID, creator.FirstName, creator.LastName));
469 m_log.WarnFormat(
"[INVENTORY ARCHIVER]: Failed to get creator profile for {0}", creatorId);
485 return CreateArchiveFolderName(folder.
Name, folder.
ID);
499 return CreateArchiveItemName(item.
Name, item.
ID);
510 return string.Format(
512 InventoryArchiveUtils.EscapeArchivePath(name),
525 return string.Format(
527 InventoryArchiveUtils.EscapeArchivePath(name),
539 int majorVersion, minorVersion;
541 if (options.ContainsKey(
"home"))
552 m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion);
554 StringWriter sw =
new StringWriter();
555 XmlTextWriter xtw =
new XmlTextWriter(sw);
556 xtw.Formatting = Formatting.Indented;
557 xtw.WriteStartDocument();
558 xtw.WriteStartElement(
"archive");
559 xtw.WriteAttributeString(
"major_version", majorVersion.ToString());
560 xtw.WriteAttributeString(
"minor_version", minorVersion.ToString());
562 xtw.WriteElementString(
"assets_included", SaveAssets.ToString());
564 xtw.WriteEndElement();
569 String s = sw.ToString();
Signals an inventory archiving problem
void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary< string, object > options, IUserAccountService userAccountService)
Gather uuids for a given entity.
void Execute(Dictionary< string, object > options, IUserAccountService userAccountService)
Execute the inventory write request
TarArchiveWriter m_archiveWriter
Constants for the archiving module
InventoryArchiveWriteRequest(UUID id, InventoryArchiverModule module, Scene scene, UserAccount userInfo, string invPath, Stream saveStream)
Constructor
UuidGatherer m_assetGatherer
Ionic.Zlib.GZipStream GZipStream
Temporary code to produce a tar archive in tar v7 format
static string CreateArchiveFolderName(InventoryFolderBase folder)
Create the archive name for a particular folder.
OpenSim.Framework.PermissionMask PermissionMask
Encapsulate the asynchronous requests for the assets required for an archive operation ...
This module loads and saves OpenSimulator inventory archives
void SaveUsers()
Save information for the users that we've collected.
static string CreateArchiveItemName(InventoryItemBase item)
Create the archive name for a particular item.
const string INVENTORY_NODE_NAME_COMPONENT_SEPARATOR
Inventory Item - contains all the properties associated with an individual inventory piece...
string CreateControlFile(Dictionary< string, object > options)
Create the control file for the archive
UUID ID
A UUID containing the ID for the inventory node itself
InventoryArchiveWriteRequest(UUID id, InventoryArchiverModule module, Scene scene, UserAccount userInfo, string invPath, string savePath)
Constructor
Ionic.Zlib.CompressionLevel CompressionLevel
static string CreateArchiveFolderName(string name, UUID id)
Create an archive folder name given its constituent components
virtual string Name
The name of the node (64 characters or less)
Ionic.Zlib.CompressionMode CompressionMode
static string CreateArchiveItemName(string name, UUID id)
Create an archive item name given its constituent components
void ReceivedAllAssets(ICollection< UUID > assetsFoundUuids, ICollection< UUID > assetsNotFoundUuids, bool timedOut)
void SaveInvFolder(InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, Dictionary< string, object > options, IUserAccountService userAccountService)
Save an inventory folder
const string INVENTORY_PATH
OpenSim.Framework.Serialization.TarArchiveWriter TarArchiveWriter
Used to serialize a whole inventory for transfer over the network.