a better way to daily post twitter to community server: just do a console app, use the metablog api, and task scheduler
scratch that last cvrap, replace the GetAndPostJob class with the following, making the whole thing a console app to run from the task scheduler:
class CMain
{
[STAThread]
static void Main(string[] args)
{
XmlDocument xmldocSettings = new XmlDocument();
xmldocSettings.Load( args[0]);
GetAndPost gap = new GetAndPost(xmldocSettings.DocumentElement);
if ( gap.Get() ) {
gap.Transform();
gap.Post();
} else if ( xmldocSettings.Attributes["bPostNone"].Value == "true" ) {
gap.Post( "nothin'" );
}
}
}
[XmlRpcUrl("http://blogs.no-ip.org/fractalnavel/metablog.ashx")]
public interface IMetaWebLogNewPost
{
[XmlRpcMethod("metaWeblog.newPost")]
string newPost(
string blogid,
string username,
string password,
MetaWeblog.Post post,
bool publish);
}
and replace the last couple of lines in the Post method:
IMetaWebLogNewPost mwlProxy = XmlRpcProxyGen.Create<IMetaWebLogNewPost>();
string ret = mwlProxy.newPost( blogid, userid, pwd, p, bPublish);
there's really no good way to get an "at" functionality from cs tasks (unless there's something undocumented; can't tell from the obfuscated code). i mean shoot, i was going to end up recreating the whole scheduler business, may as well just use the thing.
duh.
yeah, all the rest of the stuff needs cleaning, of course, but this will at least do what i want, when i want.
oh yeah - the argument to the app is the name of a file that contains the task node that used to be in communityserver.config, minus the community server specific stuff. i suppose i could use an actual config file; this was a straight forward adaptation of the previous approach.
whatever. just getting things done. i'm not in a very ocd mood. that's what happens with (b) fueled code, instead of (c).
a first shot at a community server task/job to auto-aggregate & -post my daily twitter timeline.
been playing with auto-capturing daily twittering & posting here. not that i use twitter much; pehaps this auto-posting lack is why. at first i tried loudtwitter, but community server doesn't have a way of accepting what it provides out of the box - email (needs cs enterprise license), atom, xmlrpc (what api?). so i had it email to tumblr, and then mirrored the feed from there (needs cs pro license). you may have seen the recent example of that. either i did something grossly wrong somewhere, or either loudtwitter or tumblr is eating the markup. and the post naming would cause problems with my current url rewriting scheme - i just noticed that. huh - no wonder it didn't post last night.
none of this was very acceptable (or even workable). i suppose i could have figured out what xmlrpc was being sent from loudtwitter and then used that (a more portable solution - still wopuld have the bad post naming). funny that there's nothing about anyone doing this anyplace that i can see. just me, i guess. and no, still no a.p.p. in cs2008.5sp1 (i upgraded last week).
apparently, i chose the "roll your own" route (see below), but it's not finished. well, it works, but i need to tweak scheduling and formatting, and generalizing the configuration would be nice, as would fixing the credential security issue. but hey, this is just for me. all that detail stuff is a lot of work.
not a sterling example of code or design, but, well, any landing you can walk away from ...
- fractalnavel.CS.Components.GetAndPostJob
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
using CommunityServer.Blogs.Components;
using Telligent.Tasks;
namespace fractalnavel.CS.Components
{
public class GetAndPostJob : ITask
{
public GetAndPostJob()
{
}
public void Execute(XmlNode node)
{
GetAndPost gap = new GetAndPost(node);
if ( gap.Get() ) {
gap.Transform();
gap.Post();
} else if ( node.Attributes["bPostNone"].Value == "true" ) {
gap.Post( "nothin'" );
}
}
}
public class GetAndPost
{
private XmlNode _nodSettings;
private string _strPostBody;
private XmlDocument _xmldocAll = new XmlDocument();
public GetAndPost( XmlNode node )
{
_nodSettings = node;
}
public bool Get()
{
string href = _nodSettings.Attributes["hrefGet"].Value;
int intHours = Int32.Parse(_nodSettings.Attributes["hours"].Value);
href += "?since=" + ((DateTime.Now).AddHours(-intHours)).ToString("r");
string userid = _nodSettings.Attributes["useridGet"].Value;
string pwd = _nodSettings.Attributes["pwdGet"].Value;
_strPostBody = GetTextFromHref( href, userid, pwd );
_xmldocAll.LoadXml( _strPostBody );
return (_xmldocAll.SelectNodes("//status")).Count > 0;
}
public void Transform()
{
string href = _nodSettings.Attributes["hrefXsl"].Value;
XslTransform xsl = new XslTransform();
xsl.Load( href, new XmlUrlResolver() );
StringBuilder sbResult = new StringBuilder();
StringWriter swResult = new StringWriter( sbResult );
xsl.Transform( _xmldocAll, null, swResult, null );
_strPostBody = sbResult.ToString();
}
public void Post()
{
Post( _strPostBody );
}
public void Post( string strPostBody )
{
string blogid = _nodSettings.Attributes["idBlog"].Value;
string userid = _nodSettings.Attributes["useridBlog"].Value;
string pwd = _nodSettings.Attributes["pwdBlog"].Value;
string title = _nodSettings.Attributes["titleBlog"].Value;
bool bPublish = true;
DateTime dtNow = DateTime.Now;
MetaWeblog.Post p = new MetaWeblog.Post();
p.title = title + " " + (dtNow).ToString("yyyy.MM.dd");
p.dateCreated = dtNow;
p.description = strPostBody;
IMetaWeblog metablog = new MetaWeblog();
metablog.newPost(blogid, userid, pwd, p, bPublish);
}
private string GetTextFromHref(string url, string user, string password)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Credentials = new NetworkCredential(user, password);
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseString = reader.ReadToEnd();
reader.Close();
return responseString;
}
}
}
- excerpt from communityserver.config
...
<>
<Thread minutes="1320">
<task
name = "fnGetAndPostJob"
type = "fractalnavel.CS.Components.GetAndPostJob, fractalnavel.CS"
enabled = "true"
enableShutDown = "false"
hrefGet="http://twitter.com/statuses/user_timeline.xml"
useridGet="***"
pwdGet="***"
hrefXsl="http://blogs.no-ip.org/GetAndPost.xsl"
idBlog="fractalnavel"
useridBlog="***"
pwdBlog="***"
titleBlog="a day in a life"
hours="24"
bPostNone="false"
/>
</Thread>
...
- GetAndPost.xsl
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method='html'
omit-xml-declaration="yes"
version="1.0"
encoding="UTF-8"
indent="yes"
cdata-section-elements=""
/>
<xsl:template match="/statuses">
<div class="divLTAll">
<div class="divLTHead">
via <a href="http://www.twitter.com/fractalnavel" target="_blank"
title="twitter!">@fractalnavel</a>: in the last twenty-four hours:
</div>
<div class="divLTBody">
<ul>
<xsl:apply-templates select="status" >
<xsl:sort select="position()" order="descending" data-type="number"/>
</xsl:apply-templates>
</ul>
</div>
<div class="divLTFoot">
(pulled direct from twitter via custom cs job)
</div>
</div>
</xsl:template>
<xsl:template match="status">
<li><xsl:value-of select="created_at" />: <xsl:value-of select="text" /></li>
</xsl:template>
</xsl:stylesheet>
so the intent should be clear anyway.
there were a lot of links that assisted in one way or another, but the power went phlooey this morning for no apparent reason (interestingly, my modem/router was presciently bombing just minutes before that), so that combined with my laziness means you won't see them here. mostly just stuff on generic community server task creation, and the twitter api.
other twitter related stuff to-do:
- do an updated CSModule for updating twitter when a post is created. there is an old one out there. somewhere. but my data stream is heading the other direction.
- do a sidebar widget with ajaxy & configurable timeline display. have it update & scroll, that sort of thing. eh, for the addicts out there, sure, but for me ? nahhh...
i did finally do something twitter-ish on the xo: installed TTYtter. too bad there's not a sugar-ized gui client. and it seems any other linux friendly gui twitter clients will bloat too much once all the supporting stuff gets put in place. best to do that on an xo running linux on a stick. seriously, what's the issue with expanding the storage there ? for just a few bucks more, could increase it by an order of magnitude. but it's easy being an armchair couch quarterback.