GunFinder

GunFinder ist eine datenbankgestützte Suchmaschine. Ich nutze sie um meine Backups zu durchsuchen. Ein Daemon überwacht  die eingetragenen Ordner auf Veränderung und aktualisiert die Datenbank bei Änderungen. Archive werden entpackt und durchsucht. In den Index werden nur die Dateien aufgenommen, die ich als relevant gekennzeichnet habe. Das geht mit einem glob-Pattern und wird dem Daemon als Argument übergeben. Bei pdfs und OpenOffice-Dokumenten wird der enthaltene Text extrahiert, nach Keywords analysiert und der bereinigte Text ebenfalls in der Datenbank abgespeichert. Der Vorteil gegenüber OS-Suchfunktionen liegt in der Geschwindigkeit: zwar dauert das Indizieren relativ lange, die Suche in der Datenbank aber nur wenige Sekunden. Für jeden Eintrag der Liste stehen drei Optionen zur Verfügung: öffnen mit dem Standardprogramm, den Pfad im Dateimanager öffnen und Datei kopieren.

Suche nach suche

Sourcecode:

private static GunFinderDB gfdb = new GunFinderDB();
private static GunFinderUtilities gfu = new GunFinderUtilities();
private static int pathId;

public static class Finder
extends SimpleFileVisitor<Path> {

	private final PathMatcher matcher;
	private final PathMatcher pdf_matcher;
	private final PathMatcher zip_matcher;
	private final PathMatcher exclude_matcher;
	private final PathMatcher folder_matcher;
	private final PathMatcher odf_matcher;
	private final PathMatcher jpg_matcher;
	private int numMatches = 0;

	Finder(String pattern) {
		matcher = FileSystems.getDefault()
				.getPathMatcher("glob:" + pattern);
		pdf_matcher = FileSystems.getDefault()
				.getPathMatcher("glob:*.pdf");
		zip_matcher = FileSystems.getDefault()
				.getPathMatcher("glob:{*.zip,*.rar,*.7z}");
		exclude_matcher = FileSystems.getDefault()
				.getPathMatcher("glob:.DS_Store");
		folder_matcher = FileSystems.getDefault()
				.getPathMatcher("glob:{**\\__MACOSX\\**,**/__MACOSX/**}");
		odf_matcher = FileSystems.getDefault()
				.getPathMatcher("glob:{*.odt,*.odf,*.ods,*.docx,*.pptx}");
		jpg_matcher = FileSystems.getDefault()
				.getPathMatcher("glob:{*.jpg,*.jpeg}");

	}

	// Compares the glob pattern against
	// the file or directory name.
	void find(Path file) {
		Path name = file.getFileName();
		if (name != null && (matcher.matches(name) || file.toFile().isDirectory()) ) {
			if (!exclude_matcher.matches(name) && !folder_matcher.matches(file)) {
				numMatches++;
				Timestamp ts = gfdb.selectFileMod(file);
				if (ts == null || Math.abs(ts.getTime() - new Timestamp(file.toFile().lastModified()).getTime()) > 1000) { //check if file is modified
					String content = null;
					if (matcher.matches(name) && pdf_matcher.matches(name)) { //pdf
						content = gfu.sortKeywords(gfu.parsePdf(file.toFile()));		
						if (content != null) {
							gfdb.insertFileInfo(file, content, pathId);
						}
					}
					else if (matcher.matches(name) && odf_matcher.matches(name)) { //OpenOffice
						try {
							content = gfu.sortKeywords(new GunOfficeParser().getText(file.toString()));
						} catch (Exception e) {
							e.printStackTrace();
						} finally {
							if (content != null) gfdb.insertFileInfo(file, content, pathId);
						}
					}
					else if (matcher.matches(name) && (zip_matcher.matches(name) && gfu.isZipFile(file.toFile()))) { //zip
						content = gfu.sortKeywords(gfu.getZipFileContents(file.toFile(), matcher));		
						if (content != null) {
							gfdb.insertFileInfo(file, content, pathId);
						}
					}
					else if (matcher.matches(name) && jpg_matcher.matches(name) ) { //image
						try {
							if (Files.size(file) / 1024 > 100) content = "";
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}		
						if (content != null) {
							gfdb.insertFileInfo(file, content, pathId);
						}
					}
					else if (matcher.matches(name) && !Files.isDirectory(file)) { //other files
						content = "";		
						gfdb.insertFileInfo(file, content, pathId);
					}
				}
			}
		}
	}
	// Prints the total number of
	// matches to standard out.
	void done() {
		System.out.println("Matched: "
				+ numMatches);
	}
	// Invoke the pattern matching
	// method on each file.
	@Override
	public FileVisitResult visitFile(Path file,
			BasicFileAttributes attrs) {
		find(file);
		return CONTINUE;
	}
	// Invoke the pattern matching
	// method on each directory.
	@Override
	public FileVisitResult preVisitDirectory(Path dir,
			BasicFileAttributes attrs) {
		find(dir);
		return CONTINUE;
	}
	@Override
	public FileVisitResult visitFileFailed(Path file,
			IOException exc) {
		System.err.println(exc);
		return CONTINUE;
	}
}

Interesse:

Leider ist die Datenbankverbindung fest codiert, so dass GunFinder z.Z. nur auf meinem Rechner läuft.
Frag mich nach einer maßgeschneiderten Version.