protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { if (this.IsBusy) { throw new InvalidOperationException("Scan in progress"); } /* * if (m_db != null) * m_db.Close(); // TODO ? leavOpen in Scanworker.ctor after database parameter? PASS THIS leavOpen PARAMETER AT THE BufferedItemWriter INSTANCIATION AS WELL!!! * m_media.Dispose(); // TODO ? (in case m_media implements IDisposable because of the MediaDB reference anytime later) */ } drive = null; database = null; volume = null; volumeInfo = null; options = null; asyncOperation = null; disposed = true; } }
public static Gdk.Pixbuf GetThumb(VolumeItem item, VolumeDatabase db, int size) { string dbDataPath = PathUtil.GetDbDataPath(db); string volumeDataPath = DbData.GetVolumeDataPath(dbDataPath, item.VolumeID); string thumbsPath = DbData.GetVolumeDataThumbsPath(volumeDataPath); string thumbName = System.IO.Path.Combine( thumbsPath, string.Format("{0}.png", item.ItemID)); if (File.Exists(thumbName)) { if (size > 0) { return(new Gdk.Pixbuf(thumbName, size, size, false)); } else { return(new Gdk.Pixbuf(thumbName)); } } else { return(null); } }
internal AbstractImport(string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, int bufferSize) { if (sourceDbPath == null) { throw new ArgumentNullException("sourceDbPath"); } if (targetDb == null) { throw new ArgumentNullException("targetDb"); } if (dbDataPath == null) { throw new ArgumentNullException("dbDataPath"); } this.volumeDataPaths = new List <string>(); this.sourceDbPath = sourceDbPath; this.targetDb = targetDb; this.dbDataPath = dbDataPath; this.bufferSize = bufferSize; this.isRunning = false; this.importSucceeded = false; this.cancellationRequested = false; }
public CdCatImport(string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, int bufferSize) : base(sourceDbPath, targetDb, dbDataPath, bufferSize) { }
public static IImport GetImportByExtension(string extension, string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, int bufferSize) { if (extension == null) { throw new ArgumentNullException("extension"); } foreach (var t in GetImportTypes()) { var attrs = t.GetCustomAttributes(false); foreach (var a in attrs) { var ia = a as ImportAttribute; if ((ia != null) && (ia.Extension.ToUpper() == extension.ToUpper())) { return((IImport)Activator.CreateInstance(t, new object[] { sourceDbPath, targetDb, dbDataPath, bufferSize })); } } } return(null); }
internal override void ImportThreadMain(string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, BufferedVolumeItemWriter writer) { this.counters = new long[3]; //idCounter = 2; // id 1 is the root item //totalMedia = 0; this.path = new Stack <string>(); this.mimePathPrefix = GetNonExistingPath() + "/"; this.targetDb = targetDb; this.writer = writer; using (GZipStream s = new GZipStream(File.OpenRead(sourceDbPath), CompressionMode.Decompress)) { XmlReaderSettings settings = new XmlReaderSettings() { DtdProcessing = DtdProcessing.Ignore, ValidationType = ValidationType.None, CheckCharacters = false }; XmlReader reader = XmlTextReader.Create(s, settings); XmlDocument xml = new XmlDocument(); xml.Load(reader); string dummy1 = null; MetadataStore dummy2 = MetadataStore.Empty; RecursiveDump(xml.DocumentElement, 0L, 0L, ref dummy1, ref dummy1, ref dummy2); } }
public GnomeCatalogImport(string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, int bufferSize) : base(sourceDbPath, targetDb, dbDataPath, bufferSize) { }
internal FileSystemVolume(VolumeDatabase database) : base(database, VolumeType.FileSystemVolume) { this.files = 0L; this.dirs = 0L; this.size = 0L; }
private static void ImportFile(IDataReader reader, long volumeID, long minFileID, string rootPath, MetadataStore metaData, VolumeDatabase db, BufferedVolumeItemWriter writer, long[] counters) { FileSystemVolumeItem item; if ((string)reader["type"] == "directory") { item = new DirectoryVolumeItem(db); counters[TOTAL_DIRS]++; } else { item = new FileVolumeItem(db); long size = (long)reader["size"]; ((FileVolumeItem)item).SetFileVolumeItemFields(size, null); counters[TOTAL_FILES]++; counters[TOTAL_SIZE] += size; } string path = (string)reader["path"]; Debug.Assert(path.StartsWith("file://"), "path starts with 'file://'"); string name = (string)reader["name"]; string location = DecoderUtility.UrlDecode(path); location = location.Substring(rootPath.Length); location = location.Substring(0, location.Length - name.Length - 1); if (location.Length == 0) { location = "/"; } long itemID = 2 + (long)reader["id"] - minFileID; // id 1 is the root item long parentID = Math.Max(1, 2 + (long)reader["idparent"] - minFileID); item.SetFileSystemVolumeItemFields(location, DateTime.MinValue, VolumeDatabase.ID_NONE); item.SetVolumeItemFields(volumeID, itemID, parentID, name, Util.ReplaceDBNull <string>(reader["mime"], null), metaData, Util.ReplaceDBNull <string>(reader["comment"], null), null); writer.Write(item); }
public Import(VolumeDatabase db) { this.database = db; this.import = null; BuildGui(); btnImport.Sensitive = false; // will be enabled on file selection }
internal FileVolumeItem(VolumeDatabase database) : base(database, VolumeItemType.FileVolumeItem) { //filename = null; //extension = null; size = 0L; hash = null; }
public void Fill(VolumeItem[] items, VolumeDatabase db, bool clearVolumeCache) { if (clearVolumeCache) { volumeCache.Clear(); } Fill(items, db); }
internal FileSystemVolumeItem(VolumeDatabase database, VolumeItemType volumeItemType) : base(database, volumeItemType) { this.location = null; //this.createdDate = DateTime.MinValue; this.lastWriteTime = DateTime.MinValue; this.symLinkTargetID = VolumeDatabase.ID_NONE; }
// note: // do not allow to modify the constuctor parameters // (i.e. database, options) // through public properties later, since the scanner // may already use them after scanning has been started, // and some stuff has been initialized depending on the // options in the ctor already. public AudioCdVolumeScanner(Platform.Common.IO.DriveInfo drive, VolumeDatabase database, AudioCdScannerOptions options) : base(drive, database, options) { if (!drive.HasAudioCdVolume) { throw new ArgumentException("No audio cd present in drive"); } }
public DBProperties(VolumeDatabase db) { BuildGui(); this.db = db; props = db.GetDBProperties(); entName.Text = props.Name; tvDescription.Buffer.Text = props.Description; entCreated.Text = props.Created.ToString(); }
internal DatabaseProperties(VolumeDatabase database) : base(tableName, primarykeyFields) { this.name = null; this.description = null; this.created = DateTime.MinValue; this.version = 0; this.guid = null; this.database = database; }
public static string GetDbDataPath(VolumeDatabase db) { string settingsPath = App.Settings.GetSettingsDirectory().FullName; string guid = db.GetDBProperties().Guid; string dataPath = Path.Combine(Path.Combine(settingsPath, "dbdata"), guid); if (!Directory.Exists(dataPath)) Directory.CreateDirectory(dataPath); return dataPath; }
public ItemSearch(MainWindow mainWindow, VolumeDatabase db) { windowDeleted = false; this.mainWindow = mainWindow; this.database = db; BuildGui(); btnSearch.Sensitive = false; txtSearchString.GrabFocus(); // the widget should be visible the first time // when the user clicks on an item itemInfo.Hide(); }
public static string GetDbDataPath(VolumeDatabase db) { string settingsPath = App.Settings.GetSettingsDirectory().FullName; string guid = db.GetDBProperties().Guid; string dataPath = Path.Combine(Path.Combine(settingsPath, "dbdata"), guid); if (!Directory.Exists(dataPath)) { Directory.CreateDirectory(dataPath); } return(dataPath); }
public ItemView() { itemIcons = new ItemIcons(this); loadingIcon = this.RenderIcon(Icons.Icon.Stock_Find, ICON_SIZE); HeadersClickable = true; database = null; currentVolumeType = (VolumeType)(-1); item_col = -1; // event handlers RowExpanded += OnRowExpanded; ButtonPressEvent += OnButtonPressEvent; }
public BufferedVolumeItemWriter(VolumeDatabase database, bool leaveOpen, int size) { if (database == null) throw new ArgumentNullException("database"); if (size < 1) throw new ArgumentOutOfRangeException("size"); this.database = database; this.leaveOpen = leaveOpen; this.buffer = new VolumeItem[size]; this.disposed = false; Reset(); }
private Gdk.Pixbuf GetImage(VolumeItem item, VolumeDatabase db) { Gdk.Pixbuf img = null; if (App.Settings.ShowThumbsInItemLists) { int sz = IconUtils.GetIconSizeVal(ICON_SIZE); img = PathUtil.GetThumb(item, db, sz); } if (img == null) { img = itemIcons.GetIconForItem(item, ICON_SIZE); } return(img); }
// <summary> /// Probes a volume, creates the appropriate VolumeScanner and returns a general interface to it. /// </summary> /// <param name="drive">Drive to be scanned</param> /// <param name="database">VolumeDatabase object</param> /// <param name="options">ScannerOptions for all possible scanners</param> /// <returns>Interface to the proper VolumeScanner</returns> public static IVolumeScanner GetScannerForVolume(PlatformIO.DriveInfo drive, VolumeDatabase database, ScannerOptions[] options) { if (drive == null) { throw new ArgumentNullException("drive"); } if (!drive.IsReady) { throw new ArgumentException("Drive is not ready", "drive"); } if (options == null) { throw new ArgumentNullException("options"); } IVolumeScanner scanner = null; VolumeProbeResult result = ProbeVolume(drive); switch (result) { case VolumeProbeResult.Filesystem: scanner = new FilesystemVolumeScanner(drive, database, GetOptions <FilesystemScannerOptions>(options)); break; case VolumeProbeResult.AudioCd: scanner = new AudioCdVolumeScanner(drive, database, GetOptions <AudioCdScannerOptions>(options)); break; case VolumeProbeResult.Unknown: throw new ArgumentException("Volume is of an unknown type"); default: throw new NotImplementedException(string.Format("VolumeProbeResult {0} is not implemented", result.ToString())); } return(scanner); }
public static Gdk.Pixbuf GetThumb(VolumeItem item, VolumeDatabase db, int size) { string dbDataPath = PathUtil.GetDbDataPath(db); string volumeDataPath = DbData.GetVolumeDataPath(dbDataPath, item.VolumeID); string thumbsPath = DbData.GetVolumeDataThumbsPath(volumeDataPath); string thumbName = System.IO.Path.Combine( thumbsPath, string.Format("{0}.png", item.ItemID)); if (File.Exists(thumbName)) { if (size > 0) return new Gdk.Pixbuf(thumbName, size, size, false); else return new Gdk.Pixbuf(thumbName); } else { return null; } }
// note: // do not allow to modify the constuctor parameters // (i.e. database, options) // through public properties later, since the scanner // may already use them after scanning has been started, // and some stuff has been initialized depending on the // options in the ctor already. internal AbstractVolumeScanner(PlatformIO.DriveInfo drive, VolumeDatabase database, TOpts options) { if (drive == null) { throw new ArgumentNullException("drive"); } if (!drive.IsReady) { throw new ArgumentException("Drive is not ready", "drive"); } if (options == null) { throw new ArgumentNullException("options"); } /* don't test database for null -- database is optional */ if ((options.BufferSize < 1) && (database != null)) { throw new ArgumentOutOfRangeException("BufferSize"); } this.isRunning = false; //m_cancellationRequested = false; this.scanSucceeded = false; this.disposed = false; this.drive = drive; this.database = database; // copy options reference so that they can't be modified // while the scanner is running already. this.options = new TOpts(); options.CopyTo(this.options); this.itemID = VolumeDatabase.ID_NONE; this.volume = CreateVolumeObject(drive, database, options.ComputeHashs); this.volumeInfo = CreateInstance <TVolumeInfo>(volume); }
internal VolumeItem(VolumeDatabase database, VolumeItemType itemType) : base(tableName, primarykeyFields) { this.volumeID = 0L; this.itemID = 0L; //this.rootID = 0L; this.parentID = 0L; this.name = null; this.mimeType = null; this.metaData = MetadataStore.Empty; this.note = null; this.keywords = null; //this.ownerVolume = null; this.database = database; this.itemType = itemType; }
internal void UpdateVolumeList(VolumeDatabase database) { lvVolumes.BeginUpdate(); try { lvVolumes.Clear(); foreach (DiscInDatabase disc in database.GetDiscs()) { ListViewItem lvi = new ListViewItem(); lvi.Text = disc.Name; lvi.ImageIndex = 0; lvi.Checked = true; lvi.Tag = disc; lvVolumes.Items.Add(lvi); } } finally { lvVolumes.EndUpdate(); } }
/// <summary> // Returns a specific Volume object, but preassigns properties of the Volume baseclass only. // Filling properties of the specific, derived object, is job of the specific VolumeScanner implementation. /// </summary> private static TVolume CreateVolumeObject(PlatformIO.DriveInfo d, VolumeDatabase database, bool isHashed) { // TODO : check here whether everything is still filled correctly after media class reorganisation long volumeID = VolumeDatabase.ID_NONE; if (database != null) { // TODO : this is neither threadsave nor multi-instance save in general! // maybe the db (physical db, VolumeDatabase object? this scanner?) should be locked during scanning? volumeID = database.GetNextVolumeID(); } TVolume v = CreateInstance <TVolume>(database); // /* v = new TVolume(database); */ // v = (TVolume)VolumeDB.Volume.CreateInstance(volumeType, database); // // initialize fields of the Volume base class. // don't initialize via properties. initializing via properties is error-prone // as the compiler won't error if a new field is added to the base class // and forgotten to be initialized here. v.SetVolumeFields( volumeID, d.IsMounted ? d.VolumeLabel : string.Empty, DateTime.Now, /*di.VolumeSerialNumber,*/ isHashed, volumeID.ToString(), d.DriveType.ToVolumeDriveType(), null, DateTime.MinValue, DateTime.MinValue, null, null, null ); return(v); }
public void Preview(VolumeItem item, VolumeDatabase db) { if (item == null) { throw new ArgumentNullException("item"); } if (db == null) { throw new ArgumentNullException("db"); } // free old pixbuf (but not a _cached_ icon!) if (!isIcon && (this.pb != null)) { this.pb.Dispose(); this.pb = null; } Pixbuf tmp = PathUtil.GetThumb(item, db, 0); if (tmp != null) { this.pb = tmp; this.isIcon = false; } else { if (EnableGenericIcons) { this.pb = itemIcons.GetIconForItem(item, ICON_SIZE); } else { this.pb = null; } this.isIcon = true; } QueueDraw(); }
internal Volume(VolumeDatabase database, VolumeType volumeType) : base(tableName, primarykeyFields) { this.volumeID = 0L; this.title = null; this.added = DateTime.MinValue; this.isHashed = false; this.archiveNo = null; this.driveType = VolumeDriveType.Unknown; this.loanedTo = null; this.loanedDate = DateTime.MinValue; this.returnDate = DateTime.MinValue; this.category = null; this.description = null; this.keywords = null; //this.clientAppData = null; this.database = database; this.volumeType = volumeType; }
// note: // do not allow to modify the constuctor parameters // (i.e. database, options) // through public properties later, since the scanner // may already use them after scanning has been started, // and some stuff has been initialized depending on the // options in the ctor already. public FilesystemVolumeScanner(Platform.Common.IO.DriveInfo drive, VolumeDatabase database, FilesystemScannerOptions options) : base(drive, database, options) { if (!drive.IsMounted) { throw new ArgumentException("Drive is not mounted", "drive"); } if (Options.GenerateThumbnails && string.IsNullOrEmpty(Options.DbDataPath)) { throw new ArgumentException("DbDataPath", "Thumbnail generation requires the DbDataPath option to be set"); } disposed = false; //this.mimeInfo = new MimeInfo(false); this.sbPathFixer = new StringBuilder(1024); this.paths = new Paths(Options.DbDataPath, null, null); this.symLinkHelper = new SymLinkHelper(this); this.thumbGen = new ThumbnailGenerator(); }
public void ShowInfo(VolumeItem item, VolumeDatabase db) { if (item == null) { throw new ArgumentNullException("item"); } if (db == null) { throw new ArgumentNullException("db"); } // update item preview itemPreview.Preview(item, db); if (!itemPreview.EnableGenericIcons && !Minimized) { if (itemPreview.IsThumbnailPreview) { itemPreview.Show(); } else { itemPreview.Hide(); } } // update item properties FillPropertyBox(item); // HACK : // somehow the cells of the outer hbox // don't match the gradient of this widget // if ShowInfo() is called a second time. outerBox.QueueDraw(); this.Show(); }
internal AbstractImport(string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, int bufferSize) { if (sourceDbPath == null) throw new ArgumentNullException("sourceDbPath"); if (targetDb == null) throw new ArgumentNullException("targetDb"); if (dbDataPath == null) throw new ArgumentNullException("dbDataPath"); this.volumeDataPaths = new List<string>(); this.sourceDbPath = sourceDbPath; this.targetDb = targetDb; this.dbDataPath = dbDataPath; this.bufferSize = bufferSize; this.isRunning = false; this.importSucceeded = false; this.cancellationRequested = false; }
public void Preview(VolumeItem item, VolumeDatabase db) { if (item == null) throw new ArgumentNullException("item"); if (db == null) throw new ArgumentNullException("db"); // free old pixbuf (but not a _cached_ icon!) if (!isIcon && (this.pb != null)) { this.pb.Dispose(); this.pb = null; } Pixbuf tmp = PathUtil.GetThumb(item, db, 0); if (tmp != null) { this.pb = tmp; this.isIcon = false; } else { if (EnableGenericIcons) this.pb = itemIcons.GetIconForItem(item, ICON_SIZE); else this.pb = null; this.isIcon = true; } QueueDraw(); }
public void Fill(VolumeItem[] items, VolumeDatabase db) { if (items == null) { throw new ArgumentNullException("items"); } if (db == null) { throw new ArgumentNullException("db"); } ListStore store = new Gtk.ListStore(typeof(Gdk.Pixbuf), typeof(string), typeof(VolumeItem)); /* VolumeItem - not visible */ foreach (VolumeItem item in items) { Volume vol; if (!volumeCache.TryGetValue(item.VolumeID, out vol)) { vol = item.GetOwnerVolume(); volumeCache.Add(vol.VolumeID, vol); } string description; string itemName = Util.Escape(item.Name); string volTitle = Util.Escape(vol.Title.Length > 0 ? vol.Title : STR_UNNAMED); string archiveNo = Util.Escape(vol.ArchiveNo.Length > 0 ? vol.ArchiveNo : "-"); switch (item.GetVolumeItemType()) { case VolumeItemType.FileVolumeItem: case VolumeItemType.DirectoryVolumeItem: description = string.Format("<b>{0}</b>\n<span size=\"smaller\"><i>{1}:</i> {2}\n<i>{3}:</i> {4}, <i>{5}:</i> {6}</span>", itemName, Util.Escape(STR_LOCATION), Util.Escape(((FileSystemVolumeItem)item).Location), Util.Escape(STR_VOLUME), volTitle, Util.Escape(STR_ARCHIVENO), archiveNo); break; case VolumeItemType.AudioTrackVolumeItem: description = string.Format("<b>{0}</b>\n<span size=\"smaller\"><i>{1}</i>\n<i>{2}:</i> {3}, <i>{4}:</i> {5}</span>", itemName, Util.Escape(STR_AUDIOTRACK), Util.Escape(STR_VOLUME), volTitle, Util.Escape(STR_ARCHIVENO), archiveNo); break; default: throw new NotImplementedException("Search result view has not been implemented for this volumetype"); } store.AppendValues(GetImage(item, db), description, item); } this.Model = store; ColumnsAutosize(); }
public void Fill(VolumeItem[] items, VolumeDatabase db, bool clearVolumeCache) { if (clearVolumeCache) volumeCache.Clear(); Fill(items, db); }
public void Fill(VolumeItem[] items, VolumeDatabase db) { if (items == null) throw new ArgumentNullException("items"); if (db == null) throw new ArgumentNullException("db"); ListStore store = new Gtk.ListStore( typeof(Gdk.Pixbuf), typeof(string), typeof(VolumeItem)); /* VolumeItem - not visible */ foreach (VolumeItem item in items) { Volume vol; if (!volumeCache.TryGetValue(item.VolumeID, out vol)) { vol = item.GetOwnerVolume(); volumeCache.Add(vol.VolumeID, vol); } string description; string itemName = Util.Escape(item.Name); string volTitle = Util.Escape(vol.Title.Length > 0 ? vol.Title : STR_UNNAMED); string archiveNo = Util.Escape(vol.ArchiveNo.Length > 0 ? vol.ArchiveNo : "-"); switch (item.GetVolumeItemType()) { case VolumeItemType.FileVolumeItem: case VolumeItemType.DirectoryVolumeItem: description = string.Format("<b>{0}</b>\n<span size=\"smaller\"><i>{1}:</i> {2}\n<i>{3}:</i> {4}, <i>{5}:</i> {6}</span>", itemName, Util.Escape(STR_LOCATION), Util.Escape(((FileSystemVolumeItem)item).Location), Util.Escape(STR_VOLUME), volTitle, Util.Escape(STR_ARCHIVENO), archiveNo); break; case VolumeItemType.AudioTrackVolumeItem: description = string.Format("<b>{0}</b>\n<span size=\"smaller\"><i>{1}</i>\n<i>{2}:</i> {3}, <i>{4}:</i> {5}</span>", itemName, Util.Escape(STR_AUDIOTRACK), Util.Escape(STR_VOLUME), volTitle, Util.Escape(STR_ARCHIVENO), archiveNo); break; default: throw new NotImplementedException("Search result view has not been implemented for this volumetype"); } store.AppendValues(GetImage(item, db), description, item); } this.Model = store; ColumnsAutosize(); }
internal static Volume CreateInstance(VolumeType type, VolumeDatabase database) { Volume volume = null; switch (type) { case VolumeType.FileSystemVolume: volume = new FileSystemVolume(database); break; case VolumeType.AudioCdVolume: volume = new AudioCdVolume(database); break; default: throw new NotImplementedException(string.Format("Instanciation of type {0} is not implemented", type.ToString())); } return volume; }
private Gdk.Pixbuf GetImage(VolumeItem item, VolumeDatabase db) { Gdk.Pixbuf img = null; if (App.Settings.ShowThumbsInItemLists) { int sz = IconUtils.GetIconSizeVal(ICON_SIZE); img = PathUtil.GetThumb(item, db, sz); } if (img == null) img = itemIcons.GetIconForItem(item, ICON_SIZE); return img; }
private static void ImportFile(IDataReader reader, long volumeID, long minFileID, string rootPath, MetadataStore metaData, VolumeDatabase db, BufferedVolumeItemWriter writer, long[] counters) { FileSystemVolumeItem item; if ((string)reader["type"] == "directory") { item = new DirectoryVolumeItem(db); counters[TOTAL_DIRS]++; } else { item = new FileVolumeItem(db); long size = (long)reader["size"]; ((FileVolumeItem)item).SetFileVolumeItemFields(size, null); counters[TOTAL_FILES]++; counters[TOTAL_SIZE] += size; } string path = (string)reader["path"]; Debug.Assert(path.StartsWith("file://"), "path starts with 'file://'"); string name = (string)reader["name"]; string location = DecoderUtility.UrlDecode(path); location = location.Substring(rootPath.Length); location = location.Substring(0, location.Length - name.Length - 1); if (location.Length == 0) location = "/"; long itemID = 2 + (long)reader["id"] - minFileID; // id 1 is the root item long parentID = Math.Max(1, 2 + (long)reader["idparent"] - minFileID); item.SetFileSystemVolumeItemFields(location, DateTime.MinValue, VolumeDatabase.ID_NONE); item.SetVolumeItemFields(volumeID, itemID, parentID, name, Util.ReplaceDBNull<string>(reader["mime"], null), metaData, Util.ReplaceDBNull<string>(reader["comment"], null), null); writer.Write(item); }
internal AudioCdRootVolumeItem(VolumeDatabase database) : base(database, VolumeItemType.AudioCdRootVolumeItem) { }
public VolumeScanner(VolumeDatabase db, DriveInfo drive) { this.scanCompleted = false; this.database = db; this.newVolume = null; infoIcon = RenderIcon(Icons.Icon.Stock_DialogInfo, ICON_SIZE); warningIcon = RenderIcon(Icons.Icon.Stock_DialogWarning, ICON_SIZE); errorIcon = RenderIcon(Icons.Icon.Stock_DialogError, ICON_SIZE); mdps = null; if (App.Settings.ScannerExtractMetaData && (VolumeProber.ProbeVolume(drive) == VolumeProber.VolumeProbeResult.Filesystem)) { mdps = new MetadataProvider[] { new TagLibMetadataProvider(), new ArchiveMetadataProvider() }; } // setup scanner options ScannerOptions[] opts = new ScannerOptions[2] { new FilesystemScannerOptions() { BufferSize = App.Settings.ScannerBufferSize, ComputeHashs = App.Settings.ScannerComputeHashs, DiscardSymLinks = App.Settings.ScannerDiscardSymLinks, GenerateThumbnails = App.Settings.ScannerGenerateThumbnails, MetadataProviders = mdps, DbDataPath = PathUtil.GetDbDataPath(database) }, new AudioCdScannerOptions() { EnableMusicBrainz = App.Settings.ScannerEnableMusicBrainz } }; scanner = VolumeProber.GetScannerForVolume(drive, database, opts); // scanner eventhandlers scanner.BeforeScanItem += scanner_BeforeScanItem; scanner.ScannerWarning += scanner_ScannerWarning; scanner.Error += scanner_Error; scanner.ScanCompleted += scanner_ScanCompleted; /* volumedatabase event handlers */ database.BeginWriteAccess += database_BeginWriteAccess; database.EndWriteAccess += database_EndWriteAccess; // must be called _after_ scanner instanciation // (requires scanner.VolumeInfo.GetVolumeType()) BuildGui(); InitTreeView(); scannerLog = new StringBuilder(); timer = new StatusUpdateTimer(this); try { /* NOTE: make sure the timer will be removed properly later, * or it keeps running, even if this window has been closed. */ timer.Install(); string tmp; // e.g. GIO network 'drives' do not have a devicefile if (string.IsNullOrEmpty(drive.Device)) tmp = S._("Scanning started."); else tmp = string.Format(S._("Scanning of drive '{0}' started."), drive.Device); UpdateLog(LogIcon.Info, tmp); switch (scanner.VolumeInfo.GetVolumeType()) { case VolumeType.FileSystemVolume: UpdateLog(LogIcon.Info, string.Format(S._("Options: generate thumbs: {0}, extract metadata: {1}, discard symlinks: {2}, hashing: {3}."), BoolToStr(App.Settings.ScannerGenerateThumbnails), BoolToStr(App.Settings.ScannerExtractMetaData), BoolToStr(App.Settings.ScannerDiscardSymLinks), BoolToStr(App.Settings.ScannerComputeHashs))); break; case VolumeType.AudioCdVolume: UpdateLog(LogIcon.Info, string.Format(S._("Options: MusicBrainz enabled: {0}"), BoolToStr(App.Settings.ScannerEnableMusicBrainz))); break; default: throw new NotImplementedException(string.Format("Missing options output for scannertyp {0}", scanner.GetType())); } if (scanner.VolumeInfo.GetVolumeType() == VolumeType.FileSystemVolume) { // copy already known volume data into the editor volEditor.ArchiveNo = scanner.VolumeInfo.ArchiveNo; volEditor.Title = scanner.VolumeInfo.Title; } else { // other volumetypes have no useful data yet (e.g. AudioCD data may be queried from musicbrainz.org), // so disable the editor and re-enable it and fill in the data when scanning has been completed. volEditor.Sensitive = false; } // start scanning on a new thread and return immediately scanner.RunAsync(); } catch { timer.Remove(); throw; } }
private static void ImportDisk(IDataReader reader, long volumeID, VolumeDatabase db, long[] counters) { FileSystemVolume v = new FileSystemVolume(db); // try to guess the drivetype VolumeDriveType driveType; string root = (string)reader["root"]; if (root.ToUpper().Contains("CDROM") || root.ToUpper().Contains("DVD")) driveType = VolumeDriveType.CDRom; else if (root.StartsWith("/media")) driveType = VolumeDriveType.Removable; else driveType = VolumeDriveType.Harddisk; v.SetVolumeFields(volumeID, Util.ReplaceDBNull<string>(reader["name"], null), DateTime.Now, false, null, driveType, Util.ReplaceDBNull<string>(reader["borrow"], null), DateTime.MinValue, DateTime.MinValue, null, Util.ReplaceDBNull<string>(reader["comment"], null), null); v.SetFileSystemVolumeFields(counters[TOTAL_FILES], counters[TOTAL_DIRS], counters[TOTAL_SIZE]); v.InsertIntoDB(); // insert root item DirectoryVolumeItem item = new DirectoryVolumeItem(db); item.SetFileSystemVolumeItemFields(null, DateTime.MinValue, VolumeDatabase.ID_NONE); item.SetVolumeItemFields(volumeID, 1L, 0L, "/", VolumeScanner.FilesystemVolumeScanner.MIME_TYPE_DIRECTORY, MetadataStore.Empty, null, null); item.InsertIntoDB(); }
// TODO : make this member internally protected in case this language feature has become real // see http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=33c53cf6-2709-4cc9-a408-6cafee4313ef //protected internal abstract void ImportThreadMain(string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, BufferedVolumeItemWriter writer);
private void OpenDB(string path, bool createNew, bool loadAsync, System.Action onsuccess) { EnableGui(false); // will be re-enabled after opening AND loading has been completed successfully SetWindowTitle(null); // clear views tvVolumes.Clear(); tvItems.Clear(); itemInfo.Clear(); itemInfo.Hide(); if (database != null) { database.Close(); } lastSuccessfulSearchCriteria = null; try { database = new VolumeDatabase(path, createNew); database.SearchItemResultsLimit = App.SEARCH_RESULTS_LIMIT; } catch (UnsupportedDbVersionException) { MsgDialog.ShowError(this, S._("Unsupported database version"), S._("This database version is not supported.")); return; } // load volumes Action <Volume[]> updateGui = (Volume[] volumes) => { tvVolumes.Fill(volumes); // select first volume /* * // this clearly harms startup time. * TreeIter iter; * if (tvVolumes.Model.GetIterFirst(out iter)) * tvVolumes.Selection.SelectIter(iter); */ EnableGui(true); SetWindowTitle(path); SetTempStatus(string.Format(S._("{0} volumes loaded."), volumes.Length)); recentManager.AddFull("file://" + path, recentData); App.Settings.MostRecentDBPath = path; App.Settings.Save(); if (onsuccess != null) { onsuccess(); // must be called on the gui thread } }; if (loadAsync) { // delegate that will be called // when asynchronous volume loading (searching) has been finished. AsyncCallback cb = (IAsyncResult ar) => { Volume[] volumes; try { volumes = database.EndSearchVolume(ar); } catch (Exception ex) { Application.Invoke(delegate { SetStatus(string.Format(S._("An error occured while loading the volume list: {0}"), ex.Message)); }); return; } Application.Invoke(delegate { updateGui(volumes); }); }; database.BeginSearchVolume(cb, null); // returns immediately } else { Volume[] volumes = database.SearchVolume(); updateGui(volumes); } }
private static void ImportDisk(IDataReader reader, long volumeID, VolumeDatabase db, long[] counters) { FileSystemVolume v = new FileSystemVolume(db); // try to guess the drivetype VolumeDriveType driveType; string root = (string)reader["root"]; if (root.ToUpper().Contains("CDROM") || root.ToUpper().Contains("DVD")) { driveType = VolumeDriveType.CDRom; } else if (root.StartsWith("/media")) { driveType = VolumeDriveType.Removable; } else { driveType = VolumeDriveType.Harddisk; } v.SetVolumeFields(volumeID, Util.ReplaceDBNull <string>(reader["name"], null), DateTime.Now, false, null, driveType, Util.ReplaceDBNull <string>(reader["borrow"], null), DateTime.MinValue, DateTime.MinValue, null, Util.ReplaceDBNull <string>(reader["comment"], null), null); v.SetFileSystemVolumeFields(counters[TOTAL_FILES], counters[TOTAL_DIRS], counters[TOTAL_SIZE]); v.InsertIntoDB(); // insert root item DirectoryVolumeItem item = new DirectoryVolumeItem(db); item.SetFileSystemVolumeItemFields(null, DateTime.MinValue, VolumeDatabase.ID_NONE); item.SetVolumeItemFields(volumeID, 1L, 0L, "/", VolumeScanner.FilesystemVolumeScanner.MIME_TYPE_DIRECTORY, MetadataStore.Empty, null, null); item.InsertIntoDB(); }
internal static VolumeItem CreateInstance(VolumeItemType type, VolumeDatabase database) { VolumeItem item = null; switch (type) { case VolumeItemType.DirectoryVolumeItem: item = new DirectoryVolumeItem(database); break; case VolumeItemType.FileVolumeItem: item = new FileVolumeItem(database); break; case VolumeItemType.AudioCdRootVolumeItem: item = new AudioCdRootVolumeItem(database); break; case VolumeItemType.AudioTrackVolumeItem: item = new AudioTrackVolumeItem(database); break; default: throw new NotImplementedException(string.Format("Instantiation of type {0} is not implemented", type.ToString())); } return item; }
private void ImportThread(string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, int buferSize) { Exception fatalError = null; bool cancelled = false; try { // must be the first call within the try block targetDb.TransactionBegin(); // locks VolumeDatabase if (!File.Exists(sourceDbPath)) throw new FileNotFoundException("Source database not found"); // note: // don't use the writer in a using() block here as dispose() would write // buffered items after an exception has been thrown. BufferedVolumeItemWriter writer = new BufferedVolumeItemWriter(targetDb, true, bufferSize); ImportThreadMain(sourceDbPath, targetDb, dbDataPath, writer); writer.Close(); targetDb.TransactionCommit(); // unlocks VolumeDatabase importSucceeded = true; } catch (Exception ex) { Exception cleanupException = null; try { targetDb.TransactionRollback(); // unlocks VolumeDatabase foreach (string path in volumeDataPaths) Directory.Delete(path, true); } catch (Exception e) { cleanupException = e; } if (ex is ImportCancelledException) { cancelled = true; } else { /* save the error that caused the import to stop (import failure) */ fatalError = ex; PostError(ex); Debug.WriteLine("Details for exception in ImportThread():\n" + ex.ToString()); } // in case an error occured while cleaning up, // post the error here, _after_ the initial error that made the import fail. if (cleanupException != null) { PostError(cleanupException); } //#if THROW_EXCEPTIONS_ON_ALL_THREADS // if (!(ex is ScanCancelledException)) // throw; //#endif } finally { isRunning = false; PostCompleted(fatalError, cancelled); } }
internal DirectoryVolumeItem(VolumeDatabase database) : base(database, VolumeItemType.DirectoryVolumeItem) { }
internal override void ImportThreadMain(string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, BufferedVolumeItemWriter writer) { string thumbsPath = sourceDbPath + "_thumbs"; string sqlDisks = "SELECT * FROM disks ORDER BY id"; string sqlFiles = "SELECT * FROM files WHERE iddisk = {0} ORDER BY iddisk, id"; using (IDbConnection conn = SqliteDB.Open(sourceDbPath, false)) { long totalFiles = CountFiles(conn); long fileCounter = 0; using (IDbCommand cmdDisks = conn.CreateCommand()) { using (IDbCommand cmdFiles = conn.CreateCommand()) { cmdDisks.CommandText = sqlDisks; using (IDataReader readerDisks = cmdDisks.ExecuteReader()) { while (readerDisks.Read()) { long diskID = (long)readerDisks["id"]; long minFileID = GetMinFileID(conn, diskID); string rootPath = "file://" + (string)readerDisks["root"]; long volumeID = targetDb.GetNextVolumeID(); long[] counters = { 0L, 0L, 0L }; string volDBThumbsPath = CreateThumbsDir(dbDataPath, volumeID); cmdFiles.CommandText = string.Format(sqlFiles, diskID); using (IDataReader readerFiles = cmdFiles.ExecuteReader()) { while (readerFiles.Read()) { long fileID = (long)readerFiles["id"]; ImportFile(readerFiles, volumeID, minFileID, rootPath, ConvertMetaData(conn, fileID), targetDb, writer, counters); ImportThumb(fileID, (2 + fileID - minFileID), thumbsPath, volDBThumbsPath); PostProgressUpdate((++fileCounter * 100.0) / totalFiles); CheckForCancellationRequest(); } } ImportDisk(readerDisks, volumeID, targetDb, counters); } } } } } }
abstract void ImportThreadMain(string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, BufferedVolumeItemWriter writer);
public void FillRoot(Volume volume, VolumeDatabase db) { if (volume == null) { throw new ArgumentNullException("volume"); } if (db == null) { throw new ArgumentNullException("db"); } this.database = db; TreeModel model; VolumeType volType = volume.GetVolumeType(); ResetView(); switch (volType) { case VolumeType.FileSystemVolume: InitView(volType, out model); // load volume root FileSystemVolume fsv = (FileSystemVolume)volume; DirectoryVolumeItem item = fsv.GetRoot(); AppendDirRows((TreeStore)model, TreeIter.Zero, item); Model = model; /*ColumnsAutosize();*/ break; case VolumeType.AudioCdVolume: InitView(volType, out model); // load volume root AudioCdVolume avol = (AudioCdVolume)volume; AudioCdRootVolumeItem root = avol.GetRoot(); AudioTrackVolumeItem[] tracks = root.GetTracks(); ListStore store = (ListStore)model; if (tracks.Length == 0) { store.AppendValues(null, STR_EMPTY, STR_EMPTY, STR_EMPTY); } else { foreach (AudioTrackVolumeItem track in tracks) { store.AppendValues(GetImage(track), track.Name, (track.Artist.Length == 0 ? S._("Unknown") : track.Artist), string.Format("{0:D2}:{1:D2}", track.Duration.Minutes, track.Duration.Seconds), track); } } Model = model; /*ColumnsAutosize();*/ break; default: throw new NotImplementedException("Items view has not been implemented for this volumetype"); } }
public VolumeScanner(VolumeDatabase db, DriveInfo drive) { this.scanCompleted = false; this.database = db; this.newVolume = null; infoIcon = RenderIcon(Icons.Icon.Stock_DialogInfo, ICON_SIZE); warningIcon = RenderIcon(Icons.Icon.Stock_DialogWarning, ICON_SIZE); errorIcon = RenderIcon(Icons.Icon.Stock_DialogError, ICON_SIZE); mdps = null; if (App.Settings.ScannerExtractMetaData && (VolumeProber.ProbeVolume(drive) == VolumeProber.VolumeProbeResult.Filesystem)) { mdps = new MetadataProvider[] { new TagLibMetadataProvider(), new ArchiveMetadataProvider() }; } // setup scanner options ScannerOptions[] opts = new ScannerOptions[2] { new FilesystemScannerOptions() { BufferSize = App.Settings.ScannerBufferSize, ComputeHashs = App.Settings.ScannerComputeHashs, DiscardSymLinks = App.Settings.ScannerDiscardSymLinks, GenerateThumbnails = App.Settings.ScannerGenerateThumbnails, MetadataProviders = mdps, DbDataPath = PathUtil.GetDbDataPath(database) }, new AudioCdScannerOptions() { EnableMusicBrainz = App.Settings.ScannerEnableMusicBrainz } }; scanner = VolumeProber.GetScannerForVolume(drive, database, opts); // scanner eventhandlers scanner.BeforeScanItem += scanner_BeforeScanItem; scanner.ScannerWarning += scanner_ScannerWarning; scanner.Error += scanner_Error; scanner.ScanCompleted += scanner_ScanCompleted; /* volumedatabase event handlers */ database.BeginWriteAccess += database_BeginWriteAccess; database.EndWriteAccess += database_EndWriteAccess; // must be called _after_ scanner instanciation // (requires scanner.VolumeInfo.GetVolumeType()) BuildGui(); InitTreeView(); scannerLog = new StringBuilder(); timer = new StatusUpdateTimer(this); try { /* NOTE: make sure the timer will be removed properly later, * or it keeps running, even if this window has been closed. */ timer.Install(); string tmp; // e.g. GIO network 'drives' do not have a devicefile if (string.IsNullOrEmpty(drive.Device)) { tmp = S._("Scanning started."); } else { tmp = string.Format(S._("Scanning of drive '{0}' started."), drive.Device); } UpdateLog(LogIcon.Info, tmp); switch (scanner.VolumeInfo.GetVolumeType()) { case VolumeType.FileSystemVolume: UpdateLog(LogIcon.Info, string.Format(S._("Options: generate thumbs: {0}, extract metadata: {1}, discard symlinks: {2}, hashing: {3}."), BoolToStr(App.Settings.ScannerGenerateThumbnails), BoolToStr(App.Settings.ScannerExtractMetaData), BoolToStr(App.Settings.ScannerDiscardSymLinks), BoolToStr(App.Settings.ScannerComputeHashs))); break; case VolumeType.AudioCdVolume: UpdateLog(LogIcon.Info, string.Format(S._("Options: MusicBrainz enabled: {0}"), BoolToStr(App.Settings.ScannerEnableMusicBrainz))); break; default: throw new NotImplementedException(string.Format("Missing options output for scannertyp {0}", scanner.GetType())); } if (scanner.VolumeInfo.GetVolumeType() == VolumeType.FileSystemVolume) { // copy already known volume data into the editor volEditor.ArchiveNo = scanner.VolumeInfo.ArchiveNo; volEditor.Title = scanner.VolumeInfo.Title; } else { // other volumetypes have no useful data yet (e.g. AudioCD data may be queried from musicbrainz.org), // so disable the editor and re-enable it and fill in the data when scanning has been completed. volEditor.Sensitive = false; } // start scanning on a new thread and return immediately scanner.RunAsync(); } catch { timer.Remove(); throw; } }
private void ImportThread(string sourceDbPath, VolumeDatabase targetDb, string dbDataPath, int buferSize) { Exception fatalError = null; bool cancelled = false; try { // must be the first call within the try block targetDb.TransactionBegin(); // locks VolumeDatabase if (!File.Exists(sourceDbPath)) { throw new FileNotFoundException("Source database not found"); } // note: // don't use the writer in a using() block here as dispose() would write // buffered items after an exception has been thrown. BufferedVolumeItemWriter writer = new BufferedVolumeItemWriter(targetDb, true, bufferSize); ImportThreadMain(sourceDbPath, targetDb, dbDataPath, writer); writer.Close(); targetDb.TransactionCommit(); // unlocks VolumeDatabase importSucceeded = true; } catch (Exception ex) { Exception cleanupException = null; try { targetDb.TransactionRollback(); // unlocks VolumeDatabase foreach (string path in volumeDataPaths) { Directory.Delete(path, true); } } catch (Exception e) { cleanupException = e; } if (ex is ImportCancelledException) { cancelled = true; } else { /* save the error that caused the import to stop (import failure) */ fatalError = ex; PostError(ex); Debug.WriteLine("Details for exception in ImportThread():\n" + ex.ToString()); } // in case an error occured while cleaning up, // post the error here, _after_ the initial error that made the import fail. if (cleanupException != null) { PostError(cleanupException); } //#if THROW_EXCEPTIONS_ON_ALL_THREADS // if (!(ex is ScanCancelledException)) // throw; //#endif } finally { isRunning = false; PostCompleted(fatalError, cancelled); } }
public void FillRoot(Volume volume, VolumeDatabase db) { if (volume == null) throw new ArgumentNullException("volume"); if (db == null) throw new ArgumentNullException("db"); this.database = db; TreeModel model; VolumeType volType = volume.GetVolumeType(); ResetView(); switch (volType) { case VolumeType.FileSystemVolume: InitView(volType, out model); // load volume root FileSystemVolume fsv = (FileSystemVolume)volume; DirectoryVolumeItem item = fsv.GetRoot(); AppendDirRows((TreeStore)model, TreeIter.Zero, item); Model = model; /*ColumnsAutosize();*/ break; case VolumeType.AudioCdVolume: InitView(volType, out model); // load volume root AudioCdVolume avol = (AudioCdVolume)volume; AudioCdRootVolumeItem root = avol.GetRoot(); AudioTrackVolumeItem[] tracks = root.GetTracks(); ListStore store = (ListStore)model; if (tracks.Length == 0) { store.AppendValues(null, STR_EMPTY, STR_EMPTY, STR_EMPTY); } else { foreach (AudioTrackVolumeItem track in tracks) { store.AppendValues(GetImage(track), track.Name, (track.Artist.Length == 0 ? S._("Unknown") : track.Artist), string.Format("{0:D2}:{1:D2}", track.Duration.Minutes, track.Duration.Seconds), track); } } Model = model; /*ColumnsAutosize();*/ break; default: throw new NotImplementedException("Items view has not been implemented for this volumetype"); } }