Beispiel #1
0
 /**
  * Lists all directories from root to directory of specified file, returns found directory.
  *
  * @param file
  * @param root
  * @return
  */
 private FileInfo findParentInternal(FileInfo file, FileInfo root) {
   if (root == null || file == null || root.isRecentDir()) return null;
   if (!root.isRootDir() && !file.getPathName().startsWith(root.getPathName())) return null;
   // to list all directories starting root dir
   if (root.isDirectory && !root.isSpecialDir()) listDirectory(root);
   for (int i = 0; i < root.dirCount(); i++) {
     FileInfo found = findParentInternal(file, root.getDir(i));
     if (found != null) return found;
   }
   for (int i = 0; i < root.fileCount(); i++) {
     if (root.getFile(i).getPathName().equals(file.getPathName())) return root;
     if (root.getFile(i).getPathName().startsWith(file.getPathName() + "@/")) return root;
   }
   return null;
 }
Beispiel #2
0
 /**
  * Adds dir and file children to directory FileInfo item.
  *
  * @param baseDir is directory to list files and dirs for
  * @return true if successful.
  */
 public boolean listDirectory(FileInfo baseDir) {
   Set<String> knownItems = null;
   if (baseDir.isListed) {
     knownItems = new HashSet<String>();
     for (int i = baseDir.itemCount() - 1; i >= 0; i--) {
       FileInfo item = baseDir.getItem(i);
       if (!item.exists()) {
         // remove item from list
         baseDir.removeChild(item);
       } else {
         knownItems.add(item.getBasePath());
       }
     }
   }
   try {
     File dir = new File(baseDir.pathname);
     File[] items = dir.listFiles();
     // process normal files
     if (items != null) {
       for (File f : items) {
         // check whether file is a link
         if (Engine.isLink(f.getAbsolutePath()) != null) {
           log.w("skipping " + f + " because it's a link");
           continue;
         }
         if (!f.isDirectory()) {
           // regular file
           if (f.getName().startsWith(".")) continue; // treat files beginning with '.' as hidden
           if (f.getName().equalsIgnoreCase("LOST.DIR")) continue; // system directory
           String pathName = f.getAbsolutePath();
           if (knownItems != null && knownItems.contains(pathName)) continue;
           if (engine.isRootsMountPoint(pathName)) {
             // skip mount root
             continue;
           }
           boolean isZip = pathName.toLowerCase().endsWith(".zip");
           FileInfo item = mFileList.get(pathName);
           boolean isNew = false;
           if (item == null) {
             item = new FileInfo(f);
             if (isZip) {
               item = scanZip(item);
               if (item == null) continue;
               if (item.isDirectory) {
                 // many supported files in ZIP
                 item.parent = baseDir;
                 baseDir.addDir(item);
                 for (int i = 0; i < item.fileCount(); i++) {
                   FileInfo file = item.getFile(i);
                   mFileList.put(file.getPathName(), file);
                 }
               } else {
                 item.parent = baseDir;
                 baseDir.addFile(item);
                 mFileList.put(pathName, item);
               }
               continue;
             }
             isNew = true;
           }
           if (item.format != null) {
             item.parent = baseDir;
             baseDir.addFile(item);
             if (isNew) mFileList.put(pathName, item);
           }
         }
       }
       // process directories
       for (File f : items) {
         if (f.isDirectory()) {
           if (f.getName().startsWith(".")) continue; // treat dirs beginning with '.' as hidden
           FileInfo item = new FileInfo(f);
           if (knownItems != null && knownItems.contains(item.getPathName())) continue;
           item.parent = baseDir;
           baseDir.addDir(item);
         }
       }
     }
     baseDir.isListed = true;
     return !baseDir.isEmpty();
   } catch (Exception e) {
     L.e("Exception while listing directory " + baseDir.pathname, e);
     baseDir.isListed = true;
     return false;
   }
 }
Beispiel #3
0
  /**
   * For all files in directory, retrieve metadata from DB or scan and save into DB. Call in GUI
   * thread only!
   *
   * @param baseDir is directory with files to lookup/scan; file items will be updated with info
   *     from file metadata or DB
   * @param readyCallback is Runable to call when operation is finished or stopped (will be called
   *     in GUI thread)
   * @param control allows to stop long operation
   */
  private void scanDirectoryFiles(
      final CRDBService.LocalBinder db,
      final FileInfo baseDir,
      final ScanControl control,
      final Engine.ProgressControl progress,
      final Runnable readyCallback) {
    // GUI thread
    BackgroundThread.ensureGUI();
    log.d("scanDirectoryFiles(" + baseDir.getPathName() + ") ");

    // store list of files to scan
    ArrayList<String> pathNames = new ArrayList<String>();
    for (int i = 0; i < baseDir.fileCount(); i++) {
      pathNames.add(baseDir.getFile(i).getPathName());
    }

    if (pathNames.size() == 0) {
      readyCallback.run();
      return;
    }

    // list all subdirectories
    for (int i = 0; i < baseDir.dirCount(); i++) {
      if (control.isStopped()) break;
      listDirectory(baseDir.getDir(i));
    }

    // load book infos for files
    db.loadFileInfos(
        pathNames,
        new CRDBService.FileInfoLoadingCallback() {
          @Override
          public void onFileInfoListLoaded(ArrayList<FileInfo> list) {
            log.v("onFileInfoListLoaded");
            // GUI thread
            final ArrayList<FileInfo> filesForParsing = new ArrayList<FileInfo>();
            ArrayList<FileInfo> filesForSave = new ArrayList<FileInfo>();
            Map<String, FileInfo> mapOfFilesFoundInDb = new HashMap<String, FileInfo>();
            for (FileInfo f : list) mapOfFilesFoundInDb.put(f.getPathName(), f);

            for (int i = 0; i < baseDir.fileCount(); i++) {
              FileInfo item = baseDir.getFile(i);
              FileInfo fromDB = mapOfFilesFoundInDb.get(item.getPathName());
              if (fromDB != null) {
                // use DB value
                baseDir.setFile(i, fromDB);
              } else {
                // not found in DB
                if (item.format.canParseProperties()) {
                  filesForParsing.add(new FileInfo(item));
                } else {
                  filesForSave.add(new FileInfo(item));
                }
              }
            }
            if (filesForSave.size() > 0) {
              db.saveFileInfos(filesForSave);
            }
            if (filesForParsing.size() == 0 || control.isStopped()) {
              readyCallback.run();
              return;
            }
            // scan files in Background thread
            BackgroundThread.instance()
                .postBackground(
                    new Runnable() {
                      @Override
                      public void run() {
                        // Background thread
                        final ArrayList<FileInfo> filesForSave = new ArrayList<FileInfo>();
                        try {
                          int count = filesForParsing.size();
                          for (int i = 0; i < count; i++) {
                            if (control.isStopped()) break;
                            progress.setProgress(i * 10000 / count);
                            FileInfo item = filesForParsing.get(i);
                            engine.scanBookProperties(item);
                            filesForSave.add(item);
                          }
                        } catch (Exception e) {
                          L.e("Exception while scanning", e);
                        }
                        progress.hide();
                        // jump to GUI thread
                        BackgroundThread.instance()
                            .postGUI(
                                new Runnable() {
                                  @Override
                                  public void run() {
                                    // GUI thread
                                    try {
                                      if (filesForSave.size() > 0) {
                                        db.saveFileInfos(filesForSave);
                                      }
                                      for (FileInfo file : filesForSave) baseDir.setFile(file);
                                    } catch (Exception e) {
                                      L.e("Exception while scanning", e);
                                    }
                                    // call finish handler
                                    readyCallback.run();
                                  }
                                });
                      }
                    });
          }
        });
  }