Simon Fell > Its just code > April 2003
Wednesday, April 30, 2003
Wednesday, April 30, 2003
Wednesday, April 30, 2003
Monday, April 28, 2003
public interface IBlogIt : IBlogThis
{
// Display configuration dialog to user, if applicable
void Configure();
// Return true if an editing GUI will be shown to the
// user when BlogItem is called. In this case, the
// aggregator will not display its own editing UI.
bool HasEditingGUI();
}
Sunday, April 27, 2003
Sunday, April 27, 2003
Saturday, April 26, 2003
Saturday, April 26, 2003
Update PocketSOAP 1.4.3 RC3 available. In addition to the perf fix, it also now faults on mU='1' headers that it doesn't know off, as per Glen's suggestion.
Saturday, April 26, 2003
Saturday, April 26, 2003
Friday, April 25, 2003
Thanks Sara, its great news that you're going to tackle this one.Thanks Simon! Glad you like the new RSS feeds - we're pretty pleased with them. :-)
I hear ya on the broken links. Seems like it'd be a simple thing to fix, but it's surprisingly complicated. Skipping the overly boring details (which I will share if you'd really like), here's the scoop:
- we've actually been working hard to reduce the total number of broken links on the site, and have reduced the overall number by about 95%. Of course, it's not done until we get to 100%, but we are making progress.
- we do have a spec for new infrastructure that will provide unchanging, human-typeable URLs. I can't give you a ship date yet, but it is something that we're actively working on.
Friday, April 25, 2003
Thursday, April 24, 2003
Thursday, April 24, 2003
Thursday, April 24, 2003
Thursday, April 24, 2003
Wednesday, April 23, 2003
Wednesday, April 23, 2003
Tuesday, April 22, 2003
- Sam has a bunch of thoughts on RSS. Apparently its my fault that Dave pulled namespaces from RSS 2.0, so I apologize for that. All I really wanted was for Dave to not treat every paying Radio customer as his personal test bed.
- Joe says some nice things about PocketSOAP, thanks ! Dispite (or because of <g>) Joe's performance claims, I've found a nasty perf bug when you have lots (1000's) of forward refs during deserialization, working on the fix now.
- We RTM'd the remaining products I was working on, looks like my next project will be based on Sharepoint Portal Server 2.0. So I'm following what Justin is upto with interest.
- Chris took the red pill.
Monday, April 21, 2003
Of course I should point out that a number of other toolkits fail the test, and that PocketSOAP doesn't do anything specific if it receives a response with an mU='1', however 4s4c does the right thing. I haven't seen discussed the expected behavior for WS clients handling mU='1' anyone know what the popular toolkits do ?
Monday, April 21, 2003
Monday, April 21, 2003
Monday, April 21, 2003
Sunday, April 20, 2003
Sunday, April 20, 2003
Sunday, April 20, 2003
Saturday, April 19, 2003
Saturday, April 19, 2003
Saturday, April 19, 2003
Saturday, April 19, 2003
Saturday, April 19, 2003
Friday, April 18, 2003
Thursday, April 17, 2003
Thursday, April 17, 2003
Thursday, April 17, 2003
Wednesday, April 16, 2003
Wednesday, April 16, 2003
Wednesday, April 16, 2003
Wednesday, April 16, 2003
Wednesday, April 16, 2003
Monday, April 14, 2003
Has soaked up way more time than I'd like, I think I managed to upset pretty much everyone in the process. Anyway, I've settled on the XML based interface, that is contained in the last assembly I published.
namespace Syndication.Extensibility
{
public interface IBlogThis
{
void BlogItem(IXPathNavigable rssFragment) ;
}
}
The fragment should contain a RSS document containing the item of choice, the aggregator is free to use the source RSS as is (other than removing the additional items), or to generate a synthetic document from its internal data structures. no normalization of the source data is required. The document should conform to the spec for the RSS version it indicates itself to be.
Example, I selected Sam's post about xhtml:body in Radio from his RSS 0.91 feed, If the aggregator preserves the original RSS, then I'd get a document like
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN"
"http://my.netscape.com/publish/formats/rss-0.91.dtd">
<rss version="0.91">
<channel>
<title>Sam Ruby</title>
<link>http://www.intertwingly.net/blog/</link>
<description>It's just data</description>
<language>en-us</language>
<item>
<title>xhtml:body in Radio</title>
<link>http://www.intertwingly.net/blog/1333.html</link>
<description><p>
<a href="http://weblog.infoworld.com/udell/2003/04/14.html#a666">Jon
Udell</a>: <em>Sam Ruby and Don Box have both demonstrated valid
RSS 2.0 feeds that include a &lt;body&gt; element, properly
namespaced as XHTML. Quietly, last week, I joined the
party.</em></p>
<p>Way to go Jon!&nbsp; I'm very much looking forward to your
upcoming O'Reilly Network column.</p>
</description>
</item>
</channel>
</rss>
As stated above, the aggregator could also choose to send a synthesized RSS document, perhaps like
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Sam Ruby</title>
<link>http://www.intertwingly.net/blog/</link>
<description>It's just data</description>
<item>
<title>xhtml:body in Radio</title>
<link>http://www.intertwingly.net/blog/1333.html</link>
<description>Jon Udell: Sam Ruby and Don Box have both demonstrated valid RSS 2.0
feeds that include a &lt;body&gt; element, properly namespaced as XHTML.
Quietly, last week, I joined the party. Way to go Jon!&#160; I'm very
much looking forward to your upcoming O'Reilly Network column.</description>
<dc:date>2003-04-14T15:02:28-05:00</dc:date>
</item>
</channel>
</rss>
I'm specifically not indicating how the aggregator should find the plug-in, thats upto the aggregator writer. Don has a sample that pulls it from the config file, I posted a version of Syndirella that looks for assemblies in a plugins directory that implement the interface, I'm sure there are plenty of other approaches as well.
Sunday, April 13, 2003
Sunday, April 13, 2003
Dare and Sam continue to argue that an XML based interface is better than an interface based on .NET interfaces. I'm not seeing why. Yes, with XML you can add new elements without changing the CLR interface, and do runtime checks for if the element exists or not. How is this different from having the rssItemObject implement multiple interfaces ? and having the plug-in attempt to cast the IBlogThis to the different interfaces it understands (QueryInterface for the COM heads)
namespace Dare.Extensions
{
interface IBandit
{
string language { get ; }
}
}
namespace RssBandit
{
class rssItem : Syndication.Extensibility.IBlogTHis, Dare.Extensions.IBandit
{
...
}
}
Dare says "I have a choice between being ghetto and coming up with an IWeblogItem2 ..." but how is that any more ghetto than adding {http://dare.extensions}language to the rss fragment and having the plug-in check for its existence ?
So, I'm still not seeing why one is fundamentally better than the other, however having said that, I'm likely to stay with the XML based version because at some point, someone will write an aggregator that preserves the original XML and will be able to pass that through to the plug-in. At that point, the plug-in can handle extensions to RSS without the aggregator specifically supporting it.
Sunday, April 13, 2003
POST /weblog/stories/comments.html?pid=22 HTTP/1.1
User-Agent: RssBandit 1.0d
Content-Type: text/xml
Content-Length: 244
Expect: 100-continue
Host: localhost
<item>
<title>RE: RESTLog.NET Installation & Configuration</title>
<link>http://localhost/weblog</link>
<pubDate>4/12/2003 10:02:23 PM</pubDate>
<description>did it work ?</description>
<author>Simon Fell <sf@sf.com></author>
</item>
Sunday, April 13, 2003
Saturday, April 12, 2003
Saturday, April 12, 2003
Saturday, April 12, 2003
Saturday, April 12, 2003
Saturday, April 12, 2003
interface IWeblog
{
string Name { get ; }
Uri Homepage { get ; }
}
interface IWeblogItem
{
string Title { get ; }
Uri Link { get ; }
DateTime Date { get ; }
string Post { get ; }
}
interface IWeblogItemAction
{
void DoAction ( IWeblog , IWeblogItem ) ;
}
This also highlights a hole in the rssItem XML approach, in that some channel level info would be useful, perhaps the XML version will need to recreate the feed with just one item in it ? [Updated to use properties instead of methods]
Thursday, April 10, 2003
Thursday, April 10, 2003
Thursday, April 10, 2003
Wednesday, April 9, 2003
The BlogThis interface is passed an rssFragment, but I haven't yet talked about what's actually in that fragment. What I'd like is for the aggregator to normalize the source data (as this is something it's already worked out), so that the plug-in doesn't have to cope with the wide range of rss versions, modules and extensions floating around.
The normalized fragment will be based on RSS 2.0, and its root is an item element.
At minimum the title and link elements defined in that spec should be passed through if present in the source (allowing for reasonable mappings if the source isn't rss 2.0).
pubDate and/or dc:date if present should be normalized to a dc:date element
which just leaves the content, I'm going back and forth on this one, originally I was thinking that the aggregator should normalize description / content:encoded / xhtml:body to a single content:encoded element. I'm less sure now, I can see that some people might be offended by the loss of fidelity in the xhtml:body -> content:encoded transform. Anyone have any strong opinions one way or the other on this one ?
And finally to clarify one other point, I'm assuming that the plug-in will present/manage any UI required, not the aggregator, i.e. all the aggregator has to do is collect up the data and pass it to the plug-in (this took about 100 lines of C# in Synderilla, including the automatic plugin discovery code). I want this to be drop dead simple for the aggregator writers to support.
Wednesday, April 9, 2003
Wednesday, April 9, 2003
- Thanks to Don for all the XPathNavigator info / code.
- Mark likes NSIS, so do I, its a refreshing change after years of battling various versions of InstallShield.
- Demon's email system is still largely down, has been all day, if you've sent me email today, chances are I haven't seen it yet.
- Two different objective-c bindings for expat. The SaxObjectDecoder in the SKYRiX library looks interesting, a good use of objective-c's runtime messaging. On the downside, I haven't actually been able to get either running yet.
- .NET Framework 1.1 available
- Dave is looking at trackback for Radio & Manilla.
Wednesday, April 9, 2003
Wednesday, April 9, 2003
Update: I rev'd the bits to IBlogThis and IXPathNavigable
Wednesday, April 9, 2003
Assembly al = Assembly.LoadFrom(@"C:\Source\dotnet\Syndirella\bin\Debug\plugins\restlogClient.exe");
Type[] mytypes = al.GetTypes();
foreach(Type tt in mytypes)
{
Console.WriteLine("{0}", tt.ToString() ) ;
}
Exactly the same code in console app, or new winforms app works fine, as does ildasm.
Update Got it. Synderilla is built against v0.7 of XmlRpc.NET, but restlogClient is built against v0.81 of XmlRpc.NET. When it loads the restlogClient assembly it doesn't load the XmlRpc.dll from that directory but seems to re-use the earlier version its already loaded (guess i need to go re-read Don's book)
Tuesday, April 8, 2003
Tuesday, April 8, 2003
Being able to post to a weblog from within an RSS aggregator is a really useful feature that not many tools currently have. The proliferation of blogging API compounds the problem. Given the number of .NET based aggregators now around, I had a vision for a simple extensibility point within the aggregator to be able to hook in 3rd party blogging tools. This page documents my thoughts, ideas, and code to date.
IBlogExtension
Greg, Luke, Matt, and I discussed a new version of the interface that resulted in IBlogExtension.A signed version of the assembly containing the IBlogExtension definition is available.
Aggregators
- Greg Reinacker announced that NewsGator 1.2 will support this.
- Synderilla 20030509-BT
- RSSBandit v1.1
Plug-Ins
Previous version
IBlogThis enabled Aggregators
BlogThis plug-ins
BlogIT extension to BlogThis
- Greg's initial BlogIT proposal
- Comments from Simon Fell and Douglas P
- More thoughts from Greg.
IBlogThis history
- April 14 weblog post revised details about the structure of the doucment passed to the plugin.
- BlogX gets BlogThis support
- April 12 weblog post on a strongly typed version of the IBlogThis interface.
- Relaxer updated with BlogThis support
- April 9 weblog post detailing the structure of the rss fragment XML.
- As everyone needs to refer to the same assembly for the BlogThis interface, I put together a signed version of the interface I posted.
- April 8 weblog post about first prototype
- April 6 weblog post, first attempt to explain idea, plus link to Brads post which kicked it all off
Tuesday, April 8, 2003
Tuesday, April 8, 2003
Tuesday, April 8, 2003
I should of gone to bed, instead I started looking at the Synderilla code to prototype up my blog this extensibility point idea. I have the extensibility point working, although the plug-in does nothing more interesting than message box the XML, but I find its easier to explain ideas with code than words.
First off, we need a common interface definition for all the tools to reference, I just wanted something simple, so went with this
using System;
using System.Xml ;
namespace Syndication.Extensibility
{
public interface BlogThis
{
void BlogItem(XmlDocument rssFragment) ;
}
}
Then I wrote my "plug-in" that implements this interface
class test : Syndication.Extensibility.BlogThis
{
public test()
{
}
public void BlogItem ( System.Xml.XmlDocument rssFragment )
{
System.Windows.Forms.MessageBox.Show(rssFragment.OuterXml) ;
}
}
Then I modified Syderilla to add a BlogThis context menu and for it to dynamically load the plug-in and call it
public void BlogThisItem(NewsItem item)
{
XmlDocument xml = BuildRssFragment(item) ;
Console.WriteLine(xml.OuterXml) ;
Type typePlugin = Type.GetType("test, test") ;
Syndication.Extensibility.BlogThis bp =
(Syndication.Extensibility.BlogThis)Activator.CreateInstance(typePlugin) ;
if(bp!=null)
bp.BlogItem(xml) ;
}
Compile everything up, drop test.dll and blogthis.dll into the same directory as Synerilla.exe and fire it up, click BlogThis, up pops my message box. :)
Currently the type of the plug-in class is hard coded in the GetType call, that just needs pulling out into some config value, and then just wire an implementation of BlogThis in my RESTLog client and its done. It would also be easy to write a plug-in that exposes the data as XML/Sockets as Sam has been talking about, for extensibility outside of .NET
Tuesday, April 8, 2003
Tuesday, April 8, 2003
In progress - A RESTLog client application.
Version 0.6 (October 18, 2005)
binaries and/or source- Support for uploading "media" files (images, zips etc, supporting files for a blog post), just drop the file on the Media Upload Zone. (requires the latest RESTLog.NET server code)
Version 0.5 (May 16, 2003)
binaries and/or source.- Support for IBlogExtension added.
- Improvements to the trackback/pingback client.
Version 0.4 (April 27, 2003)
binairies and/or source.- Pingback and Trackback client support added.
- Support for getting the now playing info from Windows Media Player (requires the WMP blogging plugin)
Version 0.3 (April 15, 2003)
binairies and/or source.- BlogThis integration updated to current spec.
- Spell Checker now behaves in a more expected manner (closing the dialog, cancels the spell check, and cancels the post)
- code button added for turning the selected part of the post into a <pre> wrapped section, it also entity encodes the selection, make its easy to cut'n'paste exsiting code/xml etc into a post.
- xml-rpc pings are now sent asynchronously
- dropping a link on the form will select the best match weblog from all those configured, rather than requiring you to pick the right one first.
Version 0.2 (April 9, 2003)
Tuesday, April 8, 2003
Monday, April 7, 2003
Update: its System.Windows.Forms.Application.DoEvents() Thanks Ingo !
Monday, April 7, 2003
Sunday, April 6, 2003
private string makePayload()
{
const string TUNE_NS = "http://www.pocketsoap.com/weblog/schemas/music/" ;
const string DC_NS = "http://purl.org/dc/elements/1.1/" ;
StringWriter sw = new StringWriter() ;
XmlTextWriter xw = new XmlTextWriter(sw) ;
xw.WriteStartElement("item") ;
xw.WriteElementString("title", title.Text.Trim()) ;
xw.WriteElementString("description", data.Text.Trim()) ;
xw.WriteElementString("link", link.Text.Trim()) ;
DateTime dt = DateTime.Now ;
if ( date.Text.Length > 0 )
dt = DateTime.Parse(date.Text) ;
xw.WriteElementString("date", DC_NS, dt.ToUniversalTime().ToString("s") + "Z" ) ;
xw.WriteElementString("tune", TUNE_NS, tune.Text.Trim()) ;
xw.WriteEndElement() ;
xw.Close() ;
return sw.ToString() ;
}
In fact the whole of System.Xml rocks, with one exception, using SAX its trivial to chain a bunch of SAX handlers together to do interesting/extensible things, whilst this is possible with XmlReader and/or XmlWriter, the number of methods in these classes make it cumbersome. To me they need splitting up into a small core interface, and a helper object that provides all the extra functions (most of the functions in XmlWriter are helpers than could be built on top of the core interface).
Sunday, April 6, 2003
Sunday, April 6, 2003
Sunday, April 6, 2003
Sunday, April 6, 2003
Sunday, April 6, 2003
Sunday, April 6, 2003
Sunday, April 6, 2003
Sunday, April 6, 2003
Installation
This assumes you're familar with configuring IIS & ASP.NET.
- Make sure you have ASP.NET installed and running correctly first.
- unzip the file, preserving directories somewhere convienient ( e.g. c:\inetpub\wwwroot\blog )
- if you need to, goto IIS admin and create a virtual directory that maps to the directory with the index.config file in. Note that this is entirely optional, but makes things slightly easier.
- If you didn't create a virtual dir, then move the dll's out of the bin directory to the parent app's bin directory ( e.g. c:\inetpub\wwwroot\bin )
- Using IIS admin add an application mapping for .html to the ASP.NET Isapi extension. make sure that "check that file exists" is NOT checked. If you choose the limit verbs option, you need to allow GET, POST, PUT, DELETE.
Configuration settings for the weblog are stored in the web.config file, open it up in notead, emac, vi, or whatever your particular text editor posion is.
- <configSections> - this registers the handler for the <restlog.net> section.
- <httpHandlers> - this maps .html requests onto the weblog engine.
- <restlog.net> - this houses all the weblog configuration, this is what you'll want to edit.
- <title> - the title of your weblog, this appears on the web pages, as well as being included in the generated RSS file.
- <description> - the tagline/description for your weblog, this also appears on the web pages and the RSS file.
- <author> - enter the name of the weblog's author
- <indexMaxPosts> - controls the number of entries that appear on the main page, the default is to show the most recent 15 posts, wind this up or down as the mood takes you.
- <rssMaxPosts> - controls the number of entries that appear in the RSS file, the default is to show the most recent 15 posts, wind this up or down as the mood takes you.
- <doPingbacks> - If enabled (by setting the value to true), each time you make a new post, it will automatically check the post for links, and send pingbacks to those servers that support it.
- <rss> - the name of the generated rss file.
- <basepath> - Important set this to the external path to the root of the blog, i.e., if you installed to c:\inetpub\wwwroot\blog\, then it would be /blog/ if you created a virtual directory call weblog in the root of the web server then it would be /weblog/
- <templates> - the names of the 3 templates used. by default these are mapped to .config files, as these won't be served to external clients.
- <main> - this is the main index page, that shows the most recent posts.
- <monthly> - this is the monthly archive page, by default it uses the same template as the main index, but it doesn't have to, if you want your monthly archive pages to do something different.
- <item> - this is the template for a single post page.
The template files index.config and item.config are standard ASPX files, but with a .config file extension. They use ASP.NET's code behind feature so that the weblog engine can provide the relevant information to be rendered. The main and monthly index pages should inherit from the class PocketSoap.RestLog.IndexPage and the item page should inherit from PocketSoap.RestLog.ItemPage.
Both classes expose the information from the web.config file via an instance of the WeblogSettings class available via the Weblog property. The WeblogSettings class has the following properties Title, Description, Author, IndexMaxPosts, RssMaxPosts, DoPingbacks, RssFile, BasePath, MainTemplate, MonthlyTemplate, ItemTemplate.
The Item template exposes the details of the post via an item object, accessed via the Item property, this has the following properties title, description, date, tune, postId, Link, permaLink
The index pages expose a collection (ArrayList) of items to be rendered via the Items property. In addition it has an additional property called ArchiveDate that contains the date of the monthly archived being rendered or the value DateTime.MinValue if its the main index page.
Sunday, April 6, 2003
This weblog is based on an implementation of the RESTLog API that I wrote in .NET. The source code is available under the MIT license, for those who are interesting in running / examining / extending this themselves
Sever (RESTLog.NET v0.1)The server is implemented as a number of custom HttpHandlers that are compiled to a DLL, and has the following features
- Any number of weblog instances can be run on a single ASP.NET install.
- configuration for a particular instance of a weblog is handled entirely in the web.config file.
- template files (ordinary aspx format pages) are used to control the look & feel / rending of the pages.
- A static RSS (1.0) file is generated each time there's a change.
- Support for automatic pingbacks.
- main index page show recent entries, there are also monthly archive pages and individual post pages.
- posts are stored as simple XML files, easy to migrate to/from other blogging tools.
You can download the binaries and source for v0.1, then take a gander at the installation and configurations notes. The latest code is available on SourceForge
Client (relaxer.NET v0.6)A .NET Winforms application for adding/updating/deleting posts for any RESTLog compliant server
- Simple interface, supports multiple weblogs
- Spell checker (requires MS Word)
- Winamp integration (requires WS-Amp) & WMP9 integration (requires the Blog Plugin)
- Drag'n'drop from the browser to edit.
- Can ping weblogs.com plus any other servers that implement the weblogs.com ping interface.
- Includes a pingback & trackback client.
Still in progress, v0.6 is now available.
Client (relaXer v0.1)A Cocoa application for Mac OS X for adding/updating/deleting posts for any RESTLog compliant server
- Native Cocoa application
- Spell Checker
- iTunes integration
- Drag'n'drop from the browser to edit
Still in progress, here a screen shot, to keep you going.
Saturday, April 5, 2003
Saturday, April 5, 2003
Saturday, April 5, 2003
POST /blog/1315.html?preview=yes
host: www.intertwingly.net
content-type: text/xml
<Envelope xmlns='....'>
<Body>
<item xmlns=''>....
POST /blog/1315.html
host: www.intertwingly.net
content-type: text/xml
<Envelope xmlns='....'>
<Header>
<b:Preview/>
</Header>
<Body>
<item xmlns=''>....
POST /blog/1315.html
host: www.intertwingly.net
content-type: text/xml
<Envelope xmlns='....'>
<Body>
<b:Preview>
<item xmlns=''>....
The top one seems to follow REST the closest (at least given my understanding of REST), I'm not seeing why 2 is better than 3, but am eager to learn!
Saturday, April 5, 2003
Saturday, April 5, 2003
Saturday, April 5, 2003
Saturday, April 5, 2003
Saturday, April 5, 2003
Saturday, April 5, 2003
Only time will tell if it really is a big improvement, but I like what I've seen so far enough to continue investigating. Perhaps this is the fun platform I've been looking for.