← Back to team overview

zim-wiki team mailing list archive

Re: writing plugins

 


On 02/10/2011 10:07 AM, smu@xxxxxxx wrote:
Hi alessandro,

you could post the code of your plugin, then it would be easier to
identify your bug. It sound as if a File object is expected somewhere
but None is returned and the basename function fails.

Does the preview function display your plot correctly? I get the same
exception (with the gnu_r_plugin), when I enter incorrect R code, press
OK and close the following 'An error occured...' dialog with yes.

best regards,
  stefan

On Thu, Feb 10, 2011 at 09:13:00AM +0100, Alessandro Magni wrote:
hi people,
it is a bit of time since I'm thinking about trying to write some simple
plugin - to start with, I wanted to try with an<insert GNUplot plot>,
since I prefer GNUplot in place of R.
I read in the manual to check the HACKING directory, and I tried to
follow the code in gnu_r_ploteditor.py to take it as example.
I don't know if it is me, but I probably lack a good understanding of
the basics.
I have in gnuplot_ploteditor.py three classes (InsertGNUPlotPlugin,
InsertPlotDialog, PlotGenerator), I have a template _gnuplot.gnu in
place, and I have basically changed gnu_r_ploteditor.py as less as
possible, just to call gnuplot instead of R.
In Zim I have now a Insert->GNUplot option, which calls up an insert
window. But any code I use inside it returns a "Looks like you found a
bug" window, telling me "AttributeError: 'NoneType' object has no
attribute 'basename' "

Of course you have better things to do than lead me by the hand thru
Python development, but - since the HACKING folder is a bit lacking -
could you tell me exactly what is expected from a zim plugin, in terms
of defined classes etc?
Also, what you do suggest as tricks to debug it?

Thank you!


alessandro


--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/  Dr.Alessandro Magni
\        Electromagnetics Division
/        INRiM Strada delle Cacce 91, 10135 Torino (ITALIA)
\        Email magni@xxxxxxxx
/        Tel: 0039-011-3919821  Fax: 0039-011-3919834
\        URL http://www.inrim.it/~magni
/ Our business in life is not to succeed but to continue to fail
\ in high spirits.  -- Robert Louis Stevenson
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


_______________________________________________
Mailing list: https://launchpad.net/~zim-wiki
Post to     : zim-wiki@xxxxxxxxxxxxxxxxxxx
Unsubscribe : https://launchpad.net/~zim-wiki
More help   : https://help.launchpad.net/ListHelp



well, I'm glad you asked!
Here it is ...

# -*- coding: utf-8 -*-
#
# gnuplot_ploteditor.py
#
# This is a plugin for Zim, which allows inserting GNUplot scripts to
# have Zim generate plots from them.
#
# Author: Alessandro Magni <magni@xxxxxxxx>
# Date: 2010-10-12
# Copyright (c) 2010, released under the GNU GPL v2 or higher
#
#

import gtk
import glob

from zim.fs import File, TmpFile
from zim.plugins import PluginClass
from zim.config import data_file
from zim.templates import GenericTemplate
from zim.applications import Application
from zim.gui.imagegeneratordialog import ImageGeneratorDialog

# TODO put these commands in preferences
gnuplot_cmd = ('gnuplot',)

ui_xml = '''
<ui>
<menubar name='menubar'>
<menu action='insert_menu'>
<placeholder name='plugin_items'>
<menuitem action='insert_gnuplot'/>
</placeholder>
</menu>
</menubar>
</ui>
'''

ui_actions = (
    # name, stock id, label, accelerator, tooltip, read only
    ('insert_gnuplot', None, _('GNUPlot...'), '', '', False),
        # T: menu item for insert plot plugin
)


class InsertGNUPlotPlugin(PluginClass):

    plugin_info = {
        'name': _('Insert GNUPlot'), # T: plugin name
        'description': _('''\
This plugin provides a plot editor for zim based on GNUPlot.
'''), # T: plugin description
        'help': ':Plugins:GNUPlot Editor',
        'author': 'Alessandro Magni',
    }

    @classmethod
    def check_dependencies(klass):
        return [('GNUPlot',Application(gnuplot_cmd).tryexec())]

    def __init__(self, ui):
        PluginClass.__init__(self, ui)
        if self.ui.ui_type == 'gtk':
            self.ui.add_actions(ui_actions, self)
            self.ui.add_ui(ui_xml, self)
            self.register_image_generator_plugin('gnuplot')

    def insert_gnuplot(self):
        dialog = InsertPlotDialog.unique(self, self.ui)
        dialog.show_all()

    def edit_object(self, buffer, iter, image):
        dialog = InsertPlotDialog(self.ui, image=image)
        dialog.show_all()

    def do_populate_popup(self, menu, buffer, iter, image):
        menu.prepend(gtk.SeparatorMenuItem())

item = gtk.MenuItem(_('_Edit GNUPlot')) # T: menu item in context menu
        item.connect('activate',
            lambda o: self.edit_object(buffer, iter, image))
        menu.prepend(item)



class InsertPlotDialog(ImageGeneratorDialog):

    def __init__(self, ui, image=None):
        generator = PlotGenerator()
ImageGeneratorDialog.__init__(self, ui, _('GNUPlot'), # T: dialog title
            generator, image, help=':Plugins:GNUPlot Editor' )


class PlotGenerator(object):

    # TODO: generic base class for image generators

    type = 'gnuplot'
    basename = 'gnuplot.gnu'

    def __init__(self):
        file = data_file('templates/_gnuplot.gnu')
        assert file, 'BUG: could not find templates/_gnuplot.gnu'
        self.template = GenericTemplate(file.readlines(), name=file)
        self.plotscriptfile = TmpFile('gnuplot.gnu')

    def generate_image(self, text):
        if isinstance(text, basestring):
            text = text.splitlines(True)

        plotscriptfile = self.plotscriptfile

        pngfile = File(plotscriptfile.path[:-4] + '.png')
logfile = File(plotscriptfile.path[:-4] + '.log') # len('.gnu') == 4

        plot_script = "".join(text)

template_vars = { # they go in /usr/share/zim/templates/_gnuplot.gnu
            'gnuplot_script':        plot_script,
            'png_fname':            pngfile,
        }

        # Write to tmp file usign the template for the header / footer
        plotscriptfile.writelines(
            self.template.process(template_vars)
        )
        #print '>>>%s<<<' % plotscriptfile.read()

        # Call GNUPlot
        try:
            gnu_gp = Application(gnuplot_cmd)
gnu_gp.run(args=( plotscriptfile.basename, ), cwd=plotscriptfile.dir)
                            # you call it as % gnuplot output.plt

        except:
            # log should have details of failure
            return None, logfile

        return pngfile, logfile

    def cleanup(self):
        path = self.plotscriptfile.path
        for path in glob.glob(path[:-2]+'.*'):
            File(path).remove()











--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/  Dr.Alessandro Magni
\        Electromagnetics Division
/        INRiM Strada delle Cacce 91, 10135 Torino (ITALIA)
\        Email magni@xxxxxxxx
/        Tel: 0039-011-3919821  Fax: 0039-011-3919834
\        URL http://www.inrim.it/~magni
/ Our business in life is not to succeed but to continue to fail
\ in high spirits.  -- Robert Louis Stevenson
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~




Follow ups

References