User:Tamas Bates/NetProto

From XPUB & Lens-Based wiki

RSS Feed plugin for Inkscape

http://pzwart3.wdka.hro.nl/mediawiki/images/9/9a/RssFeedImporter.zip

A small plugin for Inkscape which will download and insert the content from an RSS feed into your SVG file. Supports some basic options to allow a user to customize the content pulled from the feed, determine whether entries should be added to their own layer groups and can attach the feed's content to a path selected by the user. Requires FeedParser.

To install: extract the contents of the zip into Inkscape's /share/extensions directory.

To-Do:
  • Better error handling and friendly error messages
  • More formatting and layout options (maybe some simple template support?)
#!/usr/bin/env python

import sys, os
if os.path.exists('/usr/share/inkscape/extensions'):
    sys.path.append('/usr/share/inkscape/extensions') # or another path, as necessary
from simplestyle import *
import random, math, uuid
import inkex
import feedparser

lineSpacing = 20 # default distance between subsequent lines of text

# attaches the given text element on the given path
def putTextOnPath(text, path):
    pathID = path.attrib['id']
    textPath = inkex.etree.SubElement(text, 'textPath')
    textPath.set(inkex.addNS('href', 'xlink'), '#%s' % (pathID))
    textSpan = inkex.etree.SubElement(textPath, 'tspan')
    textSpan.text = text.text
    text.text = ''

class RssFeedReaderEffect(inkex.Effect):
    def __init__(self):
        inkex.Effect.__init__(self)
        self.OptionParser.add_option("--tab", action="store", type="string", 
            dest="tab", default="object") 
        self.OptionParser.add_option('-u', '--url', action='store', type='string',
            dest='url', default='', help='You must specify a feed URL to pull from!')
        self.OptionParser.add_option('-n', '--nentries', action='store', type='int',
            dest='maxEntries', default=10)
        self.OptionParser.add_option('-t', '--printtitle', action='store', default='true')
        self.OptionParser.add_option('-a', '--printauthor', action='store', default='true')
        self.OptionParser.add_option('-d', '--printdesc', action='store', default='true')
        self.OptionParser.add_option('-l', '--printlink', action='store', default='true')
        self.OptionParser.add_option('-p', '--putonselection', action='store', 
            default='false')
        self.OptionParser.add_option('-s', '--separateentries', action='store',
            default='true')

    # appends the list of text elements in text to the given layer, ensuring all text is added below top
    def addTextToLayerAt(self, text, layer, top, selection):
        for t in text:
            t.set('x', str(0))
            t.set('y', str(top))
            layer.append(t)
            if selection is not None:
                putTextOnPath(t, selection)
            top = top + lineSpacing # need to adjust by height of previous element to account for varying font sizes...
        return top
        
    def effect(self):
        feedUrl = self.options.url
        maxEntries = self.options.maxEntries
        printTitle = self.options.printtitle
        printAuthor = self.options.printauthor
        printDesc = self.options.printdesc
        printLink = self.options.printlink
        putOnSelection = True if self.options.putonselection and len(self.selected) == 1 else False
        selection = self.selected.popitem()[1] if putOnSelection else None
        separateEntries = self.options.separateentries # if true, creates new layer for each entry
        

        content = feedparser.parse(feedUrl)        
        svg = self.document.getroot()
        width = inkex.unittouu(svg.get('width'))
        height = inkex.unittouu(svg.get('height'))

        if separateEntries == 'false': # create a layer to hold all entries
            layer = inkex.etree.SubElement(svg, 'g')
            layer.set(inkex.addNS('label', 'inkscape'), 'Feed Entries')
            layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

        top = 0
        for i in range(0, maxEntries if len(content.entries) > maxEntries else len(content.entries)):
            output = []
            if separateEntries == 'true': # create a new layer for each entry
                layer = inkex.etree.SubElement(svg, 'g')
                layer.set(inkex.addNS('label', 'inkscape'), '%s' % (content.entries[i].title))
                layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
                top = 0
            
            if printTitle == 'true':
                titleText = inkex.etree.Element(inkex.addNS('text', 'svg'))
                titleText.set(inkex.addNS('label', 'inkscape'), 'Title')
                titleText.text = '%s' % (content.entries[i].title)
                output.append(titleText)
            if printAuthor == 'true':
                authorText = inkex.etree.Element(inkex.addNS('text', 'svg'))
                authorText.set(inkex.addNS('label', 'inkscape'), 'Author')
                authorText.text = '%s' % (content.entries[i].author)
                output.append(authorText)
            if printDesc == 'true':
                descText = inkex.etree.Element(inkex.addNS('text', 'svg'))
                descText.set(inkex.addNS('label', 'inkscape'), 'Description')
                descText.text = '%s' % (content.entries[i].description)
                output.append(descText)
            if printLink == 'true':
                linkText = inkex.etree.Element(inkex.addNS('text', 'svg'))
                linkText.set(inkex.addNS('label', 'inkscape'), 'Link')
                linkText.text = '%s' % (content.entries[i].link)
                output.append(linkText)
        
            top = self.addTextToLayerAt(output, layer, top, selection)
        
        #urltext = inkex.etree.Element(inkex.addNS('text', 'svg'))
        #urltext.text = '%s' % (content.feed.link)
        
        #urltext.set('x', str(width / 2))
        #urltext.set('y', str(height / 2))

        

        #layer.append(urltext)

        

effect = RssFeedReaderEffect()
effect.affect()