Example #1
0
    def fetch_online_directories(self):
        """Fetch online directory of repositories."""
        downloader = NetworkManager(self.DIRECTORY_URL)
        status, _ = downloader.fetch()
        if status:
            directory_file = QTemporaryFile()
            if directory_file.open():
                directory_file.write(downloader.content)
                directory_file.close()

            with open(directory_file.fileName()) as csv_file:
                reader = csv.DictReader(csv_file, fieldnames=('name', 'url'))
                for row in reader:
                    self._online_directories[row['name']] = row['url'].strip()
            # Save it to cache
            settings = QSettings()
            settings.beginGroup(repo_settings_group())
            settings.setValue('online_directories', self._online_directories)
            settings.endGroup()
        else:
            # Just use cache from previous use
            settings = QSettings()
            settings.beginGroup(repo_settings_group())
            self._online_directories = settings.value('online_directories', {})
            settings.endGroup()
Example #2
0
    def download_collection(self, id, register_name):
        """Download a collection given its ID.

        For zip collection, we will download the zip, and extract the
        collection to collections dir.

        :param id: The ID of the collection.
        :type id: str

        :param register_name: The register name of the collection (the
            section name of the collection)
        :type register_name: unicode
        """
        # Download the zip first
        collection_path = 'collections/%s.zip' % register_name
        network_manager = NetworkManager(self.file_url(collection_path))
        status, description = network_manager.fetch()

        if not status:
            return False, description

        # Create the zip file
        zip_file = QTemporaryFile()
        if zip_file.open():
            zip_file.write(network_manager.content)
            zip_file.close()

        zf = ZipFile(zip_file.fileName())
        zf.extractall(path=local_collection_path(id))
        return True, None
Example #3
0
    def write(self, theRasterName):
        print theRasterName

        path = "%s/%s" % (self.testDataDir, theRasterName)
        # myFileInfo = QFileInfo( path )
        # myBaseName = myFileInfo.baseName()
        rasterLayer = QgsRasterLayer(path, "test")
        if not rasterLayer.isValid():
            return False
        provider = rasterLayer.dataProvider()

        tmpFile = QTemporaryFile()
        tmpFile.open()  # fileName is no avialable until open
        tmpName = tmpFile.fileName()
        tmpFile.close()
        # do not remove when class is destroyd so that we can read the file and see difference
        tmpFile.setAutoRemove(False)

        fileWriter = QgsRasterFileWriter(tmpName)
        pipe = QgsRasterPipe()
        if not pipe.set(provider.clone()):
            print "Cannot set pipe provider"
            return False

        # nuller = QgsRasterNuller()
        # nuller.setNoData( ... )
        # if not pipe.insert( 1, nuller ):
        #    print "Cannot set pipe nuller"
        #    return False

        projector = QgsRasterProjector()
        projector.setCRS(provider.crs(), provider.crs())
        if not pipe.insert(2, projector):
            print "Cannot set pipe projector"
            return False

        fileWriter.writeRaster(pipe, provider.xSize(), provider.ySize(), provider.extent(), provider.crs())

        checker = QgsRasterChecker()
        ok = checker.runTest("gdal", tmpName, "gdal", path)
        self.report += checker.report()

        # All OK, we can delete the file
        tmpFile.setAutoRemove(ok)

        return ok
Example #4
0
def generate_qr_code(qr_content):
    """
    Generates a QR code SVG item and saves it as a temporary file.
    :param qr_content: Content used to generate a QR code.
    :type qr_content: str
    :return: Returns a QTemporaryFile object containing the SVG file with the
    QR code.
    :rtype: QTemporaryFile
    """
    tmpf = QTemporaryFile()
    if tmpf.open():
        file_path = tmpf.fileName()
        qr_code = pyqrcode.create(qr_content)
        qr_code.svg(file_path, scale=6)
        tmpf.close()

    return tmpf
Example #5
0
    def display_downloaded_content(self):
        """
        Called when an unsupported content type is finished downloading.
        """
        file_path = QDir.toNativeSeparators(QDir.tempPath() + "/XXXXXX_" + self.content_filename)
        myfile = QTemporaryFile(file_path)
        myfile.setAutoRemove(False)
        if (myfile.open()):
            myfile.write(self.reply.readAll())
            myfile.close()
            subprocess.Popen([self.content_handlers.get(str(self.content_type)), myfile.fileName()])

            #Sometimes downloading files opens an empty window.
            #So if the current window has no URL, close it.
            if(str(self.url().toString()) in ('', 'about:blank')):
                self.close()
Example #6
0
    def render_plot(self, tight_layout=False):
        """
        Saves the pyplot instance as an image in the OS's temp folder
        then refers the absolute path of the image to the QgsComposerPicture
        item.
        """
        chart_tmp = QTemporaryFile()
        if chart_tmp.open():
            tmp_file_name = chart_tmp.fileName()

            if tight_layout:
                plt.tight_layout()

            plt.savefig(tmp_file_name, format="tif", dpi=200)

            # Set path of picture item
            self.composer_item().setPicturePath(tmp_file_name)

        else:
            raise RuntimeError("Chart item could not be rendered")
Example #7
0
    def render_plot(self, tight_layout=False):
        """
        Saves the pyplot instance as an image in the OS's temp folder
        then refers the absolute path of the image to the QgsComposerPicture
        item.
        """
        chart_tmp = QTemporaryFile()
        if chart_tmp.open():
            tmp_file_name = chart_tmp.fileName()

            if tight_layout:
                plt.tight_layout()

            plt.savefig(tmp_file_name, format="tif", dpi=200)

            #Set path of picture item
            self.composer_item().setPicturePath(tmp_file_name)

        else:
            raise RuntimeError("Chart item could not be rendered")
    def saveOutputFile(self):
        #TODO: save sweep direction
        if self.ui.saveModeCombo.currentIndex() == 0:  # we're in I,V vs t mode
            self.postProcessThread.saveTime = True
        else:  # we're in I vs V mode
            self.postProcessThread.saveTime = False
        self.postProcessThread.area = str(self.ui.deviceAreaEdit.text())

        self.postProcessThread.savePath = os.path.join(
            str(self.ui.dirEdit.text()), str(self.ui.fileEdit.text()))

        self.postProcessThread.tempFile = QTemporaryFile()

        self.postProcessThread.sweepUp = self.sweepUp

        self.postProcessThread.start()
Example #9
0
    def _get_cursor_columns(self, c):
        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        q = QUrl.toPercentEncoding(c.sql)
        p = QgsVectorLayer("%s?query=%s" % (tmp, q), "vv", "virtual")
        if not p.isValid():
            return []
        f = [f.name() for f in p.fields()]
        if p.geometryType() != QGis.WKBNoGeometry:
            gn = getQueryGeometryName(tmp)
            if gn:
                f += [gn]
        return f
Example #10
0
    def _get_cursor_columns(self, c):
        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        q = QUrl.toPercentEncoding(c.sql)
        p = QgsProviderRegistry.instance().provider("virtual",
                                                    "%s?query=%s" % (tmp, q))
        if not p.isValid():
            return []
        f = [f.name() for f in p.fields()]
        if p.geometryType() != QGis.WKBNoGeometry:
            gn = get_query_geometry_name(tmp)
            if gn:
                f += [gn]
        return f
Example #11
0
    def __init__(self, db, sql, parent=None):
        # create a virtual layer with non-geometry results
        q = QUrl.toPercentEncoding(sql)
        t = QTime()
        t.start()

        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        p = QgsVectorLayer(
            "%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv",
            "virtual")
        self._secs = t.elapsed() / 1000.0

        if not p.isValid():
            data = []
            header = []
            raise DbError(p.dataProvider().error().summary(), sql)
        else:
            header = [f.name() for f in p.fields()]
            has_geometry = False
            if p.geometryType() != QGis.WKBNoGeometry:
                gn = getQueryGeometryName(tmp)
                if gn:
                    has_geometry = True
                    header += [gn]

            data = []
            for f in p.getFeatures():
                a = f.attributes()
                if has_geometry:
                    if f.geometry():
                        a += [f.geometry().exportToWkt()]
                    else:
                        a += [None]
                data += [a]

        self._secs = 0
        self._affectedRows = len(data)

        BaseTableModel.__init__(self, header, data, parent)
Example #12
0
    def _get_cursor_columns(self, c):
        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        q = QUrl.toPercentEncoding(c.sql)
        p = QgsVectorLayer("%s?query=%s" % (tmp, q), "vv", "virtual")
        if not p.isValid():
            return []
        f = [f.name() for f in p.fields()]
        if p.geometryType() != QGis.WKBNoGeometry:
            gn = getQueryGeometryName(tmp)
            if gn:
                f += [gn]
        return f
Example #13
0
 def _get_cursor_columns( self, c ):
     tf = QTemporaryFile()
     tf.open()
     tmp = tf.fileName()
     tf.close()
     
     q = QUrl.toPercentEncoding(c.sql)
     p = QgsProviderRegistry.instance().provider("virtual", "%s?query=%s" % (tmp, q) )
     if not p.isValid():
         return []
     f = [ f.name() for f in p.fields() ]
     if p.geometryType() != QGis.WKBNoGeometry:
         gn = get_query_geometry_name( tmp )
         if gn:
             f += [gn]
     return f
Example #14
0
def generate_qr_code(qr_content):
    """
    Generates a QR code SVG item and saves it as a temporary file.
    :param qr_content: Content used to generate a QR code.
    :type qr_content: str
    :return: Returns a QTemporaryFile object containing the SVG file with the
    QR code.
    :rtype: QTemporaryFile
    """
    tmpf = QTemporaryFile()
    if tmpf.open():
        file_path = tmpf.fileName()
        qr_code = pyqrcode.create(qr_content)
        qr_code.svg(file_path, scale=6)
        tmpf.close()

    return tmpf
Example #15
0
    def __init__(self, db, sql, parent=None):
        # create a virtual layer with non-geometry results
        q = QUrl.toPercentEncoding(sql)
        t = QTime()
        t.start()

        tf = QTemporaryFile()
        tf.open()
        tmp = tf.fileName()
        tf.close()

        p = QgsVectorLayer("%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv", "virtual")
        self._secs = t.elapsed() / 1000.0

        if not p.isValid():
            data = []
            header = []
            raise DbError(p.dataProvider().error().summary(), sql)
        else:
            header = [f.name() for f in p.fields()]
            has_geometry = False
            if p.geometryType() != QGis.WKBNoGeometry:
                gn = getQueryGeometryName(tmp)
                if gn:
                    has_geometry = True
                    header += [gn]

            data = []
            for f in p.getFeatures():
                a = f.attributes()
                if has_geometry:
                    if f.geometry():
                        a += [f.geometry().exportToWkt()]
                    else:
                        a += [None]
                data += [a]

        self._secs = 0
        self._affectedRows = len(data)

        BaseTableModel.__init__(self, header, data, parent)
    def write(self, theRasterName):
        print theRasterName

        path = "%s/%s" % (self.testDataDir, theRasterName)
        rasterLayer = QgsRasterLayer(path, "test")
        if not rasterLayer.isValid(): return False
        provider = rasterLayer.dataProvider()

        tmpFile = QTemporaryFile()
        tmpFile.open()  # fileName is no avialable until open
        tmpName = tmpFile.fileName()
        tmpFile.close()
        # do not remove when class is destroyed so that we can read
        # the file and see difference
        tmpFile.setAutoRemove(False)

        fileWriter = QgsRasterFileWriter(tmpName)
        pipe = QgsRasterPipe()
        if not pipe.set(provider.clone()):
            print "Cannot set pipe provider"
            return False

        projector = QgsRasterProjector()
        projector.setCRS(provider.crs(), provider.crs())
        if not pipe.insert(2, projector):
            print "Cannot set pipe projector"
            return False

        fileWriter.writeRaster(pipe, provider.xSize(), provider.ySize(),
                               provider.extent(), provider.crs())

        checker = QgsRasterChecker()
        ok = checker.runTest("gdal", tmpName, "gdal", path)
        self.report += checker.report()

        # All OK, we can delete the file
        tmpFile.setAutoRemove(ok)

        return ok
Example #17
0
    def adjust(self):
        """ Export data to GNU Gama xml, adjust the network and read result

            :returns: result list of adjusment from GNU Gama
        """
        # fix = 0 free network
        fix = 0
        adj = 0
        for p, s in self.points:
            if s == 'FIX':
                fix += 1
            else:
                adj += 1
        if adj == 0 or len(self.observations) == 0:
            # no unknowns or observations
            return None

        doc = QDomDocument()
        doc.appendChild(
            doc.createComment(
                'Gama XML created by SurveyingCalculation plugin for QGIS'))
        gama_local = doc.createElement('gama-local')
        gama_local.setAttribute('version', '2.0')
        doc.appendChild(gama_local)
        network = doc.createElement('network')
        network.setAttribute('axes-xy', 'ne')
        network.setAttribute('angles', 'left-handed')
        gama_local.appendChild(network)
        description = doc.createElement('description')
        if self.dimension == 1:
            description.appendChild(doc.createTextNode('GNU Gama 1D network'))
        elif self.dimension == 2:
            description.appendChild(doc.createTextNode('GNU Gama 2D network'))
        elif self.dimension == 3:
            description.appendChild(doc.createTextNode('GNU Gama 3D network'))
        network.appendChild(description)
        parameters = doc.createElement('parameters')
        parameters.setAttribute('sigma-apr', '1')
        parameters.setAttribute('conf-pr', str(self.probability))
        parameters.setAttribute('tol-abs', '1000')
        parameters.setAttribute('sigma-act', 'aposteriori')
        parameters.setAttribute('update-constrained-coordinates', 'yes')
        network.appendChild(parameters)
        points_observations = doc.createElement('points-observations')
        points_observations.setAttribute(
            'distance-stdev',
            str(self.stdev_dist) + ' ' + str(self.stdev_dist1))
        points_observations.setAttribute('direction-stdev',
                                         str(self.stdev_angle))
        points_observations.setAttribute('angle-stdev',
                                         str(math.sqrt(self.stdev_angle * 2)))
        points_observations.setAttribute('zenith-angle-stdev',
                                         str(self.stdev_angle))
        network.appendChild(points_observations)
        for p, s in self.points:
            if self.dimension == 1:
                tmp = doc.createElement('point')
                tmp.setAttribute('id', p.id)
                if p.z is not None:
                    tmp.setAttribute('z', str(p.z))
                if s == 'FIX':
                    tmp.setAttribute('fix', 'z')
                else:
                    if fix == 0:
                        tmp.setAttribute('adj', 'Z')
                    else:
                        tmp.setAttribute('adj', 'z')
                points_observations.appendChild(tmp)
            elif self.dimension == 2:
                tmp = doc.createElement('point')
                tmp.setAttribute('id', p.id)
                if p.e is not None and p.n is not None:
                    tmp.setAttribute('y', str(p.e))
                    tmp.setAttribute('x', str(p.n))
                if s == 'FIX':
                    tmp.setAttribute('fix', 'xy')
                else:
                    if fix == 0:
                        # free network
                        tmp.setAttribute('adj', 'XY')
                    else:
                        tmp.setAttribute('adj', 'xy')
                points_observations.appendChild(tmp)
            elif self.dimension == 3:
                tmp = doc.createElement('point')
                tmp.setAttribute('id', p.id)
                if p.e is not None and p.n is not None:
                    tmp.setAttribute('y', str(p.e))
                    tmp.setAttribute('x', str(p.n))
                if p.z is not None:
                    tmp.setAttribute('z', str(p.z))
                if s == 'FIX':
                    tmp.setAttribute('fix', 'xyz')
                else:
                    if fix == 0:
                        tmp.setAttribute('adj', 'XYZ')
                    else:
                        tmp.setAttribute('adj', 'xyz')
                points_observations.appendChild(tmp)
        if self.dimension == 1:
            hd = doc.createElement('height-differences')
            points_observations.appendChild(hd)
        for o in self.observations:
            if o.station == 'station':
                # station record
                st_id = o.point_id
                if o.th is None:
                    ih = 0
                else:
                    ih = o.th
                if self.dimension in [2, 3]:
                    sta = doc.createElement('obs')
                    sta.setAttribute('from', o.point_id)
                    points_observations.appendChild(sta)
            else:
                # observation
                if self.dimension == 2:
                    # horizontal network
                    if o.hz is not None:
                        tmp = doc.createElement('direction')
                        tmp.setAttribute('to', o.point_id)
                        tmp.setAttribute('val', str(o.hz.get_angle('GON')))
                        sta.appendChild(tmp)
                    if o.d is not None:
                        # horizontal distance
                        hd = o.horiz_dist()
                        if hd is not None:
                            tmp = doc.createElement('distance')
                            tmp.setAttribute('to', o.point_id)
                            tmp.setAttribute('val', str(hd))
                            sta.appendChild(tmp)
                elif self.dimension == 1:
                    # elevations only 1d
                    if o.th is None:
                        th = 0
                    else:
                        th = o.th
                    if o.d is not None and o.v is not None:
                        tmp = doc.createElement('dh')
                        tmp.setAttribute('from', st_id)
                        tmp.setAttribute('to', o.point_id)
                        # TODO hibaterjedes
                        tmp.setAttribute('stdev', '1')
                        sz = math.sin(o.v.get_angle())
                        w = self.stdev_dist + self.stdev_dist1 * o.d.d / 1000
                        ro_cc = 200 * 100 * 100 / math.pi
                        if o.d.mode == 'SD':
                            cz = math.cos(o.v.get_angle())
                            tmp.setAttribute('val', str(o.d.d * cz + ih - th))
                            tmp.setAttribute(
                                'stdev',
                                str(
                                    math.sqrt(cz**2 * w**2 +
                                              (o.d.d * 1000)**2 * sz**2 *
                                              (self.stdev_angle / RO_CC)**2)))
                        else:
                            tz = math.tan(o.v.get_angle())
                            tmp.setAttribute(
                                'val',
                                str(o.d.d / math.tan(o.v.get_angle()) + ih -
                                    th))
                            tmp.setAttribute(
                                'stdev',
                                str(
                                    math.sqrt((1 / tz)**2 * w**2 +
                                              (o.d.d * 1000)**2 *
                                              (o.d.d * 1000)**2 *
                                              (1 / sz**2)**2 *
                                              (self.stdev_angle / RO_CC)**2)))
                        hd.appendChild(tmp)
                elif self.dimension == 3:
                    # 3d
                    if o.th is None:
                        th = 0
                    else:
                        th = o.th
                    if o.hz is not None:
                        tmp = doc.createElement('direction')
                        tmp.setAttribute('to', o.point_id)
                        tmp.setAttribute('val', str(o.hz.get_angle('GON')))
                        sta.appendChild(tmp)
                    if o.d is not None:
                        if o.d.mode == 'SD':
                            tmp = doc.createElement('s-distance')
                            tmp.setAttribute('val', str(o.d.d))
                            tmp.setAttribute('from_dh', str(ih))
                            tmp.setAttribute('to_dh', str(th))
                        else:
                            tmp = doc.createElement('distance')
                            tmp.setAttribute('val', str(o.d.d))
                        tmp.setAttribute('to', o.point_id)
                        sta.appendChild(tmp)
                    if o.v is not None:
                        tmp = doc.createElement('z-angle')
                        tmp.setAttribute('to', o.point_id)
                        tmp.setAttribute('val', str(o.v.get_angle('GON')))
                        tmp.setAttribute('from_dh', str(ih))
                        tmp.setAttribute('to_dh', str(th))
                        sta.appendChild(tmp)
                else:
                    # unknown dimension
                    return None
        # generate temp file name
        tmpf = QTemporaryFile(QDir.temp().absoluteFilePath('w'))
        tmpf.open(QIODevice.WriteOnly)
        tmpf.close()
        tmp_name = tmpf.fileName()
        f = QFile(tmp_name + '.xml')
        if f.open(QIODevice.WriteOnly):
            f.write(doc.toByteArray())
            f.close()

        # run gama-local
        if self.gama_prog is None:
            return None
        status = QProcess.execute(self.gama_prog, [
            tmp_name + '.xml', '--text', tmp_name + '.txt', '--xml',
            tmp_name + 'out.xml'
        ])
        if status != 0:
            return None

        xmlParser = QXmlSimpleReader()
        xmlFile = QFile(tmp_name + 'out.xml')
        xmlInputSource = QXmlInputSource(xmlFile)
        doc.setContent(xmlInputSource, xmlParser)

        f_txt = QFile(tmp_name + '.txt')
        f_txt.open(QIODevice.ReadOnly)
        res = f_txt.readAll().data()
        f_txt.close()

        # store coordinates
        adj_nodes = doc.elementsByTagName('adjusted')
        if adj_nodes.count() < 1:
            return res
        adj_node = adj_nodes.at(0)
        for i in range(len(adj_node.childNodes())):
            pp = adj_node.childNodes().at(i)
            if pp.nodeName() == 'point':
                for ii in range(len(pp.childNodes())):
                    ppp = pp.childNodes().at(ii)
                    if ppp.nodeName() == 'id':
                        p = Point(ppp.firstChild().nodeValue())
                    elif ppp.nodeName() == 'Y' or ppp.nodeName() == 'y':
                        p.e = float(ppp.firstChild().nodeValue())
                    elif ppp.nodeName() == 'X' or ppp.nodeName() == 'x':
                        p.n = float(ppp.firstChild().nodeValue())
                    elif ppp.nodeName() == 'Z' or ppp.nodeName() == 'z':
                        p.z = float(ppp.firstChild().nodeValue())
                ScPoint(p).store_coord(self.dimension)
        # remove input xml and output xml
        tmpf.remove()
        f_txt.remove()
        f.remove()
        xmlFile.remove()

        return res
Example #18
0
    def adjust(self):
        """ Export data to GNU Gama xml, adjust the network and read result

            :returns: result list of adjusment from GNU Gama
        """
        # fix = 0 free network
        fix = 0
        adj = 0
        for p, s in self.points:
            if s == 'FIX':
                fix += 1
            else:
                adj += 1
        if adj == 0 or len(self.observations) == 0:
            # no unknowns or observations
            return None
        
        doc = QDomDocument()
        doc.appendChild(doc.createComment('Gama XML created by Land Surveying plugin for QGIS'))
        gama_local = doc.createElement('gama-local')
        gama_local.setAttribute('version', '2.0')
        doc.appendChild(gama_local)
        network = doc.createElement('network')
        network.setAttribute('axes-xy', 'ne')
        network.setAttribute('angles', 'left-handed')
        gama_local.appendChild(network)
        description = doc.createElement('description')
        if self.dimension == 1:
            description.appendChild(doc.createTextNode('GNU Gama 1D network'))
        elif self.dimension == 2:
            description.appendChild(doc.createTextNode('GNU Gama 2D network'))
        elif self.dimension == 3:
            description.appendChild(doc.createTextNode('GNU Gama 3D network'))
        network.appendChild(description)
        parameters = doc.createElement('parameters')
        parameters.setAttribute('sigma-apr', '1')
        parameters.setAttribute('conf-pr', str(self.probability))
        parameters.setAttribute('tol-abs', '1000')
        parameters.setAttribute('sigma-act', 'aposteriori')
        parameters.setAttribute('update-constrained-coordinates', 'yes')
        network.appendChild(parameters)
        points_observations = doc.createElement('points-observations')
        points_observations.setAttribute('distance-stdev', str(self.stdev_dist) + ' ' + str(self.stdev_dist1)) 
        points_observations.setAttribute('direction-stdev', str(self.stdev_angle))
        points_observations.setAttribute('angle-stdev', str(math.sqrt(self.stdev_angle * 2)))
        points_observations.setAttribute('zenith-angle-stdev', str(self.stdev_angle))
        network.appendChild(points_observations)
        for p, s in self.points:
            if self.dimension == 1:
                tmp = doc.createElement('point')
                tmp.setAttribute('id', p.id)
                if p.z is not None:
                    tmp.setAttribute('z', str(p.z))
                if s == 'FIX':
                    tmp.setAttribute('fix', 'z')
                else:
                    if fix == 0:
                        tmp.setAttribute('adj', 'Z')
                    else:
                        tmp.setAttribute('adj', 'z')
                points_observations.appendChild(tmp)
            elif self.dimension == 2:
                tmp = doc.createElement('point')
                tmp.setAttribute('id', p.id)
                if p.e is not None and p.n is not None:
                    tmp.setAttribute('y', str(p.e))
                    tmp.setAttribute('x', str(p.n))
                if s == 'FIX':
                    tmp.setAttribute('fix', 'xy')
                else:
                    if fix == 0:
                        # free network
                        tmp.setAttribute('adj', 'XY')
                    else:
                        tmp.setAttribute('adj', 'xy')
                points_observations.appendChild(tmp)
            elif self.dimension == 3:
                tmp = doc.createElement('point')
                tmp.setAttribute('id', p.id)
                if p.e is not None and p.n is not None:
                    tmp.setAttribute('y', str(p.e))
                    tmp.setAttribute('x', str(p.n))
                if p.z is not None:
                    tmp.setAttribute('z', str(p.z))
                if s == 'FIX':
                    tmp.setAttribute('fix', 'xyz')
                else:
                    if fix == 0:
                        tmp.setAttribute('adj', 'XYZ')
                    else:
                        tmp.setAttribute('adj', 'xyz')
                points_observations.appendChild(tmp)
        for o in self.observations:
            if o.station == 'station':
                # station record
                sta = doc.createElement('obs')
                sta.setAttribute('from', o.point_id)
                if o.th is None:
                    ih = 0
                else:
                    ih = o.th
                points_observations.appendChild(sta)
            else:
                # observation
                if self.dimension == 2:
                    # horizontal network
                    if o.hz is not None:
                        tmp = doc.createElement('direction')
                        tmp.setAttribute('to', o.point_id)
                        tmp.setAttribute('val', str(o.hz.get_angle('GON')))
                        sta.appendChild(tmp)
                    if o.d is not None:
                        # horizontal distance
                        hd = o.horiz_dist()
                        if hd is not None:
                            tmp = doc.createElement('distance')
                            tmp.setAttribute('to', o.point_id)
                            tmp.setAttribute('val', str(hd))
                            sta.appendChild(tmp)
                elif self.dimension == 1:
                    # elevations only
                    pass
                elif self.dimension == 3:
                    # 3d
                    if o.th is None:
                        th = o.th
                    else:
                        th = 0
                    if o.hz is not None:
                        tmp = doc.createElement('direction')
                        tmp.setAttribute('to', o.point_id)
                        tmp.setAttribute('val', str(o.hz.get_angle('GON')))
                        sta.appendChild(tmp)
                    if o.d is not None:
                        if o.d.mode == 'SD':
                            tmp = doc.createElement('s-distance')
                            tmp.setAttribute('val', str(o.d.d))
                            tmp.setAttribute('from_dh', str(ih))
                            tmp.setAttribute('to_dh', str(th))
                        else:
                            tmp = doc.createElement('distance')
                            tmp.setAttribute('val', str(o.d.d))
                        tmp.setAttribute('to', o.point_id)
                        sta.appendChild(tmp)
                    if o.v is not None:
                        tmp = doc.createElement('z-angle')
                        tmp.setAttribute('to', o.point_id)
                        tmp.setAttribute('val', str(o.v.get_angle('GON')))
                        tmp.setAttribute('from_dh', str(ih))
                        tmp.setAttribute('to_dh', str(th))
                        sta.appendChild(tmp)
                else:
                    # unknown dimension
                    return None
        #print doc.toprettyxml(indent="  ")
        # generate temp file name
        tmpf = QTemporaryFile( QDir.temp().absoluteFilePath('w') )
        tmpf.open(QIODevice.WriteOnly)
        tmpf.close()
        tmp_name = tmpf.fileName()
        f = QFile(tmp_name + '.xml')
        if f.open(QIODevice.WriteOnly):
            f.write(doc.toByteArray())
            f.close()
       
        # run gama-local
        if self.gama_prog is None:
            return None
#        status = call([str(self.gama_prog), str(tmp_name) + '.xml', '--text',
#            str(tmp_name) + '.txt', '--xml', str(tmp_name) + 'out.xml'])
        status = QProcess.execute(self.gama_prog, [ tmp_name+'.xml', '--text',
            tmp_name+'.txt', '--xml', tmp_name+'out.xml'])
        if status != 0:
            return None
        
        xmlParser = QXmlSimpleReader()
        xmlFile = QFile(tmp_name + 'out.xml')
        xmlInputSource = QXmlInputSource(xmlFile)
        doc.setContent(xmlInputSource,xmlParser)
        
        f_txt = QFile(tmp_name + '.txt') 
        f_txt.open(QIODevice.ReadOnly)
        res = f_txt.readAll().data()
        f_txt.close()
        
        # store coordinates
        adj_nodes = doc.elementsByTagName('adjusted')
        if adj_nodes.count() < 1:
            return res
        adj_node = adj_nodes.at(0)
        for i in range(len(adj_node.childNodes())):
            pp = adj_node.childNodes().at(i)
            if pp.nodeName() == 'point':
                for ii in range(len(pp.childNodes())):
                    ppp = pp.childNodes().at(ii)
                    if ppp.nodeName() == 'id':
                        p = Point(ppp.firstChild().nodeValue())
                    elif ppp.nodeName() == 'Y' or ppp.nodeName() == 'y':
                        p.e = float(ppp.firstChild().nodeValue())
                    elif ppp.nodeName() == 'X' or ppp.nodeName() == 'x':
                        p.n = float(ppp.firstChild().nodeValue())
                    elif ppp.nodeName() == 'Z' or ppp.nodeName() == 'z':
                        p.z = float(ppp.firstChild().nodeValue())
                ScPoint(p).store_coord(self.dimension)
        # remove input xml and output xml
        tmpf.remove()
        f_txt.remove()
        f.remove()
        xmlFile.remove()
        
        return res
    def processFile(self,fullPath):
        fileName, fileExtension = os.path.splitext(fullPath)
        fileName = os.path.basename(fullPath)
        self.fileNames.append(fileName)
        if fileExtension == '.csv':
            delimiter = ','
        else:
            delimiter = None

        self.ui.statusbar.showMessage("processing: "+ fileName,2500)
        
        #wait here for the file to be completely written to disk and closed before trying to read it

        fi = QFileInfo(fullPath)
        while (not fi.isWritable()):
                time.sleep(0.001)
                fi.refresh()
        
        fp = open(fullPath, mode='r')
        fileBuffer = fp.read()
        fp.close()
        first10 = fileBuffer[0:10]
        nMcHeaderLines = 25 #number of header lines in mcgehee IV file format
        isMcFile = False #true if this is a McGehee iv file format
        if (not first10.__contains__('#')) and (first10.__contains__('/')) and (first10.__contains__('\t')):#the first line is not a comment
            #the first 8 chars do not contain comment symbol and do contain / and a tab, it's safe to assume mcgehee iv file format
            isMcFile = True
            #comment out the first 25 rows here
            fileBuffer = '#'+fileBuffer
            fileBuffer = fileBuffer.replace('\n', '\n#',nMcHeaderLines-1)

        splitBuffer = fileBuffer.splitlines(True)
        
        
        area = 1
        noArea = True
        vsTime = False #this is not an i,v vs t data file
        #extract header lines and search for area
        header = []
        for line in splitBuffer:
            if line.startswith('#'):
                header.append(line)
                if line.__contains__('Area'):
                    area = float(line.split(' ')[3])
                    noArea = False
                if line.__contains__('I&V vs t'):
                    if float(line.split(' ')[5]) == 1:
                        vsTime = True
            else:
                break
        
        outputScaleFactor = np.array(1000/area) #for converstion to [mA/cm^2]

        tempFile = QTemporaryFile()
        tempFile.open()
        tempFile.writeData(fileBuffer)
        tempFile.flush()

        #read in data
        try:
            data = np.loadtxt(str(tempFile.fileName()),delimiter=delimiter)
            VV = data[:,0]
            II = data[:,1]
            if vsTime:
                time = data[:,2]
        except:
            self.ui.statusbar.showMessage('Could not read' + fileName +'. Prepend # to all non-data lines and try again',2500)
            return
        tempFile.close()
        tempFile.remove()

        
        if isMcFile: #convert to amps
            II = II/1000*area

        if not vsTime:
            #sort data by ascending voltage
            newOrder = VV.argsort()
            VV=VV[newOrder]
            II=II[newOrder]
            #remove duplicate voltage entries
            VV, indices = np.unique(VV, return_index =True)
            II = II[indices]
        else:
            #sort data by ascending time
            newOrder = time.argsort()
            VV=VV[newOrder]
            II=II[newOrder]
            time=time[newOrder]
            time=time-time[0]#start time at t=0

        #catch and fix flipped current sign:
        if II[0] < II[-1]:
            II = II * -1       

        indexInQuad1 = np.logical_and(VV>0,II>0)
        if any(indexInQuad1): #enters statement if there is at least one datapoint in quadrant 1
            isDarkCurve = False
        else:
            self.ui.statusbar.showMessage("Dark curve detected",500)
            isDarkCurve = True
        
        #put items in table
        self.ui.tableWidget.insertRow(self.rows)
        for ii in range(len(self.cols)):
            self.ui.tableWidget.setItem(self.rows,ii,QTableWidgetItem())        
        
        if not vsTime:
            fitParams, fitCovariance, infodict, errmsg, ier = self.bestEffortFit(VV,II)
        
            #print errmsg
    
            I0_fit = fitParams[0]
            Iph_fit = fitParams[1]
            Rs_fit = fitParams[2]
            Rsh_fit = fitParams[3]
            n_fit = fitParams[4]
    
            
            #0 -> LS-straight line
            #1 -> cubic spline interpolant
            smoothingParameter = 1-2e-6
            iFitSpline = SmoothSpline(VV, II, p=smoothingParameter)
    
            def cellModel(voltageIn):
                #voltageIn = np.array(voltageIn)
                return vectorizedCurrent(voltageIn, I0_fit, Iph_fit, Rs_fit, Rsh_fit, n_fit)
    
            def invCellPowerSpline(voltageIn):
                if voltageIn < 0:
                    return 0
                else:
                    return -1*voltageIn*iFitSpline(voltageIn)
    
            def invCellPowerModel(voltageIn):
                if voltageIn < 0:
                    return 0
                else:
                    return -1*voltageIn*cellModel(voltageIn)
    
            if not isDarkCurve:
                VVq1 = VV[indexInQuad1]
                IIq1 = II[indexInQuad1]
                vMaxGuess = VVq1[np.array(VVq1*IIq1).argmax()]
                powerSearchResults = optimize.minimize(invCellPowerSpline,vMaxGuess)
                #catch a failed max power search:
                if not powerSearchResults.status == 0:
                    print "power search exit code = " + str(powerSearchResults.status)
                    print powerSearchResults.message
                    vMax = nan
                    iMax = nan
                    pMax = nan
                else:
                    vMax = powerSearchResults.x[0]
                    iMax = iFitSpline([vMax])[0]
                    pMax = vMax*iMax                
    
                #only do this stuff if the char eqn fit was good
                if ier < 5:
                    powerSearchResults_charEqn = optimize.minimize(invCellPowerModel,vMaxGuess)
                    #catch a failed max power search:
                    if not powerSearchResults_charEqn.status == 0:
                        print "power search exit code = " + str(powerSearchResults_charEqn.status)
                        print powerSearchResults_charEqn.message
                        vMax_charEqn = nan
                    else:
                        vMax_charEqn = powerSearchResults_charEqn.x[0]
                    #dude
                    try:
                        Voc_nn_charEqn=optimize.brentq(cellModel, VV[0], VV[-1])
                    except:
                        Voc_nn_charEqn = nan
                else:
                    Voc_nn_charEqn = nan
                    vMax_charEqn = nan
    
    
                try:
                    Voc_nn = optimize.brentq(iFitSpline, VV[0], VV[-1])
                except:
                    Voc_nn = nan
    
            else:
                Voc_nn = nan
                vMax = nan
                iMax = nan
                pMax = nan
                Voc_nn_charEqn = nan
                vMax_charEqn = nan
                iMax_charEqn = nan
                pMax_charEqn = nan
    
    
    
            if ier < 5:
                dontFindBounds = False
                iMax_charEqn = cellModel([vMax_charEqn])[0]
                pMax_charEqn = vMax_charEqn*iMax_charEqn
                Isc_nn_charEqn = cellModel(0)
                FF_charEqn = pMax_charEqn/(Voc_nn_charEqn*Isc_nn_charEqn)
            else:
                dontFindBounds = True
                iMax_charEqn = nan
                pMax_charEqn = nan
                Isc_nn_charEqn = nan
                FF_charEqn = nan
    
            #there is a maddening bug in SmoothingSpline: it can't evaluate 0 alone, so I have to do this:
            try:
                Isc_nn = iFitSpline([0,1e-55])[0]
            except:
                Isc_nn = nan
    
            FF = pMax/(Voc_nn*Isc_nn)
    
            if (ier != 7) and (ier != 6) and (not dontFindBounds) and (type(fitCovariance) is not float):
                #error estimation:
                alpha = 0.05 # 95% confidence interval = 100*(1-alpha)
    
                nn = len(VV)    # number of data points
                p = len(fitParams) # number of parameters
    
                dof = max(0, nn - p) # number of degrees of freedom
    
                # student-t value for the dof and confidence level
                tval = t.ppf(1.0-alpha/2., dof) 
    
                lowers = []
                uppers = []
                #calculate 95% confidence interval
                for a, p,var in zip(range(nn), fitParams, np.diag(fitCovariance)):
                    sigma = var**0.5
                    lower = p - sigma*tval
                    upper = p + sigma*tval
                    lowers.append(lower)
                    uppers.append(upper)
    
            else:
                uppers = [nan,nan,nan,nan,nan]
                lowers = [nan,nan,nan,nan,nan]
    
            plotPoints = 1000
            fitX = np.linspace(VV[0],VV[-1],plotPoints)
            
            if ier < 5:
                modelY = cellModel(fitX)*outputScaleFactor
            else:
                modelY = np.empty(plotPoints)*nan
            splineY = iFitSpline(fitX)*outputScaleFactor
            graphData = {'vsTime':vsTime,'origRow':self.rows,'fitX':fitX,'modelY':modelY,'splineY':splineY,'i':II*outputScaleFactor,'v':VV,'Voc':Voc_nn,'Isc':Isc_nn*outputScaleFactor,'Vmax':vMax,'Imax':iMax*outputScaleFactor}		
    
            #export button
            exportBtn = QPushButton(self.ui.tableWidget)
            exportBtn.setText('Export')
            exportBtn.clicked.connect(self.handleButton)
            self.ui.tableWidget.setCellWidget(self.rows,self.cols.keys().index('exportBtn'), exportBtn)
              
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('pce')).setData(Qt.DisplayRole,round(pMax/area*1e3,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('pce')).setToolTip(str(round(pMax_charEqn/area*1e3,3)))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('pmax')).setData(Qt.DisplayRole,round(pMax/area*1e3,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('pmax')).setToolTip(str(round(pMax_charEqn/area*1e3,3)))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('jsc')).setData(Qt.DisplayRole,round(Isc_nn/area*1e3,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('jsc')).setToolTip(str(round(Isc_nn_charEqn/area*1e3,3)))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('voc')).setData(Qt.DisplayRole,round(Voc_nn*1e3,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('voc')).setToolTip(str(round(Voc_nn_charEqn*1e3,3)))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('ff')).setData(Qt.DisplayRole,round(FF,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('ff')).setToolTip(str(round(FF_charEqn,3)))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('rs')).setData(Qt.DisplayRole,round(Rs_fit*area,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('rs')).setToolTip('[{0}  {1}]'.format(lowers[2]*area, uppers[2]*area))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('rsh')).setData(Qt.DisplayRole,round(Rsh_fit*area,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('rsh')).setToolTip('[{0}  {1}]'.format(lowers[3]*area, uppers[3]*area))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('jph')).setData(Qt.DisplayRole,round(Iph_fit/area*1e3,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('jph')).setToolTip('[{0}  {1}]'.format(lowers[1]/area*1e3, uppers[1]/area*1e3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('j0')).setData(Qt.DisplayRole,round(I0_fit/area*1e9,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('j0')).setToolTip('[{0}  {1}]'.format(lowers[0]/area*1e9, uppers[0]/area*1e9))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('n')).setData(Qt.DisplayRole,round(n_fit,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('n')).setToolTip('[{0}  {1}]'.format(lowers[4], uppers[4]))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('Vmax')).setData(Qt.DisplayRole,round(vMax*1e3,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('Vmax')).setToolTip(str(round(vMax_charEqn*1e3,3)))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('area')).setData(Qt.DisplayRole,round(area,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('pmax2')).setData(Qt.DisplayRole,round(pMax*1e3,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('pmax2')).setToolTip(str(round(pMax_charEqn*1e3,3)))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('isc')).setData(Qt.DisplayRole,round(Isc_nn*1e3,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('isc')).setToolTip(str(round(Isc_nn_charEqn*1e3,3)))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('iph')).setData(Qt.DisplayRole,round(Iph_fit*1e3,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('iph')).setToolTip('[{0}  {1}]'.format(lowers[1]*1e3, uppers[1]*1e3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('i0')).setData(Qt.DisplayRole,round(I0_fit*1e9,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('i0')).setToolTip('[{0}  {1}]'.format(lowers[0]*1e9, uppers[0]*1e9))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('rs2')).setData(Qt.DisplayRole,round(Rs_fit,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('rs2')).setToolTip('[{0}  {1}]'.format(lowers[2], uppers[2]))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('rsh2')).setData(Qt.DisplayRole,round(Rsh_fit,3))
            self.ui.tableWidget.item(self.rows,self.cols.keys().index('rsh2')).setToolTip('[{0}  {1}]'.format(lowers[3], uppers[3]))
        
        else:#vs time
            graphData = {'vsTime':vsTime,'origRow':self.rows,'time':time,'i':II*outputScaleFactor,'v':VV}

        #file name
        self.ui.tableWidget.item(self.rows,self.cols.keys().index('file')).setText(fileName)
        self.ui.tableWidget.item(self.rows,self.cols.keys().index('file')).setToolTip(''.join(header))          
        
        #plot button
        plotBtn = QPushButton(self.ui.tableWidget)
        plotBtn.setText('Plot')
        plotBtn.clicked.connect(self.handleButton)
        self.ui.tableWidget.setCellWidget(self.rows,self.cols.keys().index('plotBtn'), plotBtn)
        self.ui.tableWidget.item(self.rows,self.cols.keys().index('plotBtn')).setData(Qt.UserRole,graphData)
        
        self.ui.tableWidget.resizeColumnsToContents()
        self.rows = self.rows + 1
Example #20
0
def print_(doc, filename=None, widget=None):
    """Prints the popplerqt4.Poppler.Document.
    
    The filename is used in the dialog and print job name.
    If the filename is not given, it defaults to a translation of "PDF Document".
    The widget is a widget to use as parent for the print dialog etc.
    
    """
    cmd = fileprinter.lprCommand()
    if not cmd and QMessageBox.information(widget, _("Warning"), _(
        "No print command to print a PostScript file could be found.\n\n"
        "Therefore the document will be printed using raster images at {resolution} DPI. "
        "It is recommended to print using a dedicated PDF viewer.\n\n"
        "Do you want to continue?").format(resolution=300),
        QMessageBox.Yes | QMessageBox.No) != QMessageBox.Yes:
        return # cancelled
        
    filename = os.path.basename(filename) if filename else _("PDF Document")
    
    printer = QPrinter()
    printer.setDocName(filename)
    
    dlg = QPrintDialog(printer, widget)
    dlg.setMinMax(1, doc.numPages())
    dlg.setOption(QPrintDialog.PrintToFile, False)
    dlg.setWindowTitle(app.caption(_("Print {filename}").format(filename=filename)))
    
    result = dlg.exec_()
    if widget:
        dlg.deleteLater() # because it has a parent
    if not result:
        return # cancelled
    
    if cmd:
        # make a PostScript file with the desired paper size
        ps = QTemporaryFile()
        if ps.open() and qpopplerview.printer.psfile(doc, printer, ps):
            ps.close()
            # let all converted pages print
            printer.setPrintRange(QPrinter.AllPages)
            command = fileprinter.printCommand(cmd, printer, ps.fileName())
            if not subprocess.call(command):
                return # success!
        QMessageBox.warning(widget, _("Printing Error"),
            _("Could not send the document to the printer."))
    else:
        # Fall back printing of rendered raster images.
        # It is unsure if the Poppler ArthurBackend ever will be ready for
        # good rendering directly to a painter, so we'll fall back to using
        # 300DPI raster images.
        
        p = Printer()
        p.setDocument(doc)
        p.setPrinter(printer)
        p.setResolution(300)
        
        d = QProgressDialog()
        d.setModal(True)
        d.setMinimumDuration(0)
        d.setRange(0, len(p.pageList()) + 1)
        d.canceled.connect(p.abort)
        
        def progress(num, total, page):
            d.setValue(num)
            d.setLabelText(_("Printing page {page} ({num} of {total})...").format(
                page=page, num=num, total=total))
                
        def finished():
            p.deleteLater()
            d.deleteLater()
            d.hide()
            if not p.success and not p.aborted():
                QMessageBox.warning(widget, _("Printing Error"),
                    _("Could not send the document to the printer."))
            
        p.finished.connect(finished)
        p.printing.connect(progress)
        p.start()
Example #21
0
    def _handle_SEND(self, chunk):
        if chunk.size == 0:
            # keep-alive
            self.msrp_session.send_report(chunk, 200, 'OK')
            return

        if chunk.content_type not in self.accept_types:
            self.msrp_session.send_report(chunk, 415, 'Invalid content-type')
            return

        if chunk.content_type == 'application/x-webodf-genesisdocument':
            if self.receivedGenesisFile is None:
                print "------- creating file for genesis"
                self.receivedGenesisFile = QTemporaryFile()
                self.receivedGenesisFile.open()

            fro, to, total = chunk.byte_range
            print "------- got x-webodf-genesisdocument - fro, to, total:", fro, to, total
            self.receivedGenesisFile.seek(fro-1)
            self.receivedGenesisFile.write(chunk.data)

            if fro+chunk.size-1 == total:
                print "------- got x-webodf-genesisdocument - complete, size:", fro+chunk.size-1
                self.receivedGenesisFile.flush()
                ndata = NotificationData(filename = self.receivedGenesisFile.fileName())
                self.notification_center.post_notification('DocumentSharingStreamGenesisDocument', sender = self, data = ndata)

            return

        self.msrp_session.send_report(chunk, 200, 'OK')

        message = cjson.decode(chunk.data)
        messageType = message['type']
        messageBody = message['body']

        print "------- got x-webodf-documentsharing:", messageType

        if messageType == 'InitRequest':
            ndata = NotificationData(content = messageBody)
            self.notification_center.post_notification('DocumentSharingStreamInitRequest', sender = self, data = ndata)
            return

        if messageType == 'InitRequestReply':
            ndata = NotificationData(content = messageBody)
            self.notification_center.post_notification('DocumentSharingStreamInitRequestReply', sender = self, data = ndata)
            return

        if messageType == 'ReplayRequest':
            ndata = NotificationData(content = messageBody)
            self.notification_center.post_notification('DocumentSharingStreamReplayRequest', sender = self, data = ndata)
            return

        if messageType == 'ReplayRequestReply':
            ndata = NotificationData(content = messageBody)
            self.notification_center.post_notification('DocumentSharingStreamReplayRequestReply', sender = self, data = ndata)
            return

        if messageType == 'error':
            ndata = NotificationData(content = messageBody['error'])
            self.notification_center.post_notification('DocumentSharingStreamError', sender = self, data = ndata)
            return

        if messageType == 'NewOps':
            ndata = NotificationData(content = messageBody, content_type = chunk.content_type)
            self.notification_center.post_notification('DocumentSharingStreamNewOps', sender = self, data = ndata)

        if messageType == 'NewOpsReply':
            ndata = NotificationData(content = messageBody)
            self.notification_center.post_notification('DocumentSharingStreamNewOpsReply', sender = self, data = ndata)
Example #22
0
class DocumentSharingStream(MSRPStreamBase):
    type = 'document-sharing'
    priority = 1
    msrp_session_class = MSRPSession

    media_type = 'application'
    accept_types = ['application/x-webodf-documentsharing', 'application/x-webodf-genesisdocument']
    accept_wrapped_types = None

    def __init__(self, filename = None, document_title = None, session_uuid = None, continue_session = None):
        super(DocumentSharingStream, self).__init__()
        self.notification_center = NotificationCenter()
        self.mode = continue_session if continue_session is not None else 'guest' if filename is None else 'host'
        self.filename = filename
        if session_uuid is None:
            session_uuid =  str(uuid.uuid4())
        self.session_uuid = session_uuid
        self.continue_session = continue_session
        self.document_title = document_title if document_title is not None else os.path.basename(filename) if filename is not None else None
        self.receivedGenesisFile = None
        self.genesisFileSender = None
        print "NEW DocumentSharingStream - filename: ", self.filename, "session_uuid: ", self.session_uuid, "continue_session: ", self.continue_session

    @classmethod
    def new_from_sdp(cls, session, remote_sdp, stream_index):
        remote_stream = remote_sdp.media[stream_index]
        if remote_stream.media != 'application':
            raise UnknownStreamError

        remote_accept_types = remote_stream.attributes.getfirst('accept-types', None)
        if remote_accept_types is None:
            raise InvalidStreamError("remote SDP media does not have 'accept-types' attribute")
        if 'application/x-webodf-documentsharing' not in remote_accept_types.split(): # TODO: check both needed mimetypes
            raise InvalidStreamError("no compatible media types found")

        expected_transport = 'TCP/TLS/MSRP' if session.account.msrp.transport=='tls' else 'TCP/MSRP'
        if remote_stream.transport != expected_transport:
            raise InvalidStreamError("expected %s transport in chat stream, got %s" % (expected_transport, remote_stream.transport))
        if remote_stream.formats != ['*']:
            raise InvalidStreamError("wrong format list specified")

        document_title = remote_stream.attributes.getfirst('document-title', None)
        session_uuid = remote_stream.attributes.getfirst('docsession-uuid', None)
        continue_session = remote_stream.attributes.getfirst('docsession-continue', None)
        # revert on reception side
        if continue_session == "host":
            continue_session = "guest"
        elif continue_session == "guest":
            continue_session = "host"

        return cls(filename = None, document_title = document_title, session_uuid = session_uuid, continue_session = continue_session)

    def _create_local_media(self, uri_path):
        local_media = super(DocumentSharingStream, self)._create_local_media(uri_path)
        # TODO: .encode('utf8') only works with filenames with latin1 chars, investigate proper fix
        local_media.attributes.append(SDPAttribute('document-title', self.document_title.encode('utf8')))
        local_media.attributes.append(SDPAttribute('docsession-uuid', self.session_uuid))
        if self.continue_session is not None:
            local_media.attributes.append(SDPAttribute('docsession-continue', self.continue_session))
        return local_media

    def _handle_SEND(self, chunk):
        if chunk.size == 0:
            # keep-alive
            self.msrp_session.send_report(chunk, 200, 'OK')
            return

        if chunk.content_type not in self.accept_types:
            self.msrp_session.send_report(chunk, 415, 'Invalid content-type')
            return

        if chunk.content_type == 'application/x-webodf-genesisdocument':
            if self.receivedGenesisFile is None:
                print "------- creating file for genesis"
                self.receivedGenesisFile = QTemporaryFile()
                self.receivedGenesisFile.open()

            fro, to, total = chunk.byte_range
            print "------- got x-webodf-genesisdocument - fro, to, total:", fro, to, total
            self.receivedGenesisFile.seek(fro-1)
            self.receivedGenesisFile.write(chunk.data)

            if fro+chunk.size-1 == total:
                print "------- got x-webodf-genesisdocument - complete, size:", fro+chunk.size-1
                self.receivedGenesisFile.flush()
                ndata = NotificationData(filename = self.receivedGenesisFile.fileName())
                self.notification_center.post_notification('DocumentSharingStreamGenesisDocument', sender = self, data = ndata)

            return

        self.msrp_session.send_report(chunk, 200, 'OK')

        message = cjson.decode(chunk.data)
        messageType = message['type']
        messageBody = message['body']

        print "------- got x-webodf-documentsharing:", messageType

        if messageType == 'InitRequest':
            ndata = NotificationData(content = messageBody)
            self.notification_center.post_notification('DocumentSharingStreamInitRequest', sender = self, data = ndata)
            return

        if messageType == 'InitRequestReply':
            ndata = NotificationData(content = messageBody)
            self.notification_center.post_notification('DocumentSharingStreamInitRequestReply', sender = self, data = ndata)
            return

        if messageType == 'ReplayRequest':
            ndata = NotificationData(content = messageBody)
            self.notification_center.post_notification('DocumentSharingStreamReplayRequest', sender = self, data = ndata)
            return

        if messageType == 'ReplayRequestReply':
            ndata = NotificationData(content = messageBody)
            self.notification_center.post_notification('DocumentSharingStreamReplayRequestReply', sender = self, data = ndata)
            return

        if messageType == 'error':
            ndata = NotificationData(content = messageBody['error'])
            self.notification_center.post_notification('DocumentSharingStreamError', sender = self, data = ndata)
            return

        if messageType == 'NewOps':
            ndata = NotificationData(content = messageBody, content_type = chunk.content_type)
            self.notification_center.post_notification('DocumentSharingStreamNewOps', sender = self, data = ndata)

        if messageType == 'NewOpsReply':
            ndata = NotificationData(content = messageBody)
            self.notification_center.post_notification('DocumentSharingStreamNewOpsReply', sender = self, data = ndata)

    def _handle_REPORT(self, chunk):
        if self.genesisFileSender:
            self.genesisFileSender.handleReportChunk(chunk)

    def _dropGenesisFileSender(self):
        # thanks for all the file, and bye
        self.notification_center.remove_observer(self, sender=self.genesisFileSender)
        self.genesisFileSender = None

    @run_in_green_thread
    def sendMessage(self, messageType, messageBody):
        print "------- sendMessage:", messageType
        if self.msrp_session:
            message = {
                'type': messageType,
                'body': messageBody
            }

            message = cjson.encode(message)
            self.msrp_session.send_message(message, 'application/x-webodf-documentsharing')

    @run_in_green_thread
    def sendGenesisFile(self, filename):
        print "------- sendGenesisFile:", filename
        if self.msrp_session:
            self.genesisFileSender = GenesisFileSender(filename, self.msrp_session, self.msrp)
            self.notification_center.add_observer(self, sender=self.genesisFileSender)
            self.genesisFileSender.startFileSending()

    def _NH_MediaStreamDidStart(self, notification):
        self.notification_center.post_notification('DocumentSharingStreamConnected', sender = self)

    def _NH_MediaStreamDidFail(self, notification):
        if self.genesisFileSender:
            self.genesisFileSender.end()
            self._dropGenesisFileSender()
        self.notification_center.post_notification('DocumentSharingStreamDisconnected', sender = self)

    def _NH_MediaStreamDidEnd(self, notification):
        if self.genesisFileSender:
            self.genesisFileSender.end()
            self._dropGenesisFileSender()
        self.notification_center.post_notification('DocumentSharingStreamDisconnected', sender = self)

    @run_in_twisted_thread
    def _NH_FileTransferHandlerDidEnd(self, notification):
        self._dropGenesisFileSender()

    @run_in_twisted_thread
    def _NH_FileTransferHandlerError(self, notification):
        self._failure_reason = notification.data.error
        notification.center.post_notification('MediaStreamDidFail', sender=self, data=NotificationData(context='transferring', reason=self._failure_reason))
Example #23
0
    def merge(self):
        """ merge current view with a previously-saved M2T """

        # first we get the old m2t path
        oldPath = QFileDialog.getOpenFileName(
            self.ui.menubar, "Select M2T file to merge", expanduser("~"), "M2T files (*.m2t);;All Files(*.*)"
        )
        if oldPath.isEmpty():
            return  # cancel action

        # then we save a copy of the current view, so that we have a m2t
        tempFile = QTemporaryFile()
        tempFile.setAutoRemove(False)
        tempFile.open()
        tempFile.close()
        self._writeM2T(tempFile.fileName())

        # then we merge
        old = etree.parse(str(oldPath))
        new = etree.parse(str(tempFile.fileName()))
        oldMap = {}

        # get statuses in the old file
        for node in old.findall(".//node"):
            if node.attrib.has_key("m2t_checked"):
                checked = node.attrib["m2t_checked"]
                oldMap[node.attrib["ID"]] = checked

        # set statuses in new file
        for node in new.findall(".//node"):
            nodeId = node.attrib["ID"]
            if oldMap.has_key(nodeId):
                node.attrib["m2t_checked"] = oldMap[nodeId]

        # write down the result
        new.write(tempFile.fileName(), "utf-8")

        # reload the view
        self.ui.treeWidget.clear()
        self._parseM2T(str(tempFile.fileName()))
        self.ui.actionSave.setDisabled(False)

        tempFile.remove()
Example #24
0
    def parse_metadata(self):
        """Parse str metadata to collection dict."""
        if not self.metadata:
            msg = 'The metadata content is None'
            LOGGER.error(msg)
            raise MetadataError(msg)

        collections = []
        metadata_file = QTemporaryFile()
        if metadata_file.open():
            metadata_file.write(self.metadata)
            metadata_file.close()

        try:
            parser = SafeConfigParser()
            metadata_path = metadata_file.fileName()
            with codecs.open(metadata_path, 'r', encoding='utf-8') as f:
                parser.readfp(f)
            collections_str = parser.get('general', 'collections')
        except Exception as e:
            raise MetadataError('Error parsing metadata: %s' % e)

        collection_list = [
            collection.strip() for collection in collections_str.split(',')
        ]
        # Read all the collections
        for collection in collection_list:
            # Parse the version
            qgis_min_version = parser.has_option(
                collection, 'qgis_minimum_version') and parser.get(
                    collection, 'qgis_minimum_version') or None
            qgis_max_version = parser.has_option(
                collection, 'qgis_maximum_version') and parser.get(
                    collection, 'qgis_maximum_version') or None
            if not qgis_min_version:
                qgis_min_version = '2.0'
            if not qgis_max_version:
                qgis_max_version = '3.99'
            if not isCompatible(QGis.QGIS_VERSION, qgis_min_version,
                                qgis_max_version):
                LOGGER.info(
                    'Collection %s is not compatible with current QGIS '
                    'version. QGIS ver:%s, QGIS min ver:%s, QGIS max ver: '
                    '%s' % (collection, QGis.QGIS_VERSION, qgis_min_version,
                            qgis_max_version))
                break

            # Collection is compatible, continue parsing
            try:
                # Parse general information
                author = parser.get(collection, 'author')
                email = parser.get(collection, 'email')
                name = parser.get(collection, 'name')
                tags = parser.get(collection, 'tags')
                description = parser.get(collection, 'description')

                # Parse licensing stuffs
                license_str = parser.has_option(
                    collection, 'license') and parser.get(
                        collection, 'license') or None
                license_path = parser.has_option(
                    collection, 'license_file') and parser.get(
                        collection, 'license_file') or None
                license_url = None
                if license_path:
                    license_url = self.collection_file_url(
                        collection, license_path.strip())

                # Parse the preview urls
                preview_str = parser.has_option(collection, 'preview') and \
                    parser.get(collection, 'preview') or ''
                preview_list = []
                for preview in preview_str.split(','):
                    if preview.strip() != '':
                        preview_url = self.collection_file_url(
                            collection, preview.strip())
                        preview_list.append(preview_url)

            except Exception as e:
                raise MetadataError('Error parsing metadata: %s' % e)

            collection_dict = {
                'register_name': collection,
                'author': author,
                'author_email': email,
                'repository_url': self.url,
                'status': COLLECTION_NOT_INSTALLED_STATUS,
                'name': name,
                'tags': tags,
                'description': description,
                'qgis_min_version': qgis_min_version,
                'qgis_max_version': qgis_max_version,
                'preview': preview_list,
                'license': license_str,
                'license_url': license_url
            }
            collections.append(collection_dict)

        return collections
Example #25
0
def print_(doc, filename=None, widget=None):
    """Prints the popplerqt4.Poppler.Document.
    
    The filename is used in the dialog and print job name.
    If the filename is not given, it defaults to a translation of "PDF Document".
    The widget is a widget to use as parent for the print dialog etc.
    
    """
    # Decide how we will print.
    # on Windows and Mac OS X a print command must be specified, otherwise
    # we'll use raster printing
    s = QSettings()
    s.beginGroup("helper_applications")
    cmd = s.value("printcommand", "", type(""))
    use_dialog = s.value("printcommand/dialog", False, bool)
    resolution = s.value("printcommand/dpi", 300, int)
    linux_lpr = False
    
    if os.name != 'nt' and not sys.platform.startswith('darwin'):
        # we're probably on Linux
        if not cmd:
            cmd = fileprinter.lprCommand()
            if cmd:
                linux_lpr = True
        elif cmd.split('/')[-1] in fileprinter.lpr_commands:
            linux_lpr = True

    print_file = filename
    title = os.path.basename(filename) if filename else _("PDF Document")
    printer = QPrinter()
    printer.setDocName(title)
    printer.setPrintRange(QPrinter.AllPages)
    
    if linux_lpr or use_dialog or not cmd:
        dlg = QPrintDialog(printer, widget)
        dlg.setMinMax(1, doc.numPages())
        dlg.setOption(QPrintDialog.PrintToFile, False)
        dlg.setWindowTitle(app.caption(_("Print {filename}").format(filename=title)))
        
        result = dlg.exec_()
        if widget:
            dlg.deleteLater() # because it has a parent
        if not result:
            return # cancelled
    
    if linux_lpr or '$ps' in cmd:
        # make a PostScript file with the desired paper size
        ps = QTemporaryFile()
        if ps.open() and qpopplerview.printer.psfile(doc, printer, ps):
            ps.close()
            print_file = ps.fileName()
    elif cmd:
        if printer.printRange() != QPrinter.AllPages:
            cmd = None # we can't cut out pages from a PDF file
        elif '$pdf' not in cmd:
            cmd += ' $pdf'
    
    command = []
    if linux_lpr:
        # let all converted pages print
        printer.setPrintRange(QPrinter.AllPages)
        command = fileprinter.printCommand(cmd, printer, ps.fileName())
    elif cmd and print_file:
        for arg in helpers.shell_split(cmd):
            if arg in ('$ps', '$pdf'):
                command.append(print_file)
            else:
                arg = arg.replace('$printer', printer.printerName())
                command.append(arg)
    if command:
        if subprocess.call(command):
            QMessageBox.warning(widget, _("Printing Error"),
                _("Could not send the document to the printer."))
        return
    else:
        # Fall back printing of rendered raster images.
        # It is unsure if the Poppler ArthurBackend ever will be ready for
        # good rendering directly to a painter, so we'll fall back to using
        # raster images.
        
        p = Printer()
        p.setDocument(doc)
        p.setPrinter(printer)
        p.setResolution(resolution)
        
        d = QProgressDialog()
        d.setModal(True)
        d.setMinimumDuration(0)
        d.setRange(0, len(p.pageList()) + 1)
        d.canceled.connect(p.abort)
        
        def progress(num, total, page):
            d.setValue(num)
            d.setLabelText(_("Printing page {page} ({num} of {total})...").format(
                page=page, num=num, total=total))
                
        def finished():
            p.deleteLater()
            d.deleteLater()
            d.hide()
            if not p.success and not p.aborted():
                QMessageBox.warning(widget, _("Printing Error"),
                    _("Could not send the document to the printer."))
            
        p.finished.connect(finished)
        p.printing.connect(progress)
        p.start()
Example #26
0
def print_(doc, filename=None, widget=None):
    """Prints the popplerqt4.Poppler.Document.
    
    The filename is used in the dialog and print job name.
    If the filename is not given, it defaults to a translation of "PDF Document".
    The widget is a widget to use as parent for the print dialog etc.
    
    """
    # Decide how we will print.
    # on Windows and Mac OS X a print command must be specified, otherwise
    # we'll use raster printing
    s = QSettings()
    s.beginGroup("helper_applications")
    cmd = s.value("printcommand", "", type(""))
    use_dialog = s.value("printcommand/dialog", False, bool)
    resolution = s.value("printcommand/dpi", 300, int)
    linux_lpr = False

    if os.name != 'nt' and not sys.platform.startswith('darwin'):
        # we're probably on Linux
        if not cmd:
            cmd = fileprinter.lprCommand()
            if cmd:
                linux_lpr = True
        elif cmd.split('/')[-1] in fileprinter.lpr_commands:
            linux_lpr = True

    print_file = filename
    title = os.path.basename(filename) if filename else _("PDF Document")
    printer = QPrinter()
    printer.setDocName(title)
    printer.setPrintRange(QPrinter.AllPages)

    if linux_lpr or use_dialog or not cmd:
        dlg = QPrintDialog(printer, widget)
        dlg.setMinMax(1, doc.numPages())
        dlg.setOption(QPrintDialog.PrintToFile, False)
        dlg.setWindowTitle(
            app.caption(_("Print {filename}").format(filename=title)))

        result = dlg.exec_()
        if widget:
            dlg.deleteLater()  # because it has a parent
        if not result:
            return  # cancelled

    if linux_lpr or '$ps' in cmd:
        # make a PostScript file with the desired paper size
        ps = QTemporaryFile()
        if ps.open() and qpopplerview.printer.psfile(doc, printer, ps):
            ps.close()
            print_file = ps.fileName()
    elif cmd:
        if printer.printRange() != QPrinter.AllPages:
            cmd = None  # we can't cut out pages from a PDF file
        elif '$pdf' not in cmd:
            cmd += ' $pdf'

    command = []
    if linux_lpr:
        # let all converted pages print
        printer.setPrintRange(QPrinter.AllPages)
        command = fileprinter.printCommand(cmd, printer, ps.fileName())
    elif cmd and print_file:
        for arg in helpers.shell_split(cmd):
            if arg in ('$ps', '$pdf'):
                command.append(print_file)
            else:
                arg = arg.replace('$printer', printer.printerName())
                command.append(arg)
    if command:
        if subprocess.call(command):
            QMessageBox.warning(
                widget, _("Printing Error"),
                _("Could not send the document to the printer."))
        return
    else:
        # Fall back printing of rendered raster images.
        # It is unsure if the Poppler ArthurBackend ever will be ready for
        # good rendering directly to a painter, so we'll fall back to using
        # raster images.

        p = Printer()
        p.setDocument(doc)
        p.setPrinter(printer)
        p.setResolution(resolution)

        d = QProgressDialog()
        d.setModal(True)
        d.setMinimumDuration(0)
        d.setRange(0, len(p.pageList()) + 1)
        d.canceled.connect(p.abort)

        def progress(num, total, page):
            d.setValue(num)
            d.setLabelText(
                _("Printing page {page} ({num} of {total})...").format(
                    page=page, num=num, total=total))

        def finished():
            p.deleteLater()
            d.deleteLater()
            d.hide()
            if not p.success and not p.aborted():
                QMessageBox.warning(
                    widget, _("Printing Error"),
                    _("Could not send the document to the printer."))

        p.finished.connect(finished)
        p.printing.connect(progress)
        p.start()