Suneido

Integrated Application Platform

  • Home
  • Learning
    • Suneido Manual
    • Beginners
      • Inside Suneido
      • The Suneido Programming Language
      • The Suneido Database
      • Installing Suneido
      • Building Suneido
      • IDE Go To Tour
      • Upgrading To A New Release
    • Advanced
      • Canvas Control
      • DrawControl Part 1
      • DrawControl Part 2
      • DrawControl Part 3
      • SAX Like XML Processing
      • A Plug-In Architecture
      • A Simple Wizard Framework
      • An HTML Include Facility
      • An RSS 2 Feed Creator
      • MIME Generation
      • A New Add-on Facility
      • Workspace Improvement Hack
    • Mockito for Suneido
    • The Suneido Task Scheduler
    • Contributing To Suneido
    • Contributor Assignment of Copyright
    • Language Translation
    • Future Directions
    • Interview With Andrew Mckinlay
  • Forum
    • Announcements
    • Internals & Enhancements
    • Cookbook
    • General
  • FAQ
  • Screenshots
  • Downloads
  • Links

From the Couch 9 – An RSS 2 Feed Creator

I’ve been thinking for a while that we could use feeds as a way to “publish” data from our applications. In house, this could be things like error reports from our customers. For our customer applications, it could be used for things like reminders.

So I sat down with Developing Feeds with RSS and Atom and wrote some code to generate feeds. I picked RSS 2.0 since it looked like the simplest but similar code could be used for other standards.

A feed is simply an XML document so it’s not too hard. I patterned the code after an example in the book of the Perl XML::RSS module.
Here’s an example of how you use it:

rss = Rss2()
rss.Channel(title: 'My Channel',
    link: 'http://abc.com/mychannel.html',
    description: 'my channel of stuff')
rss.AddItem(title: 'My Item',
    description: 'my item of stuff')
Print(rss.ToString())

This would produce:

<!--?xml version="1.0" encoding="us-ascii"?-->My Channel
http://abc.com/mychannel.htmlmy channel of stuffMy Item
my item of stuff
https://suneido.com/20071009_172526752


You can validate this using the W3C Feed Validator. The code checks for required elements.

Here is the code:

Rss2

class
    {
    New()
        {
        .items = []
        }

    channel: false
    Channel(@args)
        {
        if .channel isnt false
            throw "Rss2: only one channel allowed"
        .channel = new .channel_element
        .elements(.channel, args)
        }
    channel_element: class
        {
        Name: 'channel'
        Elements: (title, link, description,
            language, copyright, managingEditor, webMaster, pubDate,
            lastBuildDate, category, generator, docs, cloud, ttl, image,
            rating, textinput, skipDays, skipHours)
        Required: (title, link, description)
        }

    image: false
    Image(@args)
        {
        if .image isnt false
            throw "Rss2: only one image allowed"
        .image = new .image_element
        if not args.Member?(#link) and .channel isnt false
            args = args.Copy().Add(.channel.link, at: #link)
        .elements(.image, args)
        }
    image_element: class
        {
        Name: 'image'
        Elements: (url, title, link, width, height)
        Required: (url, title, link)
        }

    textInput: false
    TextInput(@args)
        {
        if .textInput isnt false
            throw "Rss2: only one textInput allowed"
        .textInput = new .textInput_element
        .elements(.textInput, args)
        }
    textInput_element: class
        {
        Name: 'textInput'
        Elements: (title, description, name, link)
        Required: (title, description, name, link)
        }

    AddItem(@args)
        {
        .items.Add(item = new .item_element)
        .elements(item, args)
        if not item.Member?(#title) and not item.Member?(#description)
            throw "Rss2: item must have either title or description"
        }
    item_element: class
        {
        Name: 'item'
        Elements: (title, link, description, author, category,
            comments, enclosure, guid, pubDate, source)
        Required: ()
        }

    ToString()
        {
        return '<!--?xml version="1.0" encoding="us-ascii"?-->\n' $
            Xml('rss', version: '2.0')
                { '\n' $ .xml(.channel, .xml(.image) $ .xml(.textInput) $ .items_tostring()) }
        }
    items_tostring()
        {
        s = ''
        for item in .items
            {
            if not item.Member?(#guid)
                item.guid = .guid()
            s $= .xml(item)
            }
        return s
        }
    guid()
        {
        return 'https://suneido.com/' $
            Display(Timestamp()).Substr(1).Tr('.', '_')
        }

    elements(ob, args)
        {
        for m in args.Members()
            if ob.Elements.Has?(m)
                ob[m] = args[m]
            else
                throw 'Rss2: invalid element: ' $ ob.Name $ '/' $ m
        for m in ob.Required
            if not ob.Member?(m)
                throw 'Rss2: missing element: ' $ ob.Name $ '/' $ m
        }

    xml(ob, body = '')
        {
        if ob is false
            return ''
        s = ''
        for m in ob.Elements
            if ob.Member?(m)
                s $= Xml(m, XmlEntityEncode(ob[m])) $ '\n'
        return Xml(ob.Name, '\n' $ s $ body) $ '\n'
        }
    }

The next step is to hook this up to HttpServer so you can actually access the feeds. And perhaps adding a caching mechanism so the feed doesn’t have to be regenerated for every request.

Contact Us | Legal Statement | Privacy Statement | SiteMap

Copyright © 2023 Axon® Development Corporation. All Rights Reserved. - Open Source Integrated Database and Programming Language