Exemplo n.º 1
0
class NodeThumbnailRenderReply(QNetworkReply):
    def __init__(self, parent, request):
        QNetworkReply.__init__(self, parent)
        self.qbuffer = None
        self.connect(self, SIGNAL('abouteToClose()'), self.__close)
        self.byteArray = QByteArray()
        self.qbuffer = QBuffer(self.byteArray)
        self.node = vfs().getnode(str(request.url().path().toUtf8()))
        self.thumbnailer = Thumbnailer()
        self.connect(self.thumbnailer, SIGNAL("ThumbnailUpdate"),
                     self.updateThumbnail)
        self.setRequest(request)
        self.setOperation(QNetworkAccessManager.GetOperation)
        mime = "image/jpg"
        self.setHeader(QNetworkRequest.ContentTypeHeader, QVariant(mime))
        self.open()
        self.setUrl(request.url())
        self.connect(parent, SIGNAL("ready"), self.ready)
        self.ready()

    def ready(self):
        if self.node.dataType().find('video') != -1:
            pixmap = self.thumbnailer.generate(self.node,
                                               iconSize=128,
                                               frames=10)
        else:
            pixmap = self.thumbnailer.generate(self.node,
                                               iconSize=256,
                                               frames=10)
        if pixmap:
            self.updateThumbnail(self.node, pixmap)

    def updateThumbnail(self, node, pixmap):
        if pixmap == None:
            pixmap = QPixmap(":file_broken.png")
        pixmap.save(self.qbuffer, 'JPG')
        self.qbuffer.seek(0)
        QTimer.singleShot(0, self, SIGNAL("readyRead()"))
        QTimer.singleShot(0, self, SIGNAL("finished()"))

    def abort(self):
        self.close()

    def __del__(self):
        self.thumbnailer.unregister()

    def open(self, mode=None):
        try:
            self.qbuffer.open(QIODevice.ReadWrite | QIODevice.Unbuffered)
            self.setOpenMode(QIODevice.ReadWrite | QIODevice.Unbuffered)
            return True
        except (AttributeError, IOError):
            return False

    def seek(self, pos):
        if self.qbuffer:
            return self.qbuffer.seek(pos)
        return False

    def __close(self):
        if self.qbuffer:
            self.qbuffer.close()
            self.qbuffer = None
        return True

    def readData(self, size):
        if self.qbuffer:
            return self.qbuffer.read(size)
        return ""

    def pos(self):
        if self.qbuffer:
            return self.qbuffer.pos()
        return 0

    def isSequential(self):
        if self.qbuffer:
            return self.qbuffer.isSequential()
        return False

    def size(self):
        return self.qbuffer.size()

    def reset(self):
        if self.qbuffer:
            self.qbuffer.seek(0)
            return True
        return False

    def atEnd(self):
        if self.qbuffer:
            return self.qbuffer.atEnd()
        return False
Exemplo n.º 2
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
Exemplo n.º 3
0
class ThumbnailVideoView(QWidget, Script):
    IconSize = 256
    Frames = 10

    def __init__(self):
        Script.__init__(self, "thumbnailvideo")
        self.icon = None
        self.vfs = vfs.vfs()

    def start(self, args):
        try:
            self.preview = args["preview"].value()
        except IndexError:
            self.preview = False
        try:
            self.node = args["file"].value()
        except KeyError:
            pass

    def g_display(self):
        QWidget.__init__(self)
        self.copyMenu = CopyMenu(self)
        self.copySelectionMenu = CopySelectionMenu(self)
        self.rubberBand = None
        self.hlayout = QVBoxLayout()
        self.setLayout(self.hlayout)

        self.menuLayout = QHBoxLayout()
        self.hlayout.addLayout(self.menuLayout)

        self.frameLayout = QFormLayout()
        self.menuLayout.addLayout(self.frameLayout)
        self.frameNumberEdit = QLineEdit(str(self.Frames))
        self.frameNumberEdit.setFixedWidth(40)
        self.frameNumberEdit.setValidator(QIntValidator(0, 256))
        self.frameLayout.addRow("Number of frame: ", self.frameNumberEdit)
        self.connect(self.frameNumberEdit, SIGNAL("textChanged(QString)"),
                     self.setFrameNumber)

        self.iconLayout = QFormLayout()
        self.menuLayout.addLayout(self.iconLayout)
        self.iconSizeEdit = QLineEdit(str(self.IconSize))
        self.iconSizeEdit.setFixedWidth(40)
        self.iconSizeEdit.setValidator(QIntValidator(0, 512))
        self.iconLayout.addRow("Size: ", self.iconSizeEdit)
        self.connect(self.iconSizeEdit, SIGNAL("textChanged(QString)"),
                     self.setIconSize)

        self.refreshButton = QPushButton("Refresh")
        self.menuLayout.addWidget(self.refreshButton)
        self.connect(self.refreshButton, SIGNAL("clicked()"),
                     self.generateThumbnail)

        self.scrollArea = QScrollArea()
        self.hlayout.addWidget(self.scrollArea)

        self.generateThumbnail()

    def mousePressEvent(self, event):
        self.dragPosition = event.pos()
        if not self.rubberBand:
            self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.rubberBand.setGeometry(QRect(self.dragPosition, QSize()))
        self.rubberBand.show()

    def mouseMoveEvent(self, event):
        self.rubberBand.setGeometry(
            QRect(self.dragPosition, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if not self.rubberBand.size().isEmpty():
            rect = QRect(self.rubberBand.pos(), self.rubberBand.size())
            rect.moveLeft(rect.left() -
                          (self.width() - self.thumbLabel.pixmap().width()) /
                          2.0)
            rect.moveTop(rect.top() -
                         (self.height() - self.thumbLabel.pixmap().height()) /
                         2.0)
            self.currentSelection = rect
            self.copySelectionMenu.popup(QCursor.pos())
        else:
            self.copyMenu.popup(QCursor.pos())
        self.rubberBand.hide()

    def copySelectionToClipboard(self):
        QApplication.clipboard().setPixmap(self.thumbLabel.pixmap().copy(
            self.currentSelection))

    def copyPixmapToClipboard(self):
        QApplication.clipboard().setPixmap(self.thumbLabel.pixmap())

    def setIconSize(self, size):
        ThumbnailVideoView.IconSize = int(size)

    def setFrameNumber(self, number):
        ThumbnailVideoView.Frames = int(number)

    def generateThumbnail(self):
        self.thumbnailer = Thumbnailer()
        self.connect(self.thumbnailer, SIGNAL("ThumbnailUpdate"),
                     self.updateThumbnail)
        pixmap = self.thumbnailer.generate(self.node,
                                           iconSize=self.IconSize,
                                           frames=self.Frames)
        if pixmap:
            self.updateThumbnail(self.node, pixmap)

    def updateThumbnail(self, node, pixmap):
        if pixmap:
            self.thumbLabel = QLabel()
            self.thumbLabel.setSizePolicy(QSizePolicy.Expanding,
                                          QSizePolicy.Expanding)
            self.thumbLabel.setWordWrap(True)
            self.thumbLabel.setPixmap(pixmap)
            self.scrollArea.setWidget(self.thumbLabel)
        else:
            self.thumbLabel.setText("Can't render, video is corrupted.")
            self.thumbLabel.setAlignment(Qt.AlignCenter)
        self.thumbnailer.unregister()

    def updateWidget(self):
        pass