/// <summary> /// Creates the metadata.txt file for a list of updates to export. /// Copies update IDs and XML data to this file /// </summary> /// <param name="updatesToExport">The updates to export</param> /// <param name="metadataTextFile">Destination metadata file</param> private void WriteMetadataFile(List <Update> updatesToExport, string metadataTextFile) { // Each line in the metadata text file contains multiple lines of the following format: // <update GUID>,<update revision>,<xml size>,<xml>\r\n // There is one line for each update exported // Open the metadata file for writing using (var metadataFile = File.CreateText(metadataTextFile)) { var allUpdates = new List <Update>(MetadataSource.GetCategories()); allUpdates.AddRange(updatesToExport); var progress = new OperationProgress() { CurrentOperation = OperationType.ExportUpdateXmlBlobProgress, Maximum = allUpdates.Count, Current = 0 }; foreach (var update in allUpdates) { using (var metadataStream = MetadataSource.GetUpdateMetadataStream(update.Identity)) { using (var metadataReader = new StreamReader(metadataStream)) { var xmlData = metadataReader.ReadToEnd(); // Write one line with GUID, revision, XML length, XML data metadataFile.WriteLine("{0},{1:x8},{2:x8},{3}", update.Identity.Raw.UpdateID, update.Identity.Raw.RevisionNumber, xmlData.Length, xmlData); } } progress.Current += 1; ExportProgress?.Invoke(this, progress); } } }
/// <summary> /// Instantiate the server and serve updates from the local repo /// </summary> /// <param name="metadataSource">The update metadata source to serve updates from</param> /// <param name="filter">The filter for which updates to serve.</param> /// <param name="serviceConfig">Service configuration.</param> public ServerSyncWebService(IMetadataSource metadataSource, MetadataFilter filter, ServerSyncConfigData serviceConfig) { MetadataSource = metadataSource; ServiceConfiguration = serviceConfig; UpdatesFilter = filter; Categories = metadataSource.GetCategories(); FilteredUpdates = metadataSource.GetUpdates(filter).ToDictionary(u => u.Identity); // If an update contains bundled updates, those bundled updates must also be made available to downstream servers var bundledUpdates = FilteredUpdates.Values.Where(u => u.IsBundle).SelectMany(u => u.BundledUpdates).Distinct().ToList(); foreach (var bundledUpdateId in bundledUpdates) { if (!FilteredUpdates.ContainsKey(bundledUpdateId)) { FilteredUpdates.Add(bundledUpdateId, metadataSource.GetUpdate(bundledUpdateId)); } } // Build the lookup tables by products and classifications ProductsIndex = new Dictionary <Guid, List <Update> >(); ClassificationsIndex = new Dictionary <Guid, List <Update> >(); foreach (var update in FilteredUpdates.Values) { if (update.HasProduct) { foreach (var productId in update.ProductIds) { if (!ProductsIndex.ContainsKey(productId)) { ProductsIndex[productId] = new List <Update>(); } ProductsIndex[productId].Add(update); } } if (update.HasClassification) { foreach (var classificationId in update.ClassificationIds) { if (!ClassificationsIndex.ContainsKey(classificationId)) { ClassificationsIndex[classificationId] = new List <Update>(); } ClassificationsIndex[classificationId].Add(update); } } } }
/// <summary> /// Print updates from the store /// </summary> /// <param name="options">Print options, including filters</param> public void PrintUpdates(QueryMetadataOptions options) { var filter = FilterBuilder.MetadataFilterFromCommandLine(options as IMetadataFilterOptions); if (filter == null) { return; } filter.FirstX = options.FirstX; // Apply filters specified on the command line List <Update> filteredUpdates; if (options.Classifications || options.Products || options.Detectoids) { filteredUpdates = MetadataSource.GetCategories(filter); if (!options.Classifications) { filteredUpdates.RemoveAll(u => u is Classification); } if (!options.Products) { filteredUpdates.RemoveAll(u => u is Product); } if (!options.Detectoids) { filteredUpdates.RemoveAll(u => u is Detectoid); } } else if (options.Updates || options.Drivers) { filteredUpdates = MetadataSource.GetUpdates(filter); if (options.Drivers) { filteredUpdates.RemoveAll(u => !(u is DriverUpdate)); } } else { filteredUpdates = new List <Update>(); } if (filteredUpdates.Count == 0) { Console.WriteLine("No data found"); } else { Console.Write("\r\nQuery results:\r\n-----------------------------"); if (!options.CountOnly) { foreach (var update in filteredUpdates) { PrintUpdateMetadata(update, MetadataSource); } } Console.WriteLine("-----------------------------\r\nMatched {0} entries", filteredUpdates.Count); } }