API to modify Firefox downloads list

前端 未结 1 1848
抹茶落季
抹茶落季 2021-01-16 17:28

I am looking to write a small firefox add-on that detects when files that were downloaded are (or have been) deleted locally and removes the corresponding entry in the firef

相关标签:
1条回答
  • 2021-01-16 18:29

    The relevant API is PlacesUtils which abstracts the complexity of the Places database.

    If your code runs in the context of a chrome window then you get a PlacesUtils glabal variable for free. Otherwise (bootstrapped, Add-on SDK, whatever) you have to import PlacesUtils.jsm.

    Cu.import("resource://gre/modules/PlacesUtils.jsm");
    

    As far as Places is concerned, downloaded files are nothing more than a special kind of visited pages, annotated accordingly. It's a matter of just one line of code to get an array of all downloaded files.

    var results = PlacesUtils.annotations.getAnnotationsWithName("downloads/destinationFileURI");
    

    Since we asked for the destinationFileURI annotation, each element of the resultarray holds the download location in the annotationValue property as a file: URI spec string.

    With that you can check if the file actually exists

    function getFileFromURIspec(fileurispec){
      // if Services is not available in your context Cu.import("resource://gre/modules/Services.jsm");
      var filehandler = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler);
      try{
        return filehandler.getFileFromURLSpec(fileurispec);
      }
      catch(e){
        return null;
      }
    }
    

    getFileFromURIspec will return an instance of nsIFile, or null if the spec is invalid which shouldn't happen in this case but a sanity check never hurts. With that you can call the exists() method and if it returns false then the associated page entry in Places is eligible for removal. We can tell which is that page by its uri, which conveniently is also a property of each element of the results.

    PlacesUtils.bhistory.removePage(result.uri);
    

    To sum it up

    var results = PlacesUtils.annotations.getAnnotationsWithName("downloads/destinationFileURI");
    results.forEach(function(result){
      var file = getFileFromURIspec(result.annotationValue);
      if(!file){
        // I don't know how you should treat this edge case
        // ask the user, just log, remove, some combination?
      }
      else if(!file.exists()){
        PlacesUtils.bhistory.removePage(result.uri);
      }
    });
    
    0 讨论(0)
提交回复
热议问题