Exemple #1
3
class EXTRACT(Script, EventHandler):
  reservednames = ['CON', 'PRN', 'AUX', 'CLOCK$', 'NUL',
                 'COM0', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
                 'LPT0', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9',
                 '$AttrDef', '$BadClus', '$Bitmap', '$Boot', '$LogFile', '$MFT', '$MFTMirr', 
                 'pagefile.sys', '$Secure', '$UpCase', '$Volume', '$Extend']

  max_depth = 2**31-1

  def __init__(self):
    Script.__init__(self, "extract")
    EventHandler.__init__(self)
    self.vfs = vfs.vfs()
    self.extractor = Extract()
    self.extractor.connection(self)


  def start(self, args):
    self.total_files = 0
    self.total_folders = 0
    self.extracted_files = 0
    self.extracted_folders = 0
    self.files_errors = 0
    self.folders_errors = 0
    self.ommited_files = 0
    self.ommited_folders = 0
    self.__failed_files = []
    self.__failed_folders = []
    self.__renamed = {}
    try:
      self.nodes = args['files'].value()
      self.syspath = args['syspath'].value().path
      if not os.path.isdir(self.syspath):
        self.res["errors"] = Variant(self.syspath + " is not a valid directory")
        return
      if args.has_key('recursive'):
        self.recursive = args["recursive"].value()
      else:
        self.recursive = False
      if args.has_key('preserve'):
        self.preserve = args["preserve"].value()
      else:
        self.preserve = False
      if args.has_key('overwrite'):
        self.overwrite = args["overwrite"].value()
      else:
        self.overwrite = False
      self.__extract()
      self.__createReport()
    except KeyError:
      pass


  def Event(self, e):
    if e.type == Extract.FileProgress:
      idx = self.stateinfo.rfind("extracting")
      vl = e.value.value()
      node = vl[0].value()
      percent = vl[1].value()
      if idx != -1:
        buff = self.stateinfo[:idx]
        buff += "extracting " + node.absolute() + ": " + str(percent) + " %"
        self.stateinfo = buff
      else:
        self.stateinfo += "extracting " + node.absolute() + ": " + str(percent) + " %"
    if e.type == Extract.OverallProgress:
      self.stateinfo = str(e.value)
    if e.type == Extract.FileFailed:
      vl = e.value.value()
      self.__failed_files.append(vl[0].value())
      print "extracting file failed", vl[0].value(), "\n", vl[1]
    if e.type == Extract.FolderFailed:
      vl = e.value.value()
      self.__failed_folders.append(vl[0].value())
      print "extracting folder failed", vl[0].value(), "\n", vl[1]
    if e.type == Extract.PreserveFailed:
      vl = e.value.value()
      self.__preserved_failed = vl[0].value()
      print "preserving tree failed", vl[0].value(), "\n", vl[1]
    if e.type == Extract.RenameOccured:
      vl = e.value.value()
      if not self.__renamed.has_key(vl[0].value()):
        self.__renamed[str(vl[0])] = []
      self.__renamed[str(vl[0])].append(str(vl[1]))
      print "rename: ", vl[0], " --> ", vl[1]
    del e

  def __extract(self):
    for vnode in self.nodes:
      node = vnode.value()
      if self.recursive:
        self.extractor.extractTree(node, self.syspath, self.preserve, self.overwrite)
      else:
        if node.hasChildren() or node.isDir():
          self.extractor.extractFolder(node, self.syspath, self.preserve, self.overwrite)
        else:
          self.extractor.extractFile(node, self.syspath, self.preserve, self.overwrite)


  def __createReport(self):
    if len(self.__failed_files):
      vl = VList()
      for ffile in self.__failed_files:
        vl.append(Variant(ffile))
      self.res["failed extraction for files"] = vl
    if len(self.__failed_folders):
      vl = VList()
      for ffolder in self.__failed_folders:
        vl.append(Variant(ffolder))
      self.res["failed extraction for folders"] = vl
    if len(self.__renamed):
      vmap = VMap()
      for key in self.__renamed:
        vl = VList()
        for val in self.__renamed[key]:
          vl.append(Variant(val))
        vmap[key] = vl
      self.res["renamed"] = vmap
Exemple #2
0
class EXTRACT(Script, EventHandler):
    reservednames = [
        'CON', 'PRN', 'AUX', 'CLOCK$', 'NUL', 'COM0', 'COM1', 'COM2', 'COM3',
        'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT0', 'LPT1', 'LPT2',
        'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9', '$AttrDef',
        '$BadClus', '$Bitmap', '$Boot', '$LogFile', '$MFT', '$MFTMirr',
        'pagefile.sys', '$Secure', '$UpCase', '$Volume', '$Extend'
    ]

    max_depth = 2**31 - 1

    def __init__(self):
        Script.__init__(self, "extract")
        EventHandler.__init__(self)
        self.vfs = vfs.vfs()
        self.extractor = Extract()
        self.extractor.connection(self)

    def start(self, args):
        self.total_files = 0
        self.total_folders = 0
        self.extracted_files = 0
        self.extracted_folders = 0
        self.files_errors = 0
        self.folders_errors = 0
        self.ommited_files = 0
        self.ommited_folders = 0
        self.__failed_files = []
        self.__failed_folders = []
        self.__renamed = {}
        try:
            self.nodes = args['files'].value()
            self.syspath = args['syspath'].value().path
            if not os.path.isdir(self.syspath):
                self.res["errors"] = Variant(self.syspath +
                                             " is not a valid directory")
                return
            if args.has_key('recursive'):
                self.recursive = args["recursive"].value()
            else:
                self.recursive = False
            if args.has_key('preserve'):
                self.preserve = args["preserve"].value()
            else:
                self.preserve = False
            if args.has_key('overwrite'):
                self.overwrite = args["overwrite"].value()
            else:
                self.overwrite = False
            self.__extract()
            self.__createReport()
        except KeyError:
            pass

    def Event(self, e):
        if e.type == Extract.FileProgress:
            idx = self.stateinfo.rfind("extracting")
            vl = e.value.value()
            node = vl[0].value()
            percent = vl[1].value()
            if idx != -1:
                buff = self.stateinfo[:idx]
                buff += "extracting " + node.absolute() + ": " + str(
                    percent) + " %"
                self.stateinfo = buff
            else:
                self.stateinfo += "extracting " + node.absolute() + ": " + str(
                    percent) + " %"
        if e.type == Extract.OverallProgress:
            self.stateinfo = str(e.value)
        if e.type == Extract.FileFailed:
            vl = e.value.value()
            self.__failed_files.append(vl[0].value())
            print "extracting file failed", vl[0].value(), "\n", vl[1]
        if e.type == Extract.FolderFailed:
            vl = e.value.value()
            self.__failed_folders.append(vl[0].value())
            print "extracting folder failed", vl[0].value(), "\n", vl[1]
        if e.type == Extract.PreserveFailed:
            vl = e.value.value()
            self.__preserved_failed = vl[0].value()
            print "preserving tree failed", vl[0].value(), "\n", vl[1]
        if e.type == Extract.RenameOccured:
            vl = e.value.value()
            if not self.__renamed.has_key(vl[0].value()):
                self.__renamed[str(vl[0])] = []
            self.__renamed[str(vl[0])].append(str(vl[1]))
            print "rename: ", vl[0], " --> ", vl[1]
        del e

    def __extract(self):
        for vnode in self.nodes:
            node = vnode.value()
            if self.recursive:
                self.extractor.extractTree(node, self.syspath, self.preserve,
                                           self.overwrite)
            else:
                if node.hasChildren() or node.isDir():
                    self.extractor.extractFolder(node, self.syspath,
                                                 self.preserve, self.overwrite)
                else:
                    self.extractor.extractFile(node, self.syspath,
                                               self.preserve, self.overwrite)

    def __createReport(self):
        if len(self.__failed_files):
            vl = VList()
            for ffile in self.__failed_files:
                vl.append(Variant(ffile))
            self.res["failed extraction for files"] = vl
        if len(self.__failed_folders):
            vl = VList()
            for ffolder in self.__failed_folders:
                vl.append(Variant(ffolder))
            self.res["failed extraction for folders"] = vl
        if len(self.__renamed):
            vmap = VMap()
            for key in self.__renamed:
                vl = VList()
                for val in self.__renamed[key]:
                    vl.append(Variant(val))
                vmap[key] = vl
            self.res["renamed"] = vmap
Exemple #3
0
class NodeListFragment(ReportPageFragment):
    DefaultHeader = [
        {
            'title': 'name',
            'callback': lambda Node: Node.name()
        },
        {
            'title': 'size',
            'callback': lambda Node: Node.size()
        },
        {
            'title': 'tags',
            'callback': lambda Node: getTags(Node)
        },
    ]
    ListView = 0
    GalleryView = 1
    DetailedAttributes = None
    HeaderAttributes = None
    HeaderAttributesName = None

    def __init__(self, title, nodes, thead, view):
        ReportPageFragment.__init__(self, title)
        self.nodes = nodes
        self.thead = thead
        self.view = view
        self.extract = Extract()
        self.filepath = None
        self.thumbpath = None
        if QApplication.instance():
            self.gui = True
        else:
            self.gui = False
        #XXX header don't support '.' in name
    def addNode(self, node):
        self.nodes.append(node)

    def elements(self):
        return self.nodes

    def dumpsJSON(self):
        thead = []
        for head in self.thead:
            thead.append(head['title'])
        if NodeListFragment.HeaderAttributes:
            for attribute in NodeListFragment.HeaderAttributes:
                thead.append(attribute)
        buff = '{"title": "' + self.title + '",' + '"widget": "node_list", "thead":'
        buff += json.dumps(thead)
        buff += ', "view" : ' + str(self.view) + ', "data" : ['
        for node in self.nodes:
            try:
                rowjson = {}
                rowjson['widget'] = 'node'
                for head in self.thead:
                    cb = head['callback'](node)
                    if type(cb) == str:
                        cb = cb.decode('utf-8', 'replace').encode('utf-8')
                    rowjson[head['title']] = cb
                    if self.gui:  #Need qt gui for QPixmap or will crash in console
                        #print 'self as GUI !', QApplication.instance()
                        self.thumbnailer = Thumbnailer()
                        if self.thumbnailer.isThumbnailable(node):
                            rowjson[
                                "thumb"] = "dff-node-thumbnail://" + node.absolute(
                                ).decode('utf-8', 'replace').encode('utf-8')
                        self.thumbnailer.unregister()
                rowjson['row_details'] = {
                    'widget': 'node_attribute',
                    'data': self.attributesToMap(node.attributes())
                }
                buff += json.dumps(rowjson)
                buff += ","
            except UnicodeError as e:
                print "Can't dump node " + str(
                    node.absolute()) + " : " + str(e)
        buff += "]}"
        return buff

    def writeSize(self, exportContent):
        size = 0
        if exportContent:
            for node in self.nodes:
                size += node.size()
        return size

    def writeJSON__(self, fd, page_path, report_path, exportContent=True):
        self.filepath = page_path + "/" + 'files'
        self.thumbpath = page_path + "/" + 'thumbs'
        buff = '{"title": "' + self.title + '",' + '"widget": "node_list", "thead":'
        fd.write(buff)
        thead = []
        for head in self.thead:
            thead.append(head['title'])
        #XXX header don't support '.' in name
        if NodeListFragment.HeaderAttributesName:
            for name in NodeListFragment.HeaderAttributesName:
                thead.append(name)
        json.dump(thead, fd)
        bdata = ', "view" : ' + str(self.view) + ', "data" : ['
        fd.write(bdata)
        self.notifyWrite(ReportPageFragment.EventWriteElements,
                         len(self.nodes))
        for node in self.nodes:
            self.notifyWrite(ReportPageFragment.EventWriteElementStart,
                             node.absolute())
            try:
                filename = None
                if exportContent:
                    filename = self.exportNode(node, self.filepath,
                                               report_path)
                self.nodeToJSON(node, filename, fd, report_path, page_path,
                                True)
                fd.write(',\n')
            except Exception as e:
                print "Can't write node " + str(
                    node.absolute()) + " : " + str(e)
            self.notifyWrite(ReportPageFragment.EventWriteElementFinish,
                             node.absolute())
        fd.write("]}")

    def attributesToMap(self, attributes):
        attributesMap = {}
        for key, variantMap in attributes.iteritems():
            vmap = self.recurseVariant(variantMap, {}, '')
            if len(vmap):
                attributesMap[key] = vmap
        attributesMap = OrderedDict(
            sorted(attributesMap.items(), key=lambda t: t[0]))
        return attributesMap

    def recurseVariant(self, variant, varMap, keyPath):
        if isinstance(variant, VMap):
            for key, vvar in variant.iteritems():
                if len(keyPath):
                    self.recurseVariant(vvar, varMap, keyPath + '.' + str(key))
                else:
                    self.recurseVariant(vvar, varMap, str(key))
        if isinstance(variant, VList):
            l = []
            for i in range(len(variant)):
                self.recurseVariant(variant[i], varMap,
                                    keyPath + ' (' + str(i) + ')')
        if isinstance(variant, Variant) or isinstance(variant, RCVariant):
            val = variant.value()
            if isinstance(val, VMap) or isinstance(val, VList):
                self.recurseVariant(val, varMap, keyPath)
            else:
                if isinstance(val, DateTime):
                    try:
                        val = str(val)
                    except:
                        val = "Invalid"
                if type(val) == str:
                    val = val.decode('utf-8', 'replace').encode('utf-8')
                translated = False
                if NodeListFragment.DetailedAttributes:
                    for (
                            finalName, attributeName
                    ) in NodeListFragment.DetailedAttributes:  #HeaderAttributes depend of this because it's attribute filled in the table will use the result of this function called by attributesMap if there is no detailed attributes there will no translation and the header can't be filled
                        if keyPath == attributeName:
                            varMap[finalName] = val
                if not translated:
                    varMap[keyPath] = val
        varMap = OrderedDict(sorted(varMap.items(), key=lambda t: t[0]))
        return varMap

    def findInAttributesMap(self, attribute, attributesMap):
        for module in attributesMap:
            moduleAttributes = attributesMap.get(module)
            if moduleAttributes:
                result = moduleAttributes.get(attribute)
                if result:
                    return result
        return ""

    def nodeToJSON(self,
                   node,
                   filename,
                   fd,
                   report_path,
                   page_path,
                   thumb=False):
        rowjson = {}
        rowjson['widget'] = 'node'
        attrMap = self.attributesToMap(node.attributes())
        for head in self.thead:
            cb = head['callback'](node)
            if type(cb) == str:
                cb = cb.decode('utf-8', 'replace').encode('utf-8')
            rowjson[head['title']] = cb
        if NodeListFragment.HeaderAttributes:
            for (name, attribute) in NodeListFragment.HeaderAttributes:
                result = self.findInAttributesMap(name, attrMap)
                rowjson[name] = result
        if filename:
            rowjson["file"] = self.filepath + "/" + filename
            if thumb and self.gui:
                if self.exportThumbnail(report_path, self.thumbpath,
                                        filename + '.jpg', node):
                    rowjson["thumb"] = self.thumbpath + "/" + filename + '.jpg'
        rowjson['row_details'] = {'widget': 'node_attribute', 'data': attrMap}
        try:
            json.dump(rowjson, fd)
        except UnicodeError as e:
            print 'report.fragment.nodeToJSON failed ' + str(e)
            print rowjson

    def exportThumbnail(self, report_path, thumbpath, name, node, size=None):
        self.thumbnailer = Thumbnailer()
        if self.thumbnailer.isThumbnailable(node):
            pixmap = self.thumbnailer.generate(node,
                                               iconSize=256,
                                               frames=10,
                                               blocking=True)
            self.thumbnailer.unregister()
            if pixmap:
                try:
                    exportPath = os.path.join(report_path,
                                              os.path.join(thumbpath, name))
                    array = QByteArray()
                    qfile = QBuffer(array)
                    qfile.open(QIODevice.ReadWrite)
                    pixmap.save(qfile, 'JPG')
                    qfile.seek(0)
                    with open(exportPath, 'wb') as f:
                        f.write(qfile.read(qfile.size()))
                    qfile.close()
                    return True
                except Exception as e:
                    qfile.close()
                    return False
            else:
                return False

    def exportNode(self, node, path, report_path):
        abspath = os.path.join(report_path, path)
        try:
            local_path = self.extract.extractFile(node, abspath)
        except Exception as e:
            pass

        if local_path:
            return os.path.basename(local_path)
        else:
            return None