<?xml version="1.0" encoding="UTF-8"?>
<essay xml:lang="en" version="5.0" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:gal="http://norman.walsh.name/rdf/gallery#" xmlns:foaf="http://xmlns.com/foaf/0.1/">
<info>
    
    
    
    
    
    
    
    
    
    
<title>Micro-blogging Backup, part the fourth</title><biblioid class="uri">http://norman.walsh.name/2009/09/09/mbb04</biblioid>
<volumenum>12</volumenum>
<issuenum>29</issuenum>
<pubdate>2009-09-09T11:11:49-04:00</pubdate>
<author>
      <personname>
<firstname>Norman</firstname>
	<surname>Walsh</surname>
</personname>
    </author>
<copyright>
      <year>2009</year>
      <holder>Norman Walsh</holder>
    </copyright>
<abstract>
<para>In which we get to see what our tweets and ’dents look like.</para>
</abstract>
<dc:subject rdf:resource="http://norman.walsh.name/knows/taxonomy#MarkLogic"/>
<dc:subject rdf:resource="http://norman.walsh.name/knows/taxonomy#Microblogging"/>
<dc:subject rdf:resource="http://norman.walsh.name/knows/taxonomy#TheWeb"/>
</info>

<para xml:id="p1">If you haven't been following along, go back and read
parts
<link xlink:href="/2009/08/27/mbb01">one</link>, 
<link xlink:href="/2009/08/28/mbb02">two</link>, and for a little background,
<link xlink:href="/2009/09/03/mbb03">three</link> first. Now you've got
<link xlink:href="http://www.marklogic.com/product/marklogic-server.html">MarkLogic
Server</link> up and running and you've been able to download your tweets
and the tweets of those you follow. (Tweets or ’dents depending on which 
microblogging service you prefer; either, actually both, work for me.)</para>

<para xml:id="p2">Next, download 
<link xlink:href="examples/mbb04.zip">mbb04.zip</link> and unpack it
in the same place where you unpacked 
<link xlink:href="/2009/08/28/examples/mbb02.zip">mbb02.zip</link>.
If you were following the instructions, you've edited some of the files
in the “<filename>mbb/inst</filename>” directory and you may have some
sessions saved in CQ, so I <emphasis>have not</emphasis> included those
directories in <filename>mbb04.zip</filename>.</para>

<para xml:id="p3">If you've been tinkering with other files, then you want to
unpack this zip with some care or you may overwrite your changes. But
you won't overwrite changes made to the installation or CQ areas. (By
the same token, this distribution is incomplete without
<filename>mbb02.zip</filename>).</para>

<para xml:id="p4">With that installed, you now have a CSS file, four modules, and a
new “top level” script, <filename>show-tweets.xqy</filename>. That's the
fun one.
Point your browser at
<link xlink:href="http://localhost:8330/show-tweets.xqy"/> and you
should be rewarded with a list of your status messages from today. (As
before, adjust the port number as necessary if you installed the
application server on a different port.)</para>

<para xml:id="p5">If you don't have any status messages from today, load
<link xlink:href="http://localhost:8330/get-tweets.xqy"/> to
download your most recent messages, then try
<link xlink:href="http://localhost:8330/show-tweets.xqy"/> again.
</para>

<para xml:id="p6">The <filename>show-tweets.xqy</filename> script accepts query
parameters. You can pass:</para>

<variablelist>
<varlistentry>
      <term>
	<literal>sdate</literal>
      </term>
<listitem>
<para xml:id="p7">To specify the starting date in “YYYY-MM-DD” format. If unspecified,
defaults to the ending date.
</para>
</listitem>
</varlistentry>

<varlistentry>
      <term>
	<literal>edate</literal>
      </term>
<listitem>
<para xml:id="p8">To specify the ending date. If unspecified, defaults to today.
</para>
</listitem>
</varlistentry>

<varlistentry>
      <term>
	<literal>users</literal>
      </term>
<listitem>
<para xml:id="p9">To specify one or more users separated by spaces
(<literal>+</literal> signs or <literal>%20</literal>’s in URI-speak). These should
match the <literal>screen_name</literal> values in your account
configuration. The value “<literal>ALL</literal>” is special, it will list
tweets for <emphasis>every</emphasis> user, including all your friends.
</para>
</listitem>
</varlistentry>

<varlistentry>
      <term>
	<literal>service</literal>
      </term>
<listitem>
<para xml:id="p10">To specify the service. If you setup accounts on multiple services,
this will let you limit the result to only those messages on a single service.
</para>
</listitem>
</varlistentry>
</variablelist>

<para xml:id="p11">Go ahead and give it a try, 
<link xlink:href="http://localhost:8330/show-tweets.xqy?sdate=2009-08-01&amp;edate=2009-08-31&amp;users=ALL"/> will show you all the messages by you and those you
follow posted in the month of August.</para>

<section xml:id="display">
<title>Message Formatting</title>

<para xml:id="p12">The messages are sorted in ascending order by date, so that
messages read chronologically “down” the page as you'd expect.
However, conversations are handled a little bit specially.</para>

<para xml:id="p13">Whenever a message is encountered that is part of a conversation
(either because it's a reply to another message, or another message exists
that is in reply to it), the whole thread is collected together and presented
as a unit, like this:</para>

<mediaobject role="flickr">
      <!--Message threading-->
  <imageobject xlink:href="http://www.flickr.com/photos/ndw/3904233170/">
    <imagedata fileref="http://farm3.static.flickr.com/2643/3904233170_f112bd175e.jpg"/>
  </imageobject>
</mediaobject>

<para xml:id="p14">I think that makes the results much easier to follow. We'll come back
to what to do about threads involving users other than you or your followers
later.</para>

<note>
<para xml:id="p15">There were some bugs in the Identi.ca server that occasionally
caused incorrect “in-reply-to” values to be inserted into the data. I
think those <link xlink:href="http://identi.ca/notice/9260164">have
been fixed</link> in the server, but there's nothing I can do about
the values that are wrong.</para>
</note>

</section>
<section xml:id="rewriting">
<title>URL Rewriting</title>

<para xml:id="p16">Those <filename>show-tweets.xqy</filename> URLs may be sufficient,
but they're hardly elegant. I'd be much happier if they were better organized
for human consumption.</para>

<para xml:id="p17">Luckily, with the URL rewriting features of MarkLogic Server V4.1, this
is easily achieved. To begin with, go back into the admin console
(<link xlink:href="http://localhost:8001/"/>) and navigate down through
Groups→Default→App Servers in the tree control then select the server you
setup for this project.</para>

<para xml:id="p18">Near the bottom of that page, you'll find a “url rewriter” field.
Specify <literal>modules/url-rewriter.xqy</literal> as the value for that
field and then click “Ok” at either the top or bottom of the page.</para>

<para xml:id="p19">The one I provided supports a range of values designed to be more
readable:</para>

<variablelist>
<varlistentry>
	<term>
	  <uri>/my-tweets/<replaceable>service</replaceable>/<replaceable>users</replaceable>/<replaceable>start-date</replaceable>/<replaceable>end-date</replaceable></uri>
	</term>
<listitem>
<para xml:id="p20">Returns the messages associated with “users” on “service” between the
specified start and end dates,
e.g., <uri>/my-tweets/identica/ndw/2009-08-01/2009-08-15</uri>.
</para>
</listitem>
</varlistentry>

<varlistentry>
	<term>
	  <uri>/my-tweets/<replaceable>users</replaceable>/<replaceable>start-date</replaceable>/<replaceable>end-date</replaceable></uri>
	</term>
<listitem>
<para xml:id="p21">Returns the messages associated with “users” on any service between the
specified start and end dates,
e.g., <uri>/my-tweets/ndw/2009-08-01/2009-08-15</uri>.
</para>
</listitem>
</varlistentry>

<varlistentry>
	<term>
	  <uri>/my-tweets/<replaceable>start-date</replaceable>/<replaceable>end-date</replaceable></uri>
	</term>
<listitem>
<para xml:id="p22">Returns the messages associated with any user on any service between
the specified start and end dates,
e.g., <uri>/my-tweets/2009-08-01/2009-08-15</uri>.
</para>
</listitem>
</varlistentry>

<varlistentry>
	<term>
	  <uri>/my-tweets/<replaceable>start-date</replaceable></uri>
	</term>
<listitem>
<para xml:id="p23">Returns the messages associated with any user on any service between
the specified start date and today,
e.g., <uri>/my-tweets/2009-09-01</uri>.
</para>
</listitem>
</varlistentry>

<varlistentry>
	<term>
	  <uri>/my-tweets</uri>
	</term>
	<listitem>
<para xml:id="p24">Returns the messages associated with any user on any service posted
today.
</para>
</listitem>
</varlistentry>

<varlistentry>
	<term>
	  <uri>/all-tweets/<replaceable>service</replaceable>/<replaceable>users</replaceable>/<replaceable>start-date</replaceable>/<replaceable>end-date</replaceable></uri>
	</term>
<listitem>
<para xml:id="p25">Returns the messages posted by anyone on “service” between the
specified start and end dates.
</para>
</listitem>
</varlistentry>

<varlistentry>
	<term>
	  <uri>/all-tweets/<replaceable>start-date</replaceable>/<replaceable>end-date</replaceable></uri>
	</term>
<listitem>
<para xml:id="p26">Returns the messages posted by anyone on any service between the
specified start and end dates.
</para>
</listitem>
</varlistentry>

<varlistentry>
	<term>
	  <uri>/all-tweets/<replaceable>service</replaceable>/<replaceable>start-date</replaceable></uri>
	</term>
<listitem>
<para xml:id="p27">Returns the messages posted by anyone on “service” between the
specified start date and today.
</para>
</listitem>
</varlistentry>

<varlistentry>
	<term>
	  <uri>/all-tweets/<replaceable>start-date</replaceable></uri>
	</term>
<listitem>
<para xml:id="p28">Returns the messages posted by anyone on any service between the
specified start date and today.
</para>
</listitem>
</varlistentry>
</variablelist>

<para xml:id="p29">The URL rewriter is just an XQuery that you can change; so it
can support any kind of values that you'd like. It recieves the URL
that the user entered. Whatever URL it returns is what the server
actually responds to. The one I've provided turns</para>

<screen>/all-tweets/2009-08-15/2009-08-31</screen>

<para xml:id="p30">into</para>

<screen>/show-tweets.xyq?users=ALL&amp;sdate=2009-08-15&amp;edate=2009-08-31</screen>

<para xml:id="p31">So nothing else has to change about the code, it all just works.
</para>

<para xml:id="p32">I'm not sure there's much else that's new or interesting about
the other modules provided in this part. If you have any questions, feel
free to ask.</para>

<para xml:id="p33">Next time, we'll look at dealing with all those ugly shortened
URLs and pesky replies that extend beyond our followers.</para>

</section>
</essay>

