static ArrayList RemapUris(LuceneQueryingDriver driver, ArrayList uris) { // We only need to remap URIs in the file system backend if (driver.IndexName != "FileSystemIndex") { return(uris); } FileAttributesStore fa_store = new FileAttributesStore(new FileAttributesStore_Mixed(Path.Combine(PathFinder.IndexDir, "FileSystemIndex"), driver.Fingerprint)); for (int i = 0; i < uris.Count; i++) { Uri uri = (Uri)uris [i]; string path = uri.LocalPath; Beagrep.Daemon.FileAttributes attr = fa_store.Read(path); if (attr == null) { Console.WriteLine("No file attribute info for {0}", uri); continue; } Uri internal_uri = new Uri("uid:" + GuidFu.ToShortString(attr.UniqueId) + uri.Fragment); uris [i] = internal_uri; } return(uris); }
private Indexable GetNewXmpIndexable(ref Indexable indexable, string path, Guid id, DirectoryModel parent) { // In non-crawl mode, check if a corresponding xmp file is present and not already scheduled and index it. // If file.xmp and file are rapidly written/updated (in that order), this does the right thing. // If file and file.xmp are rapidly written/updated (in that order), either // - file.xmp is present during FileToIndexable(file): in which case xmp properties are // added to file; and when file.xmp is indexed, it will replace the xmp properties // - file.xmp is not present during FileToIndexable(file): when the xmp file is later indexed // it will add the xmp properties // since the uid file will still be in the uid-cache, correct uid will be used for xmp prop-change indexable string possible_xmp_file_path = string.Concat(path, ".xmp"); if (!File.Exists(possible_xmp_file_path)) { return(null); } Guid xmp_id = queryable.RegisterFile(parent, (Path.GetFileName(possible_xmp_file_path))); if (xmp_id == Guid.Empty) { return(null); } XmpFile xmp_file = null; try { xmp_file = new XmpFile(possible_xmp_file_path); } catch { uid_manager.ForgetNewId(possible_xmp_file_path); return(null); } // FIXME: Should also delete previous xmp properties! foreach (Property p in xmp_file.Properties) { p.IsMutable = true; indexable.AddProperty(p); } xmp_file.Close(); // Also need to save some local states for PostAddHook, // namely, path to the xmp file, path to basefile and generated uid indexable.LocalState ["XmpFilePath"] = possible_xmp_file_path; indexable.LocalState ["BaseFilePath"] = path; indexable.LocalState ["XmpGuid"] = GuidFu.ToShortString(xmp_id); if (Debug) { Log.Debug("Adding properties from {0}({2}) to {1}({3})", possible_xmp_file_path, path, GuidFu.ToShortString(xmp_id), GuidFu.ToShortString(id)); } return(null); }
protected void InitFileAttributesStore(string name, string external_fingerprint) { string storage_path = Path.Combine(PathFinder.IndexDir, name); string fingerprint_file = Path.Combine(storage_path, "fingerprint"); string internal_fingerprint; if (!Directory.Exists(storage_path)) { Directory.CreateDirectory(storage_path); internal_fingerprint = GuidFu.ToShortString(Guid.NewGuid()); StreamWriter writer = new StreamWriter(fingerprint_file); writer.WriteLine(internal_fingerprint); writer.Close(); } else { StreamReader reader = new StreamReader(fingerprint_file); internal_fingerprint = reader.ReadLine(); reader.Close(); } string fingerprint; if (external_fingerprint != null) { fingerprint = internal_fingerprint + "-" + external_fingerprint; } else { fingerprint = internal_fingerprint; } IFileAttributesStore ifa_store; if (ExtendedAttribute.Supported) { ifa_store = new FileAttributesStore_ExtendedAttribute(fingerprint); } else { ifa_store = new FileAttributesStore_Sqlite(storage_path, fingerprint); } fa_store = new FileAttributesStore(ifa_store); }
public bool Write(FileAttributes attr) { if (Disable) { return(false); } try { if (ExtendedAttribute.OldExists(attr.Path, "Fingerprint")) { DropObsoleteAttributes(attr.Path); } string fingerprint = String.Format("{0:00} {1}", EA_VERSION, index_fingerprint); string uid = GuidFu.ToShortString(attr.UniqueId); string mtime = StringFu.DateTimeToString(attr.LastWriteTime); string filter = String.Empty; if (attr.HasFilterInfo) { filter = String.Format("{0:000} {1}", attr.FilterVersion, attr.FilterName); } attr.LastAttrTime = DateTime.UtcNow; string attrtime = StringFu.DateTimeToString(attr.LastAttrTime); string [] csv = { fingerprint, uid, mtime, attrtime, filter }; ExtendedAttribute.Set(attr.Path, String.Join(",", csv)); return(true); } catch (IOException e) { // An IOException here probably means that we don't have the right // permissions to set the EAs. We just fail silently and return false rather // than spewing a bunch of scary exceptions. //Logger.Log.Debug (e); return(false); } catch (Exception e) { //Logger.Log.Debug (e, "Caught exception writing EAs to {0}", attr.Path); // FIXME: Do something smarter with the exception. return(false); } }
// Remapping hack from DumpIndex static Uri RemapUri(LuceneQueryingDriver driver, Uri uri) { // We only need to remap URIs in the file system backend if (driver.IndexName != "FileSystemIndex") { return(uri); } FileAttributesStore fa_store = new FileAttributesStore(new FileAttributesStore_Mixed(Path.Combine(PathFinder.IndexDir, "FileSystemIndex"), driver.Fingerprint)); string path = uri.LocalPath; Beagle.Daemon.FileAttributes attr = fa_store.Read(path); if (attr == null) { Console.WriteLine("No file attribute info for {0}", uri); return(uri); } return(new Uri("uid:" + GuidFu.ToShortString(attr.UniqueId) + uri.Fragment)); }
public bool Write(FileAttributes fa) { SetPathFlag(fa.Path); int ret = 0; string filter_name; // We need to quote any 's that appear in the strings // (in particular, in the path) lock (connection) { // If a transaction has been requested, start it now. MaybeStartTransaction(); filter_name = fa.FilterName; if (filter_name == null) { filter_name = ""; } filter_name = filter_name.Replace("'", "''"); string[] param = new string [] { "@unique_id", "@directory", "@filename", "@last_mtime", "@last_attrtime", "@filter_name", "@filter_version" }; object[] vals = new object [] { GuidFu.ToShortString(fa.UniqueId), fa.Directory.Replace("'", "''"), fa.Filename.Replace("'", "''"), StringFu.DateTimeToString(fa.LastWriteTime), StringFu.DateTimeToString(fa.LastAttrTime), filter_name, fa.FilterVersion }; for (int i = 0; i < param.Length; i++) { InsertCommand.Parameters.AddWithValue(param[i], vals[i]); } ret = SqliteUtils.DoNonQuery(InsertCommand); } return(ret != 0); }
public Indexable GetXmpQueryable(string path, Guid id, DirectoryModel parent) { Log.Debug("Asked to create xmp indexable for ({0}) {1}", GuidFu.ToShortString(id), path); // Should be at least 6 characters /<...>.xmp if (path.Length < 6) { return(null); } string basefile_path = Path.ChangeExtension(path, null); // Ignore xmp files by itself // FIXME: To support indexing independent xmp files will require even greater trouble if (!File.Exists(basefile_path)) { return(null); } XmpFile xmp_file = null; try { xmp_file = new XmpFile(path); } catch { Log.Warn("Cannot create xmpfile from {0}", path); return(null); } // Try to get the correct uid for the basefile // First we need to see if basefile is already scheduled (yet to be dispatched) Uri basefile_uri = null; Indexable base_indexable; if (uid_manager.HasNewId(basefile_path)) { // Since uid_manager has a new id for this basefile, so basefile is already scheduled // Get basefile uid from there Guid basefile_id = uid_manager.GetNewId(basefile_path); basefile_uri = GuidFu.ToUri(basefile_id); Log.Debug("{0} is already scheduled with uri {1}", basefile_path, basefile_uri); } else { // Basefile is not scheduled in the current batch string basefile_name = Path.GetFileName(basefile_path); // Try to schedule it for addition base_indexable = queryable.GetCrawlingFileIndexable(parent, basefile_name); if (base_indexable == null) { // GetCrawlingFileIndexable returns null if file does not need to be indexed // So basefile is up-to-date // Need to figure out id from uid manager Guid basefile_id = uid_manager.GetIdByNameAndParentId(basefile_name, parent.UniqueId); basefile_uri = GuidFu.ToUri(basefile_id); Log.Debug("{0} is not scheduled and need not be, uri is {1}", basefile_path, basefile_uri); } else { Log.Debug("Need to index {0}", basefile_path); // basefile needs to be indexed // FIXME: Move the task business out of handler and into FSQ.cs Scheduler.Task task; task = queryable.NewAddTask(base_indexable); // FIXME: What is the correct priority ? // If should have similar priority to the one that this xmp-indexable will be a part of task.Priority = Scheduler.Priority.Immediate; queryable.ThisScheduler.Add(task); // Get the basefile uri from the indexable basefile_uri = base_indexable.Uri; } } Log.Debug("Adding xmp-indexable for {0} (basefile uri {1}) with uid {2}", path, basefile_uri, GuidFu.ToShortString(id)); Indexable indexable = new Indexable(IndexableType.PropertyChange, basefile_uri); // Set the timestamp of the indexable as the timestamp of the basefile // It could have also been skipped, the original Indexable.Add would anyway have it indexable.Timestamp = File.GetLastWriteTimeUtc(basefile_path); indexable.DisplayUri = UriFu.PathToFileUri(path); // If the file was somehow deleted before this point, bail out. if (!FileSystem.ExistsByDateTime(indexable.Timestamp)) { xmp_file.Close(); return(null); } // Save some local states for PostAddHook, namely, path to the xmp file, path to basefile and generated uid indexable.LocalState ["XmpFilePath"] = path; indexable.LocalState ["BaseFilePath"] = basefile_path; indexable.LocalState ["XmpGuid"] = GuidFu.ToShortString(id); // FIXME: Should also delete previous xmp properties! foreach (Property p in xmp_file.Properties) { p.IsMutable = true; indexable.AddProperty(p); } xmp_file.Close(); return(indexable); }