<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-759829936301057674</id><updated>2012-01-25T22:39:44.365Z</updated><category term='show'/><category term='bibliography'/><category term='requests'/><category term='installation'/><category term='fish'/><category term='html5'/><category term='books'/><category term='mv'/><category term='fdb'/><category term='measurement'/><category term='fom'/><category term='privacy'/><category term='fluiddb'/><category term='art'/><category term='api'/><category term='library'/><category term='jones'/><category term='artist'/><category term='values'/><category term='aliases'/><category term='stdin'/><category term='copy'/><category term='git'/><category term='alice'/><category term='structured data'/><category term='line'/><category term='get'/><category term='abouttag'/><category term='future'/><category term='indicators'/><category term='system'/><category term='table'/><category term='visualization'/><category term='of'/><category term='setuptools'/><category term='fluidb'/><category term='solar system'/><category term='security'/><category term='british'/><category term='faq'/><category term='move'/><category term='album'/><category term='record'/><category term='URIs'/><category term='anonymous'/><category term='permissions'/><category term='iPhone'/><category term='people'/><category term='svg'/><category term='drm'/><category term='delicious'/><category term='html'/><category term='national'/><category term='siri'/><category term='fish fluidinfo unix file system cp mv'/><category term='wiki'/><category term='songs'/><category term='client'/><category term='fish.py'/><category term='planets'/><category term='cache'/><category term='apple'/><category term='rm'/><category term='song'/><category term='tag'/><category term='pinboard'/><category term='about'/><category term='normalization'/><category term='export'/><category term='command'/><category term='http'/><category term='sync'/><category term='track'/><category term='cp'/><category term='namespaces'/><category term='shell'/><category term='amazon'/><category term='browser'/><category term='ratings'/><category term='windows'/><category term='orwell'/><category term='access'/><category term='tracks'/><category term='file'/><category term='albums'/><category term='abstract tags'/><category term='database'/><category term='URLs'/><category term='alias'/><category term='del.icio.us'/><category term='fluidinfo'/><category term='MIME'/><category term='vision'/><category term='shell-fish'/><category term='records'/><category term='objects'/><category term='engine'/><category term='files'/><category term='music'/><category term='rename'/><category term='blog'/><category term='artoftagging'/><category term='private'/><category term='terry'/><category term='sequences'/><category term='kindle'/><category term='rcp'/><category term='wikipedia'/><category term='tags'/><category term='terminal'/><category term='paths'/><category term='unix'/><category term='twitter'/><category term='untag'/><category term='structure'/><category term='search'/><category term='tagging'/><category term='command line'/><category term='conventions'/><category term='metadata'/><category term='progress'/><category term='sets'/><title type='text'>About Tag</title><subtitle type='html'>On Fluidinfo tagging and meaning.
&lt;br&gt;&lt;br&gt;
&lt;a href="#BlogArchive1"&gt;Archives&lt;/a&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.abouttag.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>96</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-3220126043418671691</id><published>2012-01-25T22:39:00.003Z</published><updated>2012-01-25T22:39:44.387Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='http'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='requests'/><category scheme='http://www.blogger.com/atom/ns#' term='setuptools'/><title type='text'>Fish Fixes and setuptools</title><content type='html'>&lt;div class="section" id="fish-fixes-and-setuptools"&gt;
&lt;p&gt;I have a few pieces of good news.   And one piece of not-so-good news.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;I&amp;#8217;ve pushed Fish 4.33 to &lt;a class="reference external" href="https://github.com/njr0/fish"&gt;Github&lt;/a&gt;.
This version includes
two main bug fixes and some
useful reorganization.   The bug fixes are:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;One test was failing under Python 2.7 (but not 2.6 or 2.5)
That turns out to be because I was lazily doing some json
encoding &amp;#8220;by hand&amp;#8221; and failing to percent-encode non-ASCII
characters.   &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;httplib&lt;/span&gt;&lt;/tt&gt; in the earlier versions didn&amp;#8217;t
seem to mind, but in Python 2.7 it does.   I am now using
a proper json serializer and things are better.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;It transpires that starting Fish interactively was failing
for new users.   This is because the interactive version of
Fish (the one you get if you just type &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt; &lt;span class="pre"&gt;&amp;lt;return&amp;gt;&lt;/span&gt;&lt;/tt&gt;)
was doing a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/tt&gt;, and that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/tt&gt; assumes that
you have a tag called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;.fish/alias&lt;/span&gt;&lt;/tt&gt;.   New users tend not
to have that.   Obviously, the solution is to create it,
which Fish now does.   (It makes it private, too.   You can
change it to public if you prefer.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish perms public .fish/alias&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;will do the job.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;My thanks to Rodrigo Barnes
(&lt;a class="reference external" href="http://twitter.com/rodrigobarnes"&gt;&amp;#64;rodrigobarnes&lt;/a&gt;)
for noticing and pointing out both problems.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;I have switched the default/preferred HTTP library used by Fish
from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;httplib2&lt;/span&gt;&lt;/tt&gt;, which had always caused me problems, to Kenneth
Reitz&amp;#8217;s
&lt;a class="reference external" href="http://docs.python-requests.org/en/latest/index.html"&gt;requests&lt;/a&gt;.
I don&amp;#8217;t know whether &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;httplib2&lt;/span&gt;&lt;/tt&gt; is just broken or whether it&amp;#8217;s
a case of user error, but I have never managed to persuade it to
work reliably.   It took under 15 minutes to swap it out and
replace it with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;requests&lt;/span&gt;&lt;/tt&gt;, and the process fixed all the problems
I knew about with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;httplib2&lt;/span&gt;&lt;/tt&gt;, so that was pretty fantastic.&lt;/p&gt;
&lt;p&gt;I have talked to various people about &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;requests&lt;/span&gt;&lt;/tt&gt; and the most
common response has been &amp;#8220;It&amp;#8217;s awesome&amp;#8221;.   Do not misunderstand me
when I say, I disagree.   My experience merely that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;requests&lt;/span&gt;&lt;/tt&gt; is
well-designed, functional, pythonic and easy-to-use.   In those
respects it is like most Python libraries.   I suspect that
the main reason &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;requests&lt;/span&gt;&lt;/tt&gt; generates reactions of awe is that
all the other main Python libraries for handling HTTP requests
are sub-par &lt;a class="footnote-reference" href="#id2" id="id1"&gt;[1]&lt;/a&gt;.   As Kenneth Reitz himself says (specifically of
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;urllib2&lt;/span&gt;&lt;/tt&gt;):&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;&lt;em&gt;Things shouldn’t be this way. Not in Python.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Requests is excellent and I strongly recommend you use it,
with one caveat:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Version 0.9.2, which I used to make the change, works
perfectly.   Use that.&lt;/p&gt;
&lt;p&gt;I have not yet been able to make version 1.0.1 work with Fish.
It is entirely possible that is because I have done something
stupid.   But at this point, using 1.0.1 will not move you forward.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The way I have upgraded Fish is first to try to import &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;requests&lt;/span&gt;&lt;/tt&gt;
and then to check that the version is less that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;1.0.0&lt;/span&gt;&lt;/tt&gt;.
If &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;requests&lt;/span&gt;&lt;/tt&gt; is unavailable, or you have &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;1.0.0&lt;/span&gt;&lt;/tt&gt; or newer,
Fish falls back (silently) to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;httplib2&lt;/span&gt;&lt;/tt&gt;.   To be fair, that
mostly works; but &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;requests&lt;/span&gt;&lt;/tt&gt; works better.&lt;/p&gt;
&lt;p&gt;[&amp;#8220;What does that mean?&amp;#8221;, you ask.   Well, I have two problems with
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;httplib2&lt;/span&gt;&lt;/tt&gt;.   First, it consistently fails with request bodies
over slightly less than 64KB.   This is a problem with some file
uploads to Fluidinfo.   Secondly, when performing bulk uploads,
particularly if I use multiple threads, I get occasional failures
with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;httplib2&lt;/span&gt;&lt;/tt&gt;.   Retrying sometimes, but not always, works.
(This was a major pain uploading, for example, the 2.5 million
items in the British National Bibliography.   The upload spent
about 50% of the time uploading the first 98%, and the other
50% retrying the troublesome 2%.   I have yet to see any random
failures with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;requests&lt;/span&gt;&lt;/tt&gt;.]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;I finally got round to packaging up Fish with setuptools.
So if you download it now, you should be able to do a standard&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;python setup.py install&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;in the package directory and standard, good things will happen.
These include installing the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; script, so if you used
an alias or specially added it to your path before, this is
no longer necessary.&lt;/p&gt;
&lt;p&gt;I also cleaned up the import structure a bit to make this work.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;So much for the good news.&lt;/p&gt;
&lt;p&gt;The bad news is that I can&amp;#8217;t upload it to PyPI, which had been my intention,
because there is already a package called fish on PyPI.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/fish/"&gt;Animating fish (and birds) for progress bars&lt;/a&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Obviously, I could rename Fish (for a second time), but that seems
undesirable when it is about to appear in print in the form of an
O&amp;#8217;Reilly book (blog post upcoming).   So I guess we&amp;#8217;ll have to do
things the old way.&lt;/p&gt;
&lt;p&gt;Needless to say, in the process of all these lovely upgrades, it is possible
I broke something.   Please let me know if I did and I will endeavour
to fix it.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="id2" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Funny term, &amp;#8220;subpar&amp;#8221;.   Every golfer aspires to shoot under par:
in golf, less is definitely more.   But I didn&amp;#8217;t feel using the
term &amp;#8220;super-par&amp;#8221; would really have conveyed my meaning.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-3220126043418671691?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/3220126043418671691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2012/01/fish-fixes-and-setuptools.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3220126043418671691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3220126043418671691'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2012/01/fish-fixes-and-setuptools.html' title='Fish Fixes and setuptools'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-8392235636518904577</id><published>2012-01-22T19:16:00.000Z</published><updated>2012-01-22T19:18:45.540Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='rcp'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><title type='text'>Tags, The Tagosphere and Every Thing: Towards an rcp for Fish</title><content type='html'>&lt;div class="section" id="tags-the-tagosphere-and-every-thing-towards-an-rcp-for-fish"&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;&lt;em&gt;In the&lt;/em&gt; &lt;a class="reference external" href="http://blog.abouttag.com/2012/01/like-0-file-systems-for-everyone.html"&gt;first of this series of articles&lt;/a&gt;
we discussed the analogy between the
Unix File System and Fluidinfo.  The Fluidinfo Shell,
&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;Fish&lt;/a&gt;,
&lt;em&gt;is largely a working through of that analogy.  A new insight from that
article, upon which we will now expand, is that the objects in
Fluidinfo can usefully be viewed as analogues of host computers in a
computer network.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;In the&lt;/em&gt; &lt;a class="reference external" href="http://blog.abouttag.com/2012/01/movement-and-copying-in-fluidinfo.html"&gt;second article&lt;/a&gt;,
&lt;em&gt;we discussed how to augment Fish with Unix-like copy&lt;/em&gt;
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt;) &lt;em&gt;and move&lt;/em&gt; (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;) &lt;em&gt;commands for Fluidinfo&amp;#8217;s
abstract tags and namespaces.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;In this third, and—with luck—final part of the trilogy, we will
tackle the more complex question of how to copy and move data within
and among objects and concrete tags in Fluidinfo.  Just
as we leant on the behaviour of Unix&amp;#8217;s&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;and&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;
&lt;em&gt;commands when considering similar commands for abstract tags in
Fluidinfo, we will look to&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rsync&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;and&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ftp&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;as
sources of wisdom, guidance and precedent as we try to design
similar commands for concrete tags in Fluidinfo.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="section" id="recapitulation"&gt;
&lt;h2&gt;Recapitulation&lt;a class="headerlink" href="#recapitulation" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the previous article in this series, we concluded that we could
sensibly model &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; commands for namespaces and abstract
tags in Fluidinfo on their Unix counterparts provided we resolve three
issues:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;How should we handle ambiguity, given that a tag and a namespace
can share the same name (and path) in Fluidinfo?&lt;/li&gt;
&lt;li&gt;How should we handle permissions on copied and moved tags, given
the rather different way permissions work in Fluidinfo and Unix?&lt;/li&gt;
&lt;li&gt;How destructive should overwriting behaviour be?  If we copy a
(whole, abstract) tag &amp;#8220;on top&amp;#8221; of another, should all old values
of that tag be destroyed, or should the result be a union in
which the new values take precedence, but the old values remain
on objects that were not tagged with the &amp;#8220;source&amp;#8221; tag?&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Our candidate solutions are (respectively):&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;Where paths are ambiguous for either source or destination items,
we will demand disambiguation by adding a trailing slash (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/&lt;/span&gt;&lt;/tt&gt;)
to denote a namespace or a trailing dot (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;.&lt;/span&gt;&lt;/tt&gt;) to denote a tag.&lt;/li&gt;
&lt;li&gt;We propose a &lt;em&gt;reverse Facebook&lt;/em&gt; principle, whereby whenever the
degree of access granted to data unclear, we
should grant the smallest set of rights that the user might
reasonably expect, the logic being that while overly restrictive
permissions can easily be relaxed, unintentional release of
private information is potentially irreversible and more harmful.&lt;/li&gt;
&lt;li&gt;We didn&amp;#8217;t really resolve overwrite behaviour beyond a
meal-mouthed suggestion that we might need to provide options.
While we should do that, this doesn&amp;#8217;t answer the question,
because unless we force the user to make an explicit choice on a
case-by-case basis, we will have to decide on the default
behaviour, and that will be the main behaviour people will
experience (unless we make such a poor choice that it is normally
overridden). I am currently leaning toward the less descructive
behaviour as the default.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="the-jobs-to-be-done"&gt;
&lt;h2&gt;The Jobs to be Done&lt;a class="headerlink" href="#the-jobs-to-be-done" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Thus far, we have considered moving and copying &lt;em&gt;whole tags&lt;/em&gt; (abstract
tags together with all their concrete instances).  But at least as
important, and probably more common in practice, will be the need to
move or copy just some concrete tags.  Concentrating first on the
movement and copying within Fluidinfo (as opposed to transfers
between Fluidinfo and the local file system), some examples of things Alice
might wish to do include:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Copy one or more tag(s) from on object to another.
For example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;Copy Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;description&lt;/span&gt;&lt;/tt&gt; tag from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Move Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;description&lt;/span&gt;&lt;/tt&gt; tag from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Move Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tag from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt;
while moving it into her private namespace (on the destination object).&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Rename or duplicate tags on one an object or a set of objects.
For example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;Rename Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tag on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt; as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;star-rating&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Copy Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tag on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;star-rating&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Move Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tag on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private/rating&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Perform any of the above operations on &lt;em&gt;all&lt;/em&gt; objects Alice has
tagged with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/personal&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Systematically move tags from objects using on about tag convention
to those using another.   For example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;Move all Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tags on objects she has tagged with
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/city&lt;/span&gt;&lt;/tt&gt; to corresponding objects with the same &lt;em&gt;about&lt;/em&gt; tag,
but preceded by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:&lt;/span&gt;&lt;/tt&gt; (e.g. from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Alice might also be interested in exchanging information between her local
file system and Fluidinfo.   (In this case, we would probably support
only copying, not movement, in much the same way as there is no &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rmv&lt;/span&gt;&lt;/tt&gt;
command, and indeed even drag on drop usually copies rather than moves
when source and destination are different volumes or hosts.)
Examples of upload and download to and from Fluidinfo might include&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Copy a local set of files to an object.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;Copy the files and directories in Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~alice/blog&lt;/span&gt;&lt;/tt&gt; directory
as corresponding tags and namespaces on the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Alice's&lt;/span&gt; &lt;span class="pre"&gt;Blog&lt;/span&gt;&lt;/tt&gt;
object in Fluidinfo.&lt;/li&gt;
&lt;li&gt;The same operation, but now taking the files from
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~alice/blogs/drinkingblog/html&lt;/span&gt;&lt;/tt&gt; and placing them in a new
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/blog&lt;/span&gt;&lt;/tt&gt; namspace on the same nominated object&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Conversely, Alice might wish to download a blog, stored as a collection
of tags and namespaces in Fluidinfo as a set of local files—the precise
inverse of the cases above.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Download tags from a number of objects in Fluidinfo to different parts of
the local file system.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;Alice might have a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;description&lt;/span&gt;&lt;/tt&gt; tag on objects corresponding
to each element of the periodic table and wish to download them
either to different local directories or different files within
a directory.   For example, she might want the description from
the element &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;element:mercury&lt;/span&gt;&lt;/tt&gt; to go to
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;elements/mercury/description.txt&lt;/span&gt;&lt;/tt&gt; or to
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;elements/mercury-description&lt;/span&gt;&lt;/tt&gt; on the local file system.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Again, conversely, Alice might wish to upload a directory structure,
taking one or more of the upper levels of the directory structure
either as object specifiers or tags in some systematic way.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;It is unlikely that the first version of any &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; analogue in Fish
will support all of these fully, but it is useful to think about what our
aspirations might be.&lt;/p&gt;
&lt;p&gt;Still another case might be to map between the contents of a local
file (e.g. a CSV file) and a set of objects in Fluidinfo.  However, I
currently regard that as a separate kind of task, and not really
suitable for analogues of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="lessons-from-rcp-rsync-scp-etc"&gt;
&lt;h2&gt;Lessons from rcp, rsync, scp etc.&lt;a class="headerlink" href="#lessons-from-rcp-rsync-scp-etc" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have argued that Fluidinfo objects (which represent &lt;em&gt;things&lt;/em&gt;)
can usefully be viewed as analogues of hosts (computers) with
Unix File systems.   That immediately suggests that we might usefully
look to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; and its variants (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rsync&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;scp&lt;/span&gt;&lt;/tt&gt; and possibly &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ftp&lt;/span&gt;&lt;/tt&gt;)
for inspiration.&lt;/p&gt;
&lt;p&gt;The basic addressing scheme in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; simply identifies a remote file as&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;host:path/to/file.ext&lt;/span&gt;&lt;/tt&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Fr example, to copy a file &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;drink.me&lt;/span&gt;&lt;/tt&gt; from a host &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;wonderland&lt;/span&gt;&lt;/tt&gt;,
Alice can say, for example:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;rcp wonderland:drink.me .&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In fact, in normal use, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; can replace &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt;, solong as your
file names don&amp;#8217;t contain colons.   In the case of Fluidinfo,
we won&amp;#8217;t introduce a different command at this stage but will simply
extend &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; (though later we will propose adding an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; for
different purposes).&lt;/p&gt;
&lt;p&gt;Remembering that we are mapping hosts to Fluidinfo objects, which are
usually identified by their &lt;em&gt;about&lt;/em&gt; tags, this suggests we might
naïvely consider a directly similar &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt;-like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; command for
Fluidinfo.  The first use case we suggested for Alice was copying her
description from the object for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paris&lt;/span&gt;&lt;/tt&gt; to the object for
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt;.   So that might be:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp paris:description city:paris:description&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Unfortunately, in this particular case the &amp;#8220;solution&amp;#8221; doesn&amp;#8217;t work
well because the target &lt;em&gt;about&lt;/em&gt; tag includes a colon.  Obviously, in
principle, we could escape the colon in some way.  If we did the
&amp;#8216;obvious&amp;#8217; thing of escaping with a backslash, and were typing
into an interactive Fish shell (rather than from the command line),
that would mean we would need to type:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp paris:description city\:paris:description&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;which is already tedious. However, if we were working from a Unix
shell, which itself uses backslash for escaping, we would need to use
either&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp paris:description city\\:paris:description&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or perhaps&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp paris:description 'city\:paris':description&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is OK in principle, but would get very tiresome (and be rather
error-prone) in practice, particularly since colons are widely used in
&lt;em&gt;about&lt;/em&gt; tags.&lt;/p&gt;
&lt;p&gt;Another option we might consider is to use Fluidinfo&amp;#8217;s full path
convention.   Recall that the value for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/description&lt;/span&gt;&lt;/tt&gt;
on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paris&lt;/span&gt;&lt;/tt&gt; is available at&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://fluiddb.fluidinfo.com/about/paris/alice/description&lt;/span&gt;&lt;/tt&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;So it might seem promising to base things on that.
Our &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; command would then look something like:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp /about/paris/alice/description /about/city:paris/alice/description&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Unfortunately, that doesn&amp;#8217;t look too promising either.
First, Fish already uses a leading slash to introduce absolute
paths to other users&amp;#8217; tags (allowing Alice can omit &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/&lt;/span&gt;&lt;/tt&gt;
from her own tags, a significant convenience, that it would be
awkward to retain using this scheme).&lt;/p&gt;
&lt;p&gt;Perhaps worse, however, is that one of the most common kinds of
&lt;em&gt;about&lt;/em&gt; tags is a URL.   That would cause real pain getting an
&lt;em&gt;about&lt;/em&gt; tag through the shell with the slashes protected as part
of a path such as above.   Imagine having to say:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp /about/http:\\/\\/example.com\\/foo\\/bar/description /about/http:\\/\\/example.com\\/foo\\/bas&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is not really a problem for the API, where the &lt;em&gt;about&lt;/em&gt; tag
typically gets passed into some function separately and escaped
automatically by the machine, but it would be a significant
inconvenience for a Fish user.&lt;/p&gt;
&lt;p&gt;An alternative that might work better is to swap the host and the path.
A colon still wouldn&amp;#8217;t make a good separator since colon is a legal
character in a tag name, and it would be confusing to reverse &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt;&amp;#8216;s
convention anyway.   We could, however, use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;&lt;/span&gt;&lt;/tt&gt;, which would perhaps
seem more natural in that order.   So Alice might say:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp description@paris description@city:paris&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I think I remember using that as an alternative form with some version
of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt;, but I can&amp;#8217;t see it in the documentation for any version
I&amp;#8217;m currently using, so I may be mistaken.  Nevertheless, the form
does feel reasonably natural from both &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;&lt;/span&gt;&lt;/tt&gt;&amp;#8216;s use in email addresses
and its more general use to mean &amp;#8220;at&amp;#8221;.   Although the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;&lt;/span&gt;&lt;/tt&gt; is used
in reasonably common about tags (particularly Twitter names),
it doesn&amp;#8217;t really cause a problem, since it is not a valid character
in a tag name.   It would be fine to say:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp chess@@RedQueen chess@@WhiteQueen&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;since the second &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;&lt;/span&gt;&lt;/tt&gt;, in each case, it clearly part of the object
identifier. This feels like the first contender.&lt;/p&gt;
&lt;p&gt;Another possibility we might mention is specifying objects using
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-i&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-q&lt;/span&gt;&lt;/tt&gt;, as is possible with other Fish commands such
as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tag&lt;/span&gt;&lt;/tt&gt;.  The issue with that is that it only works well if all the
tags are on the same object.  We could have either repeated flags or
different names flags for source and destination, but if we want to
allow Unix-like&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv src1 src2 ... srcN dest&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;that will be less good.   But it might be useful for some cases,
particularly when the source and destination objects are the same.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s try some other examples from our shopping list, keeping in
mind the possibility of using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-q&lt;/span&gt;&lt;/tt&gt; etc. as well as the
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;&lt;/span&gt;&lt;/tt&gt; convention:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Move Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;description&lt;/span&gt;&lt;/tt&gt; tag from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp description@paris description@city:paris&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or potentially:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp description@paris @city:paris&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Move Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tag from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt;
while moving it into her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; namespace (on the destination object).&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp rating@paris private/rating@city:paris&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Rename Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tag on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt; as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;star-rating&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv rating@city:paris star-rating@city:paris
mv -a city:paris rating star-rating
mv -q 'fluiddb/about matches "city:paris"' rating star-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We could also allow a trailing at to mean &amp;#8216;the same as last time&amp;#8217;
on the second or subsequence use, so that&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv rating@city:paris star-rating@&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;might be acceptable, or even just&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv rating@city:paris star-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Copy Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tag on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;star-rating&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp rating@city:paris star-rating@city:paris
cp rating@city:paris star-rating@
cp rating@city:paris star-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Move Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tag on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private/rating&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv rating@city:paris private/rating@city:paris
mv rating@city:paris private/rating@
mv rating@city:paris private/rating
mv -a 'city:paris' rating private/rating&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Perform any of the above operations on all objects alice has
tagged with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/personal&lt;/span&gt;&lt;/tt&gt;.   For example, let&amp;#8217;s take
the moving of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private/star-rating&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv -q 'has alice/personal' rating private/star-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;We could also do the same thing with namespaces, though I didn&amp;#8217;t
list that as an example.   But it seem fairly clear that&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp -q 'has alice/personal' private secret&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or perhaps&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp -q 'has alice/personal' -r private secret&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;would mean copy all the tags under personal to a new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;secret&lt;/span&gt;&lt;/tt&gt;
namespace (if it doesn&amp;#8217;t exist) or to under &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;secret&lt;/span&gt;&lt;/tt&gt; if it does.
[The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-r&lt;/span&gt;&lt;/tt&gt; would mean recurse, as with cp, but whether it should
be required I&amp;#8217;m not sure.]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Move all Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tags on objects she has tagged with
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city&lt;/span&gt;&lt;/tt&gt; to corresponding objects with the same &lt;em&gt;about&lt;/em&gt; tag,
but preceded by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:&lt;/span&gt;&lt;/tt&gt; (e.g. from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paris&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;city:paris&lt;/span&gt;&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;This one is completely different and is probably something we
need to admit defeat on for now.   Though it is not the same,
it reminds me of a Unix command I&amp;#8217;ve always thought was missing,
which is a pattern-based bulk rename (and bulk copy).   I actually
have to allow systematic renaming of files using commands like:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;bmv foo@.txt bar@.txt&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;which in which the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;&lt;/span&gt;&lt;/tt&gt; is a wildcard and on the right has the same value
as that on the left (like a tagged regular expression).   So if
a directory had &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;food.txt&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fool.txt&lt;/span&gt;&lt;/tt&gt;, this would match
rename &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;food.txt&lt;/span&gt;&lt;/tt&gt; as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bard.txt&lt;/span&gt;&lt;/tt&gt;, and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fool.txt&lt;/span&gt;&lt;/tt&gt; as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;barl.txt&lt;/span&gt;&lt;/tt&gt;.
Systematic construction of &lt;em&gt;about&lt;/em&gt; tags could follow a similar pattern,
but useful though it would be, is probably out of scope here.&lt;/p&gt;
&lt;p&gt;I can, however, imagine allowing a more manual version.
For example, we might allow braces and a syntax like:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp rating@{foo,bar,baz} star-rating@{Foo,Bar,Baz}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;to move and rename tags from things like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;foo&lt;/span&gt;&lt;/tt&gt;
to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;star-rating&lt;/span&gt;&lt;/tt&gt; on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Foo&lt;/span&gt;&lt;/tt&gt; etc.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Although perhaps not pretty, this &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;&lt;/span&gt;&lt;/tt&gt; syntax, combined with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt;,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-i&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-q&lt;/span&gt;&lt;/tt&gt; flags (for when the same object is to be used both sides
of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;) seems to get us a long way.   Adding in
paired lists in the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;{a,b,c}&lt;/span&gt;&lt;/tt&gt; form would go a step further.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="upload-and-download"&gt;
&lt;h2&gt;Upload and Download&lt;a class="headerlink" href="#upload-and-download" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ironically, although we modelled our extended &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt;,
we have concluded that we don&amp;#8217;t really need the &amp;#8220;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;r&lt;/span&gt;&lt;/tt&gt;&amp;#8221; but can just use
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; for all copying and movement &lt;em&gt;within&lt;/em&gt; Fluidinfo.   Curiously,
this leaves open the possibility of using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; to perform upload
and download.   The idea would be that paths without an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;&lt;/span&gt;&lt;/tt&gt;
in the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; command would be taken as paths on the local file system
while paths that include an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;&lt;/span&gt;&lt;/tt&gt; refer to tags on an object in Fluidinfo.&lt;/p&gt;
&lt;p&gt;In case it&amp;#8217;s not clear, the key point is that since Fluidinfo tags can
have arbitrary MIME types, they can be used to store files: the
analogy we have been pursuing is not merely structural.  For example,
the &lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;documentation for Fish&lt;/a&gt; is stored
in Fluidinfo, as a collection of tags on the object with the &lt;em&gt;about&lt;/em&gt;
tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;, with its &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;index.html&lt;/span&gt;&lt;/tt&gt; file at&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;http://fluiddb.fluidinfo.com/about/fish/fish/index.html&lt;/a&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The be completely clear, this is not a URL pointing to a static HTML
file: this is the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user&amp;#8217;s tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;index.html&lt;/span&gt;&lt;/tt&gt; on the object
with the &lt;em&gt;about&lt;/em&gt; tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;, being retrieved directly from the Fluidinfo
database.&lt;/p&gt;
&lt;p&gt;A partial visualization of the tags on that object is shown below.&lt;/p&gt;
&lt;img alt="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at103-tree.gif" src="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at103-tree.gif" /&gt;
&lt;p&gt;The point of commands for uploading to Fluidinfo is to make it easy to publish
a tree of files such as this.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s see how the example use cases for upload and download might work
in this case.   I am going to assume that we have no difficult cases
with ambiguous paths in Fluidinfo, and that if we were to we would either
require disambiguation or the commands would fail.   (This would obviously
be an issue only on download.)&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;dl class="first docutils"&gt;
&lt;dt&gt;Copy a local set of files to an object.&lt;/dt&gt;
&lt;dd&gt;&lt;ul class="first last"&gt;
&lt;li&gt;&lt;p class="first"&gt;Copy the files and directories in Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~alice/blog&lt;/span&gt;&lt;/tt&gt; directory
as corresponding tags and namespaces on the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Alice's&lt;/span&gt; &lt;span class="pre"&gt;Blog&lt;/span&gt;&lt;/tt&gt;
object in Fluidinfo.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;rcp blog blog@"Alice's Blog"&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The same operation, but now taking the files from
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~alice/blogs/drinkingblog/html&lt;/span&gt;&lt;/tt&gt; and placing them in a new
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/blog&lt;/span&gt;&lt;/tt&gt; namspace on the nominated object&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;rcp ~alice/blogs/drinkingblog/html blog@"Alice's blog"&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Conversely, Alice might wish to download a blog, stored as a collection
of tags and namespaces in Fluidinfo as a set of local files,
the precise inverse of the cases above.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;rcp blog@"Alice's Blog" blog
rcp blog@"Alice's blog" ~alice/blogs/drinkingblog/html&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Download tags from a number of objects in Fluidinfo to different parts of
the local file system.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Alice might have a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;description&lt;/span&gt;&lt;/tt&gt; tag on objects corresponding
to each element of the periodic table and wish to download them
either to different local directories or different files within
a directory.   For example, she might want the description from
the element &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;element:mercury&lt;/span&gt;&lt;/tt&gt; to go to
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;elements/mercury/description.txt&lt;/span&gt;&lt;/tt&gt; or to
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;elements/mercury-description&lt;/span&gt;&lt;/tt&gt; on the local file system.&lt;/p&gt;
&lt;p&gt;This is a more interesting and difficult case, and again is
fundamentally about constructing paths semi-programmatically.
Although it is not too hard to think of ways it might be done
(perhaps with regular expressions), we might be moving beyond
what it&amp;#8217;s reasonabe to expect Fish to do.   That goes for
the final example too.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;These examples suggest that modelling a Fish &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; command on
a modified Unix-like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; could work well.   It&amp;#8217;s almost as
if we are considering our host machine as part of Fluidinfo,
with its file system representing a concrete tag hierarchy
on an anonymous local object.   There are certainly other issues
to consider, including MIME types and files for potential omission
(dot files? backup files ending in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~&lt;/span&gt;&lt;/tt&gt;, symbolic links etc.),
but we seem to have a promising way forward.&lt;/p&gt;
&lt;p&gt;I was going to consider &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ftp&lt;/span&gt;&lt;/tt&gt; as an alternative source of inspiration,
but its model seems more cumbersome in general, and better suited to
situations where you can considering only one host, whereas in Fluidinfo
it is normal to consider many objects, so I think we can probably forget
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ftp&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="summary"&gt;
&lt;h2&gt;Summary&lt;a class="headerlink" href="#summary" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Perhaps surprisingly, we have largely got there.&lt;/p&gt;
&lt;p&gt;Over the last three articles, we have probed and extended the
analogy between Fluidinfo and the Unix file system and come up with
plausible syntaxes for building &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; commands that give
us pretty powerful ways of moving and copying data within Fluidinfo,
drawing on ideas from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rsync&lt;/span&gt;&lt;/tt&gt; as well
as the current Fish.&lt;/p&gt;
&lt;p&gt;Despite borrowing from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; in designing Fish&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; command,
we had left &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; itself free and can now use it as the basis for
moving data between a local file system and Fluidinfo, using almost
identical conventions save for the interpretation of a path
that does not contain an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;#64;&lt;/span&gt;&lt;/tt&gt; (&amp;#8220;the same as object as before&amp;#8221; for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt;,
and &amp;#8220;the local file system&amp;#8221; for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;There are definitely holes to fill, but it feels like there is a reasonable
outline spec.   If people see problems, or have better ideas or comments,
do let me know.&lt;/p&gt;
&lt;p&gt;Otherwise, all the remains is the trivial task of implementation.
How hard could that be?&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-8392235636518904577?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/8392235636518904577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2012/01/tags-tagosphere-and-every-thing-towards.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/8392235636518904577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/8392235636518904577'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2012/01/tags-tagosphere-and-every-thing-towards.html' title='Tags, The Tagosphere and Every Thing: Towards an rcp for Fish'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-3779918808166988725</id><published>2012-01-19T14:52:00.000Z</published><updated>2012-01-19T14:52:09.166Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mv'/><category scheme='http://www.blogger.com/atom/ns#' term='copy'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='file'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='rename'/><category scheme='http://www.blogger.com/atom/ns#' term='system'/><category scheme='http://www.blogger.com/atom/ns#' term='move'/><category scheme='http://www.blogger.com/atom/ns#' term='cp'/><title type='text'>Movement and Copying in Fluidinfo</title><content type='html'>&lt;div class="section" id="movement-and-copying-in-fluidinfo"&gt;
&lt;blockquote&gt;
&lt;em&gt;In the&lt;/em&gt; &lt;a class="reference external" href="http://last.last"&gt;previous article&lt;/a&gt;, &lt;em&gt;we discussed the
analogy between the Unix File System and Fluidinfo&amp;#8217;s tag hierarchy.
This analogy forms the basis and inspiration for the Fluidinfo Shell,&lt;/em&gt;
&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;Fish&lt;/a&gt;.
&lt;em&gt;But a file system without move and copy commands would be a sad
and contemptible thing, and at the moment Fish, like Fluidinfo,
is impoverished by the lack of such basic functionality as&lt;/em&gt;
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;and&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;.   &lt;em&gt;Here we will try to design such functionality,
building on the analogy.&lt;/em&gt;&lt;/blockquote&gt;
&lt;div class="section" id="copying-and-moving"&gt;
&lt;h2&gt;Copying and Moving&lt;a class="headerlink" href="#copying-and-moving" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In Unix we can&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;copy files with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; command&lt;/li&gt;
&lt;li&gt;copy directories (and their contents) with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt; &lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;move files to a different location with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;move directories (and their contents) to a different location with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;rename files, also with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; command&lt;/li&gt;
&lt;li&gt;rename directories with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;delete files with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; (&amp;#8220;remove&amp;#8221;)&lt;/li&gt;
&lt;li&gt;delete empty directories with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rmdir&lt;/span&gt;&lt;/tt&gt; command and
delete directories together with their contents
with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt; &lt;span class="pre"&gt;-r&lt;/span&gt;&lt;/tt&gt; command.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;In general, the functionality of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; is conceptually equivalent
to copying and then removing an item.&lt;/p&gt;
&lt;p&gt;We can also copy files and directories between different machines
using the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rsync&lt;/span&gt;&lt;/tt&gt; commands, which are both similar to
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; but understand a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;host:&lt;/span&gt;&lt;/tt&gt; prefix.  An alternative to these
commands is the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ftp&lt;/span&gt;&lt;/tt&gt; command, which operates in a very different
manner, and uses different mechanisms, to ultimately similar effect.&lt;/p&gt;
&lt;p&gt;Fish, today, offers no commands for moving, renaming or copying tags
or namespaces, but does provide an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; command that performs the
combined functions of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rmdir&lt;/span&gt;&lt;/tt&gt; (also requiring a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-r&lt;/span&gt;&lt;/tt&gt;
and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; flags in some cases).   It is worth noting, briefly,
that in some sense Fish&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; goes much further than &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; on
Unix, in that the command&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish rm rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;removes not only the abstract &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; tag, but &lt;em&gt;every occurrence&lt;/em&gt;
of that tag in Fluidinfo, potentially on millions of objects.
This is why Fish requires the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; flag to force the removal
of a tag that is in use.   In the prevous article, we argued that
Fluidinfo&amp;#8217;s objects play the natural analogues of computers in a network.
From that perspective, if we think of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; as a more powerful
version &lt;em&gt;remote&lt;/em&gt; version of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt;, Fish&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; command is more like
a remote &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; (presumably &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rrm&lt;/span&gt;&lt;/tt&gt;) that allows you to remove all files with
a given path on all hosts simultaneously.   It&amp;#8217;s as if you could say
something like:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;rrm -f *:~/.bashrc&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;to remove the .bashrc in your home directory on every machine on which
you have an account.   Indeed, if Linus Torvalds were not merely Linux&amp;#8217;s
creator but the superuser on all copies of the OS, with such a command he
could remove everything on all Linux hosts with&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;rrm -rf *:/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Let&amp;#8217;s think about the Unix commands &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;, and their
possible generalizations to the realm of Fluidinfo.  Recall that, when
we want to be precise, we need to distinguish between two different
senses of the word &amp;#8220;tag&amp;#8221;.  Ordinarily when we attach a tag, possibly
with a value, to an object, we create what we might variously call a
&amp;#8220;tag instance&amp;#8221; or a &amp;#8220;concrete tag&amp;#8221;.  Fluidinfo, however, maintains a
user&amp;#8217;s tag hierarchy independent of whether tags are actually in use.
When discussing tags in this sense, independent of objects, I call
them &lt;em&gt;abstract&lt;/em&gt; or &lt;em&gt;platonic tags&lt;/em&gt;.  These are quite real and can
persist even when the tag is not in use.  The diagram below shows the
abstract tag hierarchy for Alice, on the right, and her file system,
on the left.  Note carefully that in her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; namespace Alice
has both a tag and a namespace called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;moments&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;img alt="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at102-tags.png" src="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at102-tags.png" /&gt;
&lt;p&gt;In what follows, assume Alice&amp;#8217;s current working directory on Unix is
her home directory &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/home/alice&lt;/span&gt;&lt;/tt&gt;, and for concreteness,
assume that her shell is the &lt;em&gt;Bourne Again Shell,&lt;/em&gt; Bash.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="copying-a-file-or-a-tag"&gt;
&lt;h2&gt;Copying a file or a tag&lt;a class="headerlink" href="#copying-a-file-or-a-tag" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On Unix, Alice can copy her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;has-drunk&lt;/span&gt;&lt;/tt&gt; file into her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; directory
by saying any of the following:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp has-drunk private/has-drunk
cp has-drunk private/
cp has-drunk private&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Obvious though it is, let us spell out what this means.  After running
one of these commands, Alice will have two files,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/home/alice/has-drunk&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/home/alice/private/has-drunk&lt;/span&gt;&lt;/tt&gt;, where
previously she had only one, and each will contain a separate copy of
the same data.&lt;/p&gt;
&lt;p&gt;We could plausibly adopt any or all of these in Fish to copy Alice&amp;#8217;s
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;has-drunk&lt;/span&gt;&lt;/tt&gt; tag to her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; namespace.   But what would that do?
I think the most obvious action would be to create a new
abstract tag called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/private/has-drunk&lt;/span&gt;&lt;/tt&gt; and then tag all
the objects currently tagged with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/private/has-drunk&lt;/span&gt;&lt;/tt&gt; with the new
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/private/has-drunk&lt;/span&gt;&lt;/tt&gt; tag, copying their values if any.
We would need to consider quite carefully how to handle permissions
when performing such copying.
The case is rather different from Unix, because in Unix permissions
are hierarchical in the sense that a file with public read permission
in an fully private directory cannot be read.   This is an important detail.
On Unix, let&amp;#8217;s assume that Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private/things&lt;/span&gt;&lt;/tt&gt; file has open read
permissions (644):&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;alice$ ls -l private/things
-rw-r--r--  1 alice  staff   0 17 Jan 18:57 things&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and that she then locks her private directory so that only even she can
look at it.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;alice$ chmod 700 private&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If Bert now trys to look at &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alice/private/things&lt;/span&gt;&lt;/tt&gt; he will find that he
cannot:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;bert$ cat ~alice/private/things
cat: /home/alice/private/things: Permission denied&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In particular, on Unix this means that if Alice moves a non-private file to
a private directory (by which I mean, one with neither read nor execute
permission) it becomes unreadable.&lt;/p&gt;
&lt;p&gt;In Fluidinfo, the permissions hierarchy is consulted only when new
tags and namespaces are created.  So if Alice creates a new tag in her
private namespace, it will default to being private; if we copy the
permissions of a tag when copying the tag, its permissions will be
unaltered, and potentially different from if we created the tag afresh
in the new location.&lt;/p&gt;
&lt;p&gt;The correct behaviour is not clear, and either way there is potential for
surprising the user in unpleasant ways, most obviously by making public
data that the user intended to be private.   We have seen above how
by copying permissions with tags we could violate a (reasonable)
assumption that moving a tag into a private namespace would make it private.
If we fail, however, to copy permissions, copying a private tag to a
non-private namespace would result in a non-private tag, which might also
be a nasty surprise.&lt;/p&gt;
&lt;p&gt;My first inclination here is to do a &amp;#8220;reverse Facebook&amp;#8221; by, when in doubt,
setting the permissions on the destination to the &lt;em&gt;more restrictive&lt;/em&gt; of
the two possibilities, on the assumption that revealing data that
Alice wanted to keep private is both worse and less correctable than
making data more private than intended, given the inability to make
people unsee (or even, uncopy) things.  Needless to say, we could also
have options to allow the user to choose what behaviour she wants.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Q1. &lt;em&gt;How should permissions behave when tags and namespaces are copied
or moved?   Should we go for:&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;The permission of the destination is copied from the source?&lt;/li&gt;
&lt;li&gt;We follow &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;rm&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;cp&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; and create the new tag
or namespace in the new location according to default rules?&lt;/li&gt;
&lt;li&gt;Maximum privacy: apply the more restrictive of the permissions
suggested by a. and b. (or, if necessary, their most restrictive
intersection).&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="moving-or-renaming-a-file-or-a-tag"&gt;
&lt;h2&gt;Moving or renaming a file or a tag&lt;a class="headerlink" href="#moving-or-renaming-a-file-or-a-tag" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Going back to Unix, Alice can move her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;has-drunk&lt;/span&gt;&lt;/tt&gt; file from her
home directory to her private directory with any of these commands:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv has-drunk private/has-drunk
mv has-drunk private/
mv has-drunk private&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Again, we could plausibly adopt all of these forms in Fish to move
Alice&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;has-drunk&lt;/span&gt;&lt;/tt&gt; name to her private namespace.   In this case,
there seems no real issue about what should happen.   We can&amp;#8217;t sensibly
&amp;#8220;move&amp;#8221; the abstract tag but not the concrete ones.   Using our rule
of thumb that&lt;/p&gt;
&lt;blockquote&gt;
&lt;em&gt;move&lt;/em&gt; = &lt;em&gt;copy to new location&lt;/em&gt; + &lt;em&gt;remove the original&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;blockquote&gt;
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt; &lt;span class="pre"&gt;src&lt;/span&gt; &lt;span class="pre"&gt;dest&lt;/span&gt;&lt;/tt&gt; = &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt; &lt;span class="pre"&gt;src&lt;/span&gt; &lt;span class="pre"&gt;dest;&lt;/span&gt; &lt;span class="pre"&gt;rm&lt;/span&gt; &lt;span class="pre"&gt;src&lt;/span&gt;&lt;/tt&gt;&lt;/blockquote&gt;
&lt;p&gt;this reinforces the case for making &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; copy all the concrete tags
as well as the abstract tag.&lt;/p&gt;
&lt;p&gt;Renaming really raises no extra issues: just as in Unix Alice can rename
here &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;has-drunk&lt;/span&gt;&lt;/tt&gt; tag to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;drunk&lt;/span&gt;&lt;/tt&gt; with a simple&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv has-drunk drunk&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;she should be able to rename her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;has-drunk&lt;/span&gt;&lt;/tt&gt; abstract tag as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;drunk&lt;/span&gt;&lt;/tt&gt;
with the same command in Fish, and in the process rename all its concrete
instances.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="copying-and-moving-and-renaming-directories"&gt;
&lt;h2&gt;Copying and Moving and Renaming Directories&lt;a class="headerlink" href="#copying-and-moving-and-renaming-directories" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;What about copying a directory in Unix?   We use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; for that, but now
we need to use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt; to force the directory and &lt;em&gt;all its contents&lt;/em&gt;
to be copied recursively: without this &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt;, we can&amp;#8217;t even copy
and empty directory such as things:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ cp things thangs
cp: things is a directory (not copied).&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;But with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt;, we can copy a directory hierarchy as easily as a file.
Let&amp;#8217;s suppose Alice wants a duplicate of her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; directory
in her things directory.   She can use any of&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp -R private things
cp -R private things/
cp -R private things/private
cp -R private things/private/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and the result will be a duplicate:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ ls -RF things
private/

things/private:
moments/      things          thoughts/

things/private/moments:

things/private/thoughts:&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Move works essentially the same way and needs no example.   Again, so far
there seems to be no reason why we shouldn&amp;#8217;t build analogous functionality
in Fish for copying and moving namespaces and their contents.
We would certainly allow the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt; flag, but might not require it,
and would certainly allow &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-r&lt;/span&gt;&lt;/tt&gt; to be used as a synonym.
As with copying simple files, and following our &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;cp&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; dictum,
concrete tags in the hierarchy would be copied, together with their values,
on all objects to which they are attached.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="clobbering"&gt;
&lt;h2&gt;Clobbering&lt;a class="headerlink" href="#clobbering" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now consider the following commands on Unix, in the context of the same
directory structure shown in the original figure:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp has-drunk private/things
mv has-drunk private/things&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The destination, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private/things&lt;/span&gt;&lt;/tt&gt; is a file that already exists: it
will be &lt;em&gt;clobbered&lt;/em&gt; (overwritten) by both &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;.  The same
would be true if Alice copied her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private/moments/things&lt;/span&gt;&lt;/tt&gt; file to
her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; directory with any of&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;cp private/moments/things private
cp private/moments/things private/
cp private/moments/things private/things&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or their &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; counterparts.   So in Unix, the rule is&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When the destination specified is a directory, move or copy the source
into that directory.   If there was already a file with that name in
the directory, delete it first.&lt;/p&gt;
&lt;p&gt;When the destination specified is a file, first remove that file
if it exists, then copy or move the source to that destination.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Except that this isn&amp;#8217;t quite true: you can&amp;#8217;t clobber a file with a
directory.   So&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ cp -R things private/things
cp: private/things: Not a directory
cp: private/things: Not a directory
cp: private/things: Not a directory
cp: private/things: Not a directory&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;(the four failures being as each of the entities in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; fails to be
be copied), and&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ mv things private/things
mv: rename things to private/things: Not a directory&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Why can&amp;#8217;t a hulking great directory clobber a puny file? I don&amp;#8217;t know.
Unix has many wonderful attributes, but consistency is not foremost
among them.  To my surprise, even adding &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; cannot persuade the
system to do it.  Whether Fish should copy this apparently anomalous
behaviour is not completely clear to me: logic suggests
not, but fidelity to Unix conventions suggests maybe so.  The point
may be moot anyway, as there&amp;#8217;s a good chance I will require a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt;
to clobber even a tag, just as I do with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt;, if it is in use.
This is because whereas on Unix, clobbering a single file removes a
single entity, however big.  In Fluidinfo, a single abstract tag could
have a million instances or more, and I feel requiring a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; flag
to encourage the user to confirm her intent before engaging in such
(potentially) wide-spread destruction is not unreasonable.&lt;/p&gt;
&lt;p&gt;These minor exceptions notwithstanding, the way files get clobbered suggests
that we might extend our recipe to include the rule:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;If dest is a file:
   mv src dest = rm -f dest; cp -R src dest; rm -r src&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Does that make sense for tags in Fish?&lt;/p&gt;
&lt;p&gt;This, I think, is an interesting question.
We could certainly make Fish remove all the abstract destination
tag &lt;em&gt;and all its concrete tags&lt;/em&gt; before moving or copying another tag.
But it also seems reasonable to consider the possibility of replacing
those concrete tags present in the source, but &lt;em&gt;not&lt;/em&gt; those absent in the
source.&lt;/p&gt;
&lt;p&gt;To make this real: suppose Alice says (in Fish)&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ cp has-drunk moments&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and at the time she does the state of her &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;has-drunk&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;drunk&lt;/span&gt;&lt;/tt&gt;
tags is as follows:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show -q 'has alice/has-drunk' /about
2 objects matched
Object d440c5cf-9680-4748-b70e-56f07f35ca09:
  /fluiddb/about = "drink me (not poison)"
Object ec430756-e110-4bc4-b882-544afda1cce8:
  /fluiddb/about = "drink me"

$ fish show -q 'has alice/drunk' /about
2 objects matched
Object d440c5cf-9680-4748-b70e-56f07f35ca09:
  /fluiddb/about = "drink me (not poison)"
Object 49126b6d-18bd-457f-af55-a251cf400fc9:
  /fluiddb/about = "drink me not"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or, diagramatically:&lt;/p&gt;
&lt;img alt="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at102-has-drunk.png" src="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at102-has-drunk.png" /&gt;
&lt;p&gt;It seems clear that the value of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;has-drunk&lt;/span&gt;&lt;/tt&gt; tag on
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;quot;drink&lt;/span&gt; &lt;span class="pre"&gt;me&lt;/span&gt; &lt;span class="pre"&gt;(not&lt;/span&gt; &lt;span class="pre"&gt;poison)&amp;quot;&lt;/span&gt;&lt;/tt&gt; (no value) should be replaced with the
value of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;drunk&lt;/span&gt;&lt;/tt&gt; tag (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/tt&gt;), and that a new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;has-drunk&lt;/span&gt;&lt;/tt&gt; tag
should be placed on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;quot;drink&lt;/span&gt; &lt;span class="pre"&gt;me&lt;/span&gt; &lt;span class="pre"&gt;not&amp;quot;&lt;/span&gt;&lt;/tt&gt;, also with the value &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;true&lt;/span&gt;&lt;/tt&gt;.
It is less clear, however, that the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;has-drunk&lt;/span&gt;&lt;/tt&gt;
tag on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;quot;drink&lt;/span&gt; &lt;span class="pre"&gt;me&amp;quot;&lt;/span&gt;&lt;/tt&gt; needs to be deleted.
We will be moving on to discuss selective copying and moving
later anyway, but we have certainly formed a question:&lt;/p&gt;
&lt;blockquote&gt;
Q2. &lt;em&gt;If a tag is clobbered by a&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;or&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;command,
should all of its instances be clobbered, or only those necessary
to make way for the tag values from the source?&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="shared-paths"&gt;
&lt;h2&gt;Shared Paths&lt;a class="headerlink" href="#shared-paths" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Where things get more interesting is when the source or destination
is ambiguous, because it specifies both a tag and a namespace.
This can&amp;#8217;t occur in Unix, because each path resolves unambiguously
to &lt;em&gt;either&lt;/em&gt; a file &lt;em&gt;or&lt;/em&gt; a namespace.   Let&amp;#8217;s think through the cases
with the aid of our diagram of Alice&amp;#8217;s tag structure above, which I&amp;#8217;ll
repeat for easier reference (sod the cost!)&lt;/p&gt;
&lt;img alt="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at102-alicetags.png" src="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at102-alicetags.png" /&gt;
&lt;p&gt;What would Alice reasonably expect to happen if she issued the following
commands?&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv private/moments private/thoughts
mv moments private
mv moments private/moments
mv private/moments /alice&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There is ambiguity everywhere.   Both the source and the destination
can be ambiguous, so we have to consider all of:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;unambiguous source, unambiguous destination&lt;/li&gt;
&lt;li&gt;unambiguous source, ambiguous destination&lt;/li&gt;
&lt;li&gt;ambiguous source, unambiguous destination&lt;/li&gt;
&lt;li&gt;ambiguous source, ambiguous destination&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Only the first of these is straightforward.&lt;/p&gt;
&lt;p&gt;In the case of the existing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; commands in Fish,
I have taken that view that an ambiguous path refers to &lt;em&gt;both&lt;/em&gt;
the possible targets, but while this seems unobjectionable in
the case of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt;, it clearly leads to the possibility of removing
more than the user intended.  I plan to reconsider
that in the light of these ruminations on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;It seems to me that probably a better way forward than taking an
ambiguous specification as referring to both its targets is to
demand disambiguation.   The question is: how would that be achieved?&lt;/p&gt;
&lt;p&gt;I have made a point, in the examples above, of listing subtly
different alternative forms for some commands, e.g.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv has-drunk private
mv has-drunk private/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Over recent years (particularly with the rise of tab completion in shells)
it has become increasing common to allow directories to be specified
including a trailing slash, and no harm derives from this practice.
The question is we can we exploit this tend this as a way of disambiguating
between tags and namespaces.&lt;/p&gt;
&lt;p&gt;In Unix shells and commands, in most cases, the
inclusion or omission of the slash makes no difference to behaviour,
though I am aware of at least one case where this is not so—&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rsync&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;To quote from the man page for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rsync&lt;/span&gt;&lt;/tt&gt; (on Mac OS 10.6.8):&lt;/p&gt;
&lt;blockquote&gt;
A trailing slash on the source changes this behavior to avoid  creating
an  additional  directory level at the destination.  You can think of a
trailing / on a source as meaning &amp;#8220;copy the contents of this directory&amp;#8221;
as  opposed  to  &amp;#8220;copy  the  directory  by name&amp;#8221;, but in both cases the
attributes of the containing directory are transferred to the  contain-
ing  directory on the destination.  In other words, each of the follow-
ing commands copies the files in the same way, including their  setting
of the attributes of /dest/foo:&lt;/blockquote&gt;
&lt;p&gt;I personally find this behaviour bizarre and it always make me slightly
nervous, using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rsync&lt;/span&gt;&lt;/tt&gt;, which is otherwise superior in every way
to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt;.   However, the idea of using a trailing slash to specify
the namespace (cf. directory) rather than the tag is different: it is not
changing the behaviour of the command according to which of two unanambiguous
specifications of a directory (namespace) is used, but rather using the
slash to disambiguate; this seems less objectionable.&lt;/p&gt;
&lt;p&gt;The question then would be, how would unambiguously specify the tag?
It would seem very ill advised to require that namespaces should
always be specified with a trailing slash, so we cannot sensibly
say that a path &lt;em&gt;not&lt;/em&gt; ending a slash will be taken to be a tag:
that way madness lies.&lt;/p&gt;
&lt;p&gt;My temptation is to use a trailing dot.  I like this as a solution
partly because I can recall no case, in nearly thirty years of Unix
use, of ever meeting a file (other than the directories &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;.&lt;/span&gt;&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;..&lt;/span&gt;&lt;/tt&gt;) whose name ended in a dot.  I also feel that, while files do
not always have extensions, and directory names may include them, by
convention most filenames do contain a period and most directory names
do not.  Admittedly, this is not true of tags, but for me, at least,
some association between dots-in-tag-names and &amp;#8220;file-ness&amp;#8221; survives
through the analogy on which Fish is built.  If we adopt this idea,
our problems all but disappear.   We can imagine:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ mv private/moments private/thoughts
Error: private/moments is ambiguous; use private/moments. or private/moments/

$ mv private/moments. private/thoughts
# moves the tag private/moments to the tag private/thoughts/moments

$ mv private/moments/ private/thoughts
# moves the namespace private/moments to the namespace private/thoughts/moments

$ mv private/moments/ private/moments. private/thoughts
# moves private/moments. to private/thoughts/moments.
# and private/moments/ to private/thoughts/moments/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If this were adopted in Fish, I think there would be an overwhelming
case for making &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; work the same way; the current behaviour of
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt; might stay the same, as it is not descructive, or might change
in the interest of slavish consistency.&lt;/p&gt;
&lt;p&gt;That concludes our discussion of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; for abstract tags
in Fish.   In the third and perhaps final part of this &amp;#8220;trilogy&amp;#8221;, we will
discuss moving and copying tags and namespaces in the context of the
object hierarchy, i.e., how we might copy or move tags from one object
to another, or within or among objects.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-3779918808166988725?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/3779918808166988725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2012/01/movement-and-copying-in-fluidinfo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3779918808166988725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3779918808166988725'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2012/01/movement-and-copying-in-fluidinfo.html' title='Movement and Copying in Fluidinfo'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-3896969857831866716</id><published>2012-01-17T21:03:00.000Z</published><updated>2012-01-17T21:03:22.537Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='fish fluidinfo unix file system cp mv'/><title type='text'>Like ℵ0 File Systems for Everyone</title><content type='html'>&lt;div class="section" id="like-0-file-systems-for-everyone"&gt;
&lt;blockquote&gt;
&lt;em&gt;If the ideal blog post is but a screenful or two, this one fails
rather badly.   So badly, in fact, that I&amp;#8217;ve decided to split it
into three, each of which will itself be amply proportioned.
This post discusses the analogy between the Unix File System
and Fluidinfo, as a way of preparing the ground for the following posts.
The second post will build on that to discuss options for syntax&lt;/em&gt;
of potential &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;and&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;commands in Fish.
The final post in the series will discuss&lt;/em&gt;
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;upload&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;and&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;download&lt;/span&gt;&lt;/tt&gt;, &lt;em&gt;or maybe&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rsync&lt;/span&gt;&lt;/tt&gt;
&lt;em&gt;and&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ftp&lt;/span&gt;&lt;/tt&gt;; &lt;em&gt;as well as possibly&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fsync&lt;/span&gt;&lt;/tt&gt;,
&lt;em&gt;i.e., commands for copying parts of a local file system to
or from Fluidinfo.&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;Everyone loves the Unix File System, even through the
expletives we utter at those moments when our ardour is temporarily
diminished.&lt;/p&gt;
&lt;p&gt;The Fluidinfo Shell,
&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;Fish&lt;/a&gt;,
is largely built on the idea of mapping Fluidinfo
namespaces to Unix directories, tags to files, and tag values to the
contents of files.  Fish&amp;#8217;s commands are mostly constructed with close and
deliberate reference to corresponding Unix commands.&lt;/p&gt;
&lt;img alt="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at101-FSvsFluidinfo.png" src="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at101-FSvsFluidinfo.png" /&gt;
&lt;p&gt;Fluidinfo and Unix diverge in several small and one large way when
viewed through the lens of this analogy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;In Unix, a path (such as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/Users/njr/foo&lt;/span&gt;&lt;/tt&gt;) resolves either to a file
or to a directory, but not both; in Fluidinfo, a file and
a namespace may share a path.   This difference causes a number
of complications in mapping Unix commands to Fluidinfo.&lt;/li&gt;
&lt;li&gt;In Unix, &lt;em&gt;full&lt;/em&gt; paths begin with a slash (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/&lt;/span&gt;&lt;/tt&gt;) and the Unix
kernel works only with such full paths. The shell maintains a notion of
a &lt;em&gt;current working directory&lt;/em&gt; and allows the user to refer to
files relative to that.  The &lt;em&gt;Fluidinfo Shell&lt;/em&gt;, Fish,
does something similar in the context of Fluidinfo, but effectively
clamps the working directory to the user&amp;#8217;s home namespace
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt;, in my case).&lt;/li&gt;
&lt;li&gt;To a first approximation, Unix provides only a &lt;em&gt;single&lt;/em&gt;
hierarchical file structure for each user: Fluidinfo provides an
infinite number of them—one for every possible &lt;em&gt;about&lt;/em&gt; tag text
and one for each UUID.  (There are 2&lt;sup&gt;128&lt;/sup&gt;, or some 340
decillion = 3.4 ⨉ 10&lt;sup&gt;38&lt;/sup&gt;, UUIDs).  It is this infinite
number of potential &lt;em&gt;about&lt;/em&gt; tags motivates the title of this
piece: ℵ&lt;sub&gt;0&lt;/sub&gt; (&amp;#8220;aleph zero&amp;#8221;) is the smallest infinity—the
number of counting numbers.  Non-mathematicians may be unaware,
and skeptical, of the idea that there can be infinities of
different sizes, but thanks the remarkable work of Georg Cantor,
we can be quite confident that this is so. Infinite sets require
some care, and have surprising properties: for example, ℵ&lt;sub&gt;0&lt;/sub&gt; is not only the number of &lt;em&gt;positive&lt;/em&gt; whole numbers, but
also the number of whole numbers (positive and negative).  Even
the number of rational numbers (fractions) is the same.  It is
only when we add in the &lt;em&gt;irrationals&lt;/em&gt;, to form the &lt;em&gt;real&lt;/em&gt; numbers,
which are vastly more numerous than the rationals, that we get a
larger cardinal, ℵ&lt;sub&gt;1&lt;/sub&gt;.  Needless to say, while Fluidinfo
does &lt;em&gt;in principle&lt;/em&gt; offer ℵ&lt;sub&gt;0&lt;/sub&gt; tag hierarchies to each
user, just as real-world Turing machines are limited by the
inability of Maxell to supply an infinite tape, the maximum
possible size of Fluidinfo itself is limited by the physical
properties of the universe, not to mention the finite capacity of
even Amazon&amp;#8217;s &lt;em&gt;Simple Storage System&lt;/em&gt;, S3.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is this last difference—a tag hierarchy for each Fluidinfo
object—that is most significant.  One way of thinking about it is
this: on Unix (at least considering a single host, with a single file
system, in isolation) there is a single directory hierarchy containing
everything, as illustrated on the left in the diagram below.&lt;/p&gt;
&lt;p&gt;In contrast, we can think of Fluidinfo as having a tag hierarchy,
with (potentiall) different tag values for the same tag,
on each of a very large number of objects.&lt;/p&gt;
&lt;p&gt;Some tags in the tag heirarchy are present on many objects, others on
only one, or even none (since there is a notion of an &lt;em&gt;abstract&lt;/em&gt; tag
in Fluidinfo, separate from any concrete instances of it actually
attached to objects).&lt;/p&gt;
&lt;p&gt;The tag heirarchies on all the objects can be viewed as a single
structure, only part of which is present on any object.
I&amp;#8217;ve attempted to show this with dark tags and directories for
instantiated parts of the Fluidinfo hierarchy on each objects, with
parts instantiated elsewhere left pale in the diagram below.
I&amp;#8217;ve illustrated two whiskies (which use the same parts of the
overall hierarchy) and one city, which uses mostly different tags.&lt;/p&gt;
&lt;img alt="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at101-OneFSvsMany.png" src="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at101-OneFSvsMany.png" /&gt;
&lt;p&gt;We might call this way of thinking about the Fluidinfo tag structure
as the the &lt;em&gt;many tag hierarchies&lt;/em&gt; view.
Sometimes this seems like the natural way to think about Fluidinfo&amp;#8217;s
tag hierarchy, with the tag structure being in some sense inferior to
the objects.
The objects might then be likened to different hosts in a computer network,
and tags could be thought of as having a single value in each separate
hierarchy, just as the contents of a single file is well-defined and
unambiguous on a specific computer.&lt;/p&gt;
&lt;p&gt;At other times, it seems more natural to think of the tag hierarchy
as the primary entity with the with tags having different values
on different objects.   I&amp;#8217;ve tried to illustrate this below, with
different collections of objects hanging off tags in a single hierarchy.&lt;/p&gt;
&lt;img alt="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at101-OneFSforFI.gif" src="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at101-OneFSforFI.gif" /&gt;
&lt;p&gt;We might call this the &lt;em&gt;single tag hierarchy&lt;/em&gt; view.&lt;/p&gt;
&lt;p&gt;Neither of these views is really more correct that the other—the underlying
storage mechanism looks little like either, though is perhaps slightly
closer to the second view, in the sense that all the values for a given
tag are stored together in the database.&lt;/p&gt;
&lt;p&gt;Fluidinfo&amp;#8217;s addressing mechanism, however, is very like the
&amp;#8220;many tag hierarchies&amp;#8221; view.   After all, the address to access Alice&amp;#8217;s
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;whisky/age&lt;/span&gt;&lt;/tt&gt; tag on &lt;em&gt;Ardbeg&lt;/em&gt; is&lt;/p&gt;
&lt;blockquote&gt;
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://fluiddb.fluidinfo.com/about/Ardbeg/alice/whisky/rating&lt;/span&gt;&lt;/tt&gt;&lt;/blockquote&gt;
&lt;p&gt;Ignoring the base URL (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://fluiddb.fluidinfo.com&lt;/span&gt;&lt;/tt&gt;) we then have
something remarkably familiar from Unix, and comparable either to a
host or a volume (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/about/Ardbeg&lt;/span&gt;&lt;/tt&gt;), followed (after a separating slash)
by the tag path (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/alice/whisky/rating&lt;/span&gt;&lt;/tt&gt;).
Notice how similar this is, for example, to the way we address files
across systems using Unix&amp;#8217;s remote copy, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt;.  If Alice wanted to
copy a file from the host &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ardbeg&lt;/span&gt;&lt;/tt&gt; on her local area network, she
might say&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;rcp ardbeg:whisky/rating ./whisky/ardbeg-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;rcp ardbeg:/Users/alice/whisky/rating ./whisky/ardbeg-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or even, if she were on host &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;talisker&lt;/span&gt;&lt;/tt&gt;, and wished to be more explicit&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;rcp ardbeg:/Users/alice/whisky/rating talisker:/Users/talisker/whisky/ardbeg-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Similarly, if she has multiple file systems mounted on her machine,
Alice might say something like:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Volumes&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;whiskydata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;whisky&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ardbeg&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;whisky&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ardbeg&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;where now &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/Volumes/whiskydata&lt;/span&gt;&lt;/tt&gt; is a disk (or file system).&lt;/p&gt;
&lt;p&gt;We could also note that an alternative way of specifying the previous
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rcp&lt;/span&gt;&lt;/tt&gt; command would be:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;rcp /Users/alice/whisky/rating@ardbeg ./whisky/ardbeg-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is entirely equivalent, but looks slightly more like the &amp;#8220;single
tag hierarchy&amp;#8221; view, at least in the sense that the disambiguating
host comes after—rather than before—the tag path.&lt;/p&gt;
&lt;p&gt;However we lay things out, it feels fairly clear that there is a good
case for extending our analogy to include either volumes, or more likely
hosts as the file-system analogues of Fluidinfo&amp;#8217;s objects.&lt;/p&gt;
&lt;img alt="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at101-ExtendedFSvsFI.png" src="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/at101-ExtendedFSvsFI.png" /&gt;
&lt;p&gt;That concludes the introduction to this series.
In the next part, I&amp;#8217;ll discuss how these alternative views might
help us to decide the best way to implement &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; commands
in Fish.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-3896969857831866716?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/3896969857831866716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2012/01/like-0-file-systems-for-everyone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3896969857831866716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3896969857831866716'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2012/01/like-0-file-systems-for-everyone.html' title='Like ℵ&lt;sub&gt;0&lt;/sub&gt; File Systems for Everyone'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-5124812088252265146</id><published>2012-01-15T11:20:00.001Z</published><updated>2012-01-15T11:20:40.688Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='about'/><category scheme='http://www.blogger.com/atom/ns#' term='art'/><category scheme='http://www.blogger.com/atom/ns#' term='sync'/><category scheme='http://www.blogger.com/atom/ns#' term='tagging'/><category scheme='http://www.blogger.com/atom/ns#' term='tag'/><category scheme='http://www.blogger.com/atom/ns#' term='artoftagging'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='alias'/><category scheme='http://www.blogger.com/atom/ns#' term='shell-fish'/><category scheme='http://www.blogger.com/atom/ns#' term='of'/><title type='text'>Updates to the Web Apps Shell-Fish and About Tag</title><content type='html'>&lt;div class="section" id="updates-to-the-web-apps-shell-fish-and-about-tag"&gt;
&lt;p&gt;I just pushed new versions of &lt;a class="reference external" href="http://shell-fish.appspot.com/"&gt;Shell-Fish&lt;/a&gt;
(the online version
of &lt;a class="reference external" href="https://github.com/njr0/fish"&gt;Fish&lt;/a&gt;)
and the &lt;a class="reference external" href="https://abouttag.appspot.com/"&gt;About Tag&lt;/a&gt; app.&lt;/p&gt;
&lt;p&gt;There are some quite significant changes, which I will summarize briefly.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Shell-Fish has been updated to the latest version 4.26.   It has sat at
4.00.0 for a ridiculously long time, and that became self-sustaining
because non-trivial changes were needed to the web version to make
it use the new one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The &lt;a class="reference external" href="https://abouttag.appspot.com/"&gt;About Tag&lt;/a&gt; app
now includes a clone of &lt;a class="reference external" href="http://shell-fish.appspot.com/"&gt;Shell-Fish&lt;/a&gt;.
Click the bottom tag on the logo to use this.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The search functionality in &lt;a class="reference external" href="https://abouttag.appspot.com/"&gt;About Tag&lt;/a&gt;
has been overhauled and
remodelled on the much better version used at
yet another of my sites, &lt;a class="reference external" href="http://artoftagging.com/"&gt;Art of Tagging&lt;/a&gt;,
which is hosted on the intriguing
&lt;a class="reference external" href="http://pythonanywhere.com/"&gt;PythonAnywhere&lt;/a&gt; platform.
Changes include:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;When you click a link, the diagram now appears inline&lt;/li&gt;
&lt;li&gt;If you re-click, it refreshes&lt;/li&gt;
&lt;li&gt;If you&amp;#8217;re signed in, you can tag items and the diagram updates.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The changes are quite major, and I haven&amp;#8217;t tested them as thoroughly
as I would wish, so I&amp;#8217;ve probably broken some thing.   Sorry.   Let
me know and I&amp;#8217;ll try to fix them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The three sites all use the same model of requiring your Fluidinfo
credentials; unfortunately they don&amp;#8217;t share databases, so if you
want to use all three, you need put them in three times.  This is
crazy; all three sites should merge, but that will take time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Although the search functionality on the
&lt;a class="reference external" href="https://abouttag.appspot.com/"&gt;About Tag&lt;/a&gt; site mostly works
well, Google&amp;#8217;s hard 10-second time limit on queries means that
queries that match a lot of objects tend to time out.
The version of &lt;a class="reference external" href="http://artoftagging.com/"&gt;Art of Tagging&lt;/a&gt;
doesn&amp;#8217;t suffer from this limit, but unfortunately
that site is quite often down for maintenance.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;There are many small changes to
&lt;a class="reference external" href="http://shell-fish.appspot.com/"&gt;Shell-Fish&lt;/a&gt;
but two really major bits of new functionality:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;a class="reference external" href="http://blog.abouttag.com/2011/12/fish-418-released-aliases-sequences.html"&gt;Aliases and syncing&lt;/a&gt; now work.   If you create aliases
on a local version, type sync in Shell-Fish and they will
appear there, and &lt;em&gt;vice-versa&lt;/em&gt;.
Among other things, this makes it easy to use
&lt;a class="reference external" href="http://blog.abouttag.com/2011/08/sequences-in-fluidinfo.html"&gt;sequences&lt;/a&gt;
and access them from both sites.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;You can drop the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-i&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt; in almost all cases.
So (in the most common case), rather than:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish&amp;gt; tag -a "artist:melody gardot" rating=10&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;you can simply use:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish&amp;gt; tag "artist:melody gardot" rating=10&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;though the old form will, of course, continue to work,
along with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-q&lt;/span&gt;&lt;/tt&gt; and the new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-&amp;#64;&lt;/span&gt;&lt;/tt&gt; (for
&lt;a class="reference external" href="http://blog.abouttag.com/2012/01/dial-for-anonymous.html"&gt;anonymous&lt;/a&gt;
objects).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;My process of turning everything from XHTML to HTML5 continues.
&lt;a class="reference external" href="http://shell-fish.appspot.com/"&gt;Shell-Fish&lt;/a&gt;
and the &lt;a class="reference external" href="https://abouttag.appspot.com/"&gt;About Tag&lt;/a&gt;
we app are now pure HTML5, like this blog.
Previously, they were all XHTML, which worked for everything under
the Sun except Microsoft Browsers; at least now Internet Explorer 9
should be able to use some of the functionality.
Users of Internet Explorer 1–8, and therefore of Windows XP,
remain out of luck (in more ways than I can possibly enumerate,
most of which are rather more significant than not being able
to use these web sites).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-5124812088252265146?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/5124812088252265146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2012/01/updates-to-web-apps-shell-fish-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/5124812088252265146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/5124812088252265146'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2012/01/updates-to-web-apps-shell-fish-and.html' title='Updates to the Web Apps Shell-Fish and About Tag'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-7726249680866442625</id><published>2012-01-12T22:36:00.000Z</published><updated>2012-01-12T22:57:06.287Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='anonymous'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='objects'/><category scheme='http://www.blogger.com/atom/ns#' term='privacy'/><category scheme='http://www.blogger.com/atom/ns#' term='private'/><title type='text'>Dial @ for Anonymous</title><content type='html'>&lt;div class="section" id="dial-for-anonymous"&gt;
&lt;p&gt;I have added a new flag to Fish in version 4.25, which I have
just pushed to &lt;a class="reference external" href="https://github.com/njr0/fish"&gt;the Fish repository on Github&lt;/a&gt;.
The feature allows you to ask Fluidinfo to usher into existence
a brand new, tagless object with no about tag, and is accessed using
the new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-&amp;#64;&lt;/span&gt;&lt;/tt&gt; flag as follows:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish tag -@ private/note="Dial @ for Anonymous"

Tagged object d679b99d-fe5e-43e9-88dc-47334df776c7 with private/note = "Dial @ for Anonymous"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Although Fish usually exhibits an almost monastic silence when it
successfully completes a non-reporting task you have set it, in this
case, there seems quite a high likelihood that you will want to know the
ID of the object it has created, so it tells you.&lt;/p&gt;
&lt;p&gt;The new flag also works with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tag&lt;/span&gt;&lt;/tt&gt; command&amp;#8217;s recently added &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt;
flag to accept input from a file or from standard input.   In particular,
this provides a convenient way of attaching a multi-line note to an
anonymous object:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish tag -@f private/note
Everyone needs a little privacy sometimes.
And you don't get much more private than a private tag
on an anonymous object.
^D

Tagged object afcf1f23-7c4b-44ea-a251-1bc99e959436 with private/note = "Everyone needs a little privacy sometimes.
And you don't get much more private than a private tag
on an anonymous object.
"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It will not have escaped the notice of the attentive reader of this
&lt;em&gt;About Tag&lt;/em&gt; blog that its author has spent perhaps five years
proselytizing on behalf of Fluidinfo&amp;#8217;s &lt;em&gt;about&lt;/em&gt; tag (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fluiddb/about&lt;/span&gt;&lt;/tt&gt;)
as the one true way to identify an object in Fluidinfo, benefiting as
it does from the system-guaranteed properties of uniqueness and
persistence.  Nothing has changed: I still believe that data that is
to have any social aspect, i.e., which might ever be shared with
someone else, or associated with someone else&amp;#8217;s data, is almost always
better placed on an object with an &lt;em&gt;about&lt;/em&gt; tag.&lt;/p&gt;
&lt;p&gt;For personal data, however, particularly when private, I think the
situation reverses.  If the data I am writing is not intended to be in
any way social, it may be that it is much better to put it on an
anonymous object.   It also provides an conventient way of guaranteeing
that an object, at least at creation time, currently has no other tags.&lt;/p&gt;
&lt;p&gt;I plan shortly to revamp the sequence command to allow it to use
anonymous objects, which probably fit better with some of its use cases.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-7726249680866442625?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/7726249680866442625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2012/01/dial-for-anonymous.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/7726249680866442625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/7726249680866442625'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2012/01/dial-for-anonymous.html' title='Dial @ for Anonymous'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-4858098802075526348</id><published>2012-01-09T22:58:00.002Z</published><updated>2012-01-09T23:02:45.886Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='sets'/><title type='text'>From Sets to Lists</title><content type='html'>&lt;div class="section" id="from-sets-to-lists"&gt;
&lt;p&gt;The Fluidinfo API has just been updated from version 1.13 to version 1.14.
There is a single change to the API: where previously
it supported &lt;em&gt;sets&lt;/em&gt; of strings as a primitive type for tag values,
it now instead supports &lt;em&gt;lists&lt;/em&gt; of strings.   The
differences are:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;in lists, the order of elements is significant, whereas is sets it is not&lt;/li&gt;
&lt;li&gt;in lists, repetition is allowed, whereas in sets an element is either
present of absent.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;In mathematics, sets are conventionally denoted using braces &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;{...}&lt;/span&gt;&lt;/tt&gt;
whereas lists (sequences) are more often denoted using either square
brackets &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[...]&lt;/span&gt;&lt;/tt&gt; or parentheses &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(...)&lt;/span&gt;&lt;/tt&gt;, and this is also true in
some more mathematical programming languages, such as Python.&lt;/p&gt;
&lt;p&gt;The following pair of interactions with Fish illustrates the difference.
Here is the old behaviour, with a slightly older version of Fish:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish --version
fish 4.20

$ fish show fluidinfo /fluiddb/version /fluiddb/release-date
Object with about="fluidinfo":
  /fluiddb/api-version = "1.13"
  /fluiddb/release-date = "2011-12-02T02:28:17Z"

$ fish tag Paris airports='{"Orly", "Charles de Gaulle", "Orly"}'

$ fish show Paris airports
Object with about="Paris":
  /njr/airports = {
    "Charles de Gaulle",
    "Orly"
  }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Notice how the set specified as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;{&amp;quot;Orly&amp;quot;,&lt;/span&gt; &lt;span class="pre"&gt;&amp;quot;Charles&lt;/span&gt; &lt;span class="pre"&gt;de&lt;/span&gt; &lt;span class="pre"&gt;Gaulle&amp;quot;,&lt;/span&gt; &lt;span class="pre"&gt;&amp;quot;Orly&amp;quot;}&lt;/span&gt;&lt;/tt&gt;
has been deduplicated and reordered, and that Fish uses braces to denote
the value.&lt;/p&gt;
&lt;p&gt;Here is the new behaviour, with a new version of Fish that I&amp;#8217;ve just pushed
to &lt;a class="reference external" href="https://github.com/njr0/fish"&gt;Github&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish --version
fish 4.24

$ fish show fluidinfo /fluiddb/version /fluiddb/release-date
Object with about="fluidinfo":
  /fluiddb/api-version = "1.14"
  /fluiddb/release-date = "2012-01-10T00:34:00Z"

$ fish tag Paris airports='["Orly", "Charles de Gaulle", "Orly"]'

$ fish show Paris airportsObject with about="Paris":
  /njr/airports = [
    "Orly",
    "Charles de Gaulle",
    "Orly"
  ]&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this case, order has been preserved, and duplicates in the list have
been retained.&lt;/p&gt;
&lt;p&gt;For the moment, with an eye to backwards compatibility, Fish allows
you to use either braces or square brackets when specifying a compound tag
value, but always reports the result using square brackets.&lt;/p&gt;
&lt;p&gt;For people interfacing with Fluidinfo directly through the API, there
is no &lt;em&gt;syntactic&lt;/em&gt; change since compound values were already sent to
and returned from the API using JSON lists.  The difference is behavioural,
with order and duplicates now being preserved in lists sent to Fluidinfo
where previously they were not.&lt;/p&gt;
&lt;p&gt;Existing compound values will be returned in an unspecified order.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-4858098802075526348?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/4858098802075526348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2012/01/from-sets-to-lists.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4858098802075526348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4858098802075526348'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2012/01/from-sets-to-lists.html' title='From Sets to Lists'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-4860426889839222774</id><published>2012-01-09T09:40:00.001Z</published><updated>2012-01-09T09:40:42.707Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='stdin'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='MIME'/><title type='text'>Fish 4.23</title><content type='html'>&lt;div class="section" id="fish-4-23"&gt;
&lt;p&gt;I&amp;#8217;ve just pushed a new version, 4.23, of Fish to
&lt;a class="reference external" href="https://github.com/njr0/fish"&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It contains three changes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;It now shows non-primitive tag values when they are textual, where before
it simply showed their MIME type and size.&lt;/li&gt;
&lt;li&gt;It allows standard input (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;stdin&lt;/span&gt;&lt;/tt&gt;) to be used to specify long
string values for tags, which are then written, by default, with
MIME type &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;text/plain&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Where previously it used &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;{...}&lt;/span&gt;&lt;/tt&gt; to denote tag values that are
sets of strings (both for input and output), it now uses &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[...]&lt;/span&gt;&lt;/tt&gt;
instead, reflecting a forthcoming change to the API.  The change
is that Fluidinfo&amp;#8217;s primitive compound values will transmogrify
from unordered &lt;em&gt;sets&lt;/em&gt; of strings to ordered &lt;em&gt;lists&lt;/em&gt; of strings.  I
will blog separately about that when the release occurs.  (The
change to Fish is backwards compatible, and braces will still be
allowed on input.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&amp;#8217;ll explain a little more about the first two changes.&lt;/p&gt;
&lt;div class="section" id="non-primitive-text-types"&gt;
&lt;h2&gt;Non-primitive text types&lt;a class="headerlink" href="#non-primitive-text-types" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the early days of Fluidinfo, almost all tag values were &lt;em&gt;primitive&lt;/em&gt;,
i.e. they were either numbers, strings, booleans, sets of strings
or valueless (NULL, if you prefer).   However, the API has always supported
tag values with arbitrary MIME types.&lt;/p&gt;
&lt;p&gt;Fish largely ignored the MIME type in the early days, and since almost all
values were primitive, this was not a great problem.   However, as Fluidinfo
has developed, ever more non-primitive tag values are used, and the result
has been that using Fish&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;show&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tags&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;get&lt;/span&gt;&lt;/tt&gt; commands has
caused binary data to be dumped to terminals with at best meaningless,
and at worst destructive consequences.&lt;/p&gt;
&lt;p&gt;As a result, I previously changed Fish to show only information about
the size and MIME type for non-primitive tag values. For example:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show abouttag image/red-spinner.gif
Object with about="abouttag":
  /njr/image/red-spinner.gif = &amp;lt;Non-primitive value of type image/gif (size 3208)&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;While this is good for MIME types such as GIF, it is less useful for textual
MIME types.   For example, instead of using primitive strings for Fluidinfo&amp;#8217;s
record of its API version and release date, the team decided to use
MIME type &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;text/plain&lt;/span&gt;&lt;/tt&gt; so that these show up nicely in browers,
as you can verify by visiting:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fluidinfo/fluiddb/version"&gt;http://fluiddb.fluidinfo.com/about/fluidinfo/fluiddb/version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fluidinfo/fluiddb/release-date"&gt;http://fluiddb.fluidinfo.com/about/fluidinfo/fluiddb/release-date&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;But with the old Fish behaviour, this meant that the result was the following,
less than helpful, output:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show fluidinfo /fluiddb/version /fluiddb/release-date
Object with about="fluidinfo":
  /fluiddb/version = &amp;lt;Non-primitive value of type text/plain (size 4)&amp;gt;
  /fluiddb/release-date = &amp;lt;Non-primitive value of type text/plain (size 20)&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So with the change in 4.23, Fish now provides more helpful output whenever
it recognizes a MIME type as textual:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show fluidinfo /fluiddb/version /fluiddb/release-date
Object with about="fluidinfo":
  /fluiddb/version = "1.13"
  /fluiddb/release-date = "2011-12-02T02:28:17Z"&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="setting-tag-values-from-standard-input"&gt;
&lt;h2&gt;Setting Tag Values from Standard Input&lt;a class="headerlink" href="#setting-tag-values-from-standard-input" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I added the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; flag to Fish&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tag&lt;/span&gt;&lt;/tt&gt; command the other day to allow
the value of a tag to be set from a file.   This left the slightly anomalous
situation that when &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; was used, any value specified would be taken as
a filename, but any valueless tags specified were simply set as old-style
valueless tags.&lt;/p&gt;
&lt;p&gt;Since that useful change, I was reflecting on two further anomalies.
First, in Unix, it is usually possible to use standard input instead
of a file, which is helpful both for pipelining data and for typing
multi-line input.   Fish provided no mechanism for this.
Secondly, there is no easy way in Fish of directly
specifying a multi-line string value.&lt;/p&gt;
&lt;p&gt;I realised that all three of these anomalies can be pleasingly
remedied by changing things so that when a valueless tag is given to
Fish&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tag&lt;/span&gt;&lt;/tt&gt; command, in combination with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; flag, Fish will
read &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;stdin&lt;/span&gt;&lt;/tt&gt; to get a value for the tag.  (If more than one tag is
specified this way, the same value from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;stdin&lt;/span&gt;&lt;/tt&gt; is be used for all
of them.)  By default, the MIME type will be set to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;text/plain&lt;/span&gt;&lt;/tt&gt;,
though the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-M&lt;/span&gt;&lt;/tt&gt; flag can be used to specify something different.&lt;/p&gt;
&lt;p&gt;So that&amp;#8217;s what I&amp;#8217;ve done.   Here is an example:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish tag -f foo foo
This is line one.
This is line two.
...and that's your lot!
^D

$ fish show foo foo
Object with about="foo":
  /njr/foo = "This is line one.
This is line two.
...and that's your lot!
"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;For those less familiar with the Unix command line, here I typed
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt; &lt;span class="pre"&gt;tag&lt;/span&gt; &lt;span class="pre"&gt;-f&lt;/span&gt; &lt;span class="pre"&gt;foo&lt;/span&gt; &lt;span class="pre"&gt;foo&lt;/span&gt;&lt;/tt&gt; at the command promt (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;$&lt;/span&gt;&lt;/tt&gt;).  Fish then read
what I typed until I terminated the input with the end-of-file
character (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;CTRL+D&lt;/span&gt;&lt;/tt&gt; on Unix, including Mac OS X, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;CTRL+Z&lt;/span&gt;&lt;/tt&gt; on Windows).
The input was then used as the tag value.&lt;/p&gt;
&lt;p&gt;Here is an example using a pipe:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ cat &amp;gt; foo.txt
One
Two
Buckle my shoe

$ cat foo.txt | fish tag -f foo foo

$ fish show foo foo
Object with about="foo":
  /njr/foo = "One
Two
Buckle my shoe
"&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-4860426889839222774?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/4860426889839222774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2012/01/fish-423.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4860426889839222774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4860426889839222774'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2012/01/fish-423.html' title='Fish 4.23'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-379681087059857447</id><published>2012-01-01T19:24:00.000Z</published><updated>2012-01-01T19:24:11.054Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='files'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><title type='text'>Writing Files to Fluidinfo with Fish 4.21</title><content type='html'>&lt;div class="section" id="writing-files-to-fluidinfo-with-fish-4-21"&gt;
&lt;p&gt;I pushed a new version of Fish to &lt;a class="reference external" href="https://github.com/njr0/fish"&gt;Github&lt;/a&gt;.
It includes experimental new functionality to allow files to be written
to Fluidinfo using Fish&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tag&lt;/span&gt;&lt;/tt&gt; command.&lt;/p&gt;
&lt;p&gt;This functionality is invoked by the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; flag; when this is used,
parameter values are taken to be file names.   For example,
suppose the Fluidinfo user &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt; has a file in the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/tmp&lt;/span&gt;&lt;/tt&gt;
directory called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;spinner.gif&lt;/span&gt;&lt;/tt&gt; and wants to upload this as the
tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/image/red-spinner.gif&lt;/span&gt;&lt;/tt&gt; on the object whose
&lt;em&gt;about&lt;/em&gt; tag is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;abouttag&lt;/span&gt;&lt;/tt&gt;.   Assume that we are on a Unix-like system
and that the current working directory is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/tmp&lt;/span&gt;&lt;/tt&gt;.   Then any of the
following will work:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish tag -f abouttag image/red-spinner.gif=spinner.gif
$ fish tag -f abouttag image/red-spinner.gif=./spinner.gif
$ fish tag -f abouttag image/red-spinner.gif=/tmp/spinner.gif
$ fish tag -f -M image/gif abouttag image/red-spinner.gif=/tmp/spinner.gif&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;red-spinner.gif&lt;/span&gt;&lt;/tt&gt; file has actually been written to this location,
using a command similar to those above, and can be viewed at:&lt;/p&gt;
&lt;blockquote&gt;
&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/red-spinner.gif"&gt;http://fluiddb.fluidinfo.com/about/abouttag/njr/image/red-spinner.gif&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;Notice that the correct MIME type is served, so the browser can show
the image.&lt;/p&gt;
&lt;p&gt;Points to note:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; flag indicates that all tag values in the command are filenames,
i.e. you can&amp;#8217;t mix file-based values and literals in a single command.&lt;/li&gt;
&lt;li&gt;The filename has to be included even if it is indentical to the tag name
(though this may change at a later date) and there is no recursive option
for writing directories as tag bundles at the moment.&lt;/li&gt;
&lt;li&gt;By default, MIME types for certain common files are inferred from the
file extensions as detailed below.&lt;/li&gt;
&lt;li&gt;If you want to specify the MIME type explicitly, use the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-M&lt;/span&gt;&lt;/tt&gt; flag
to do this. This will apply to &lt;em&gt;all&lt;/em&gt; tags set in the command.&lt;/li&gt;
&lt;li&gt;Text files are assumed to be encoded as UTF-8.&lt;/li&gt;
&lt;li&gt;On unix-like systems, tildes will be expanded, so &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~njr&lt;/span&gt;&lt;/tt&gt;
etc. may be used.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The file extensions for which MIME types are inferred fall into two groups.
First are the textual MIME types (not necessarily types that begin
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;text/&lt;/span&gt;&lt;/tt&gt;, but ones whose contents are textual).   These are:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;TEXTUAL_MIMES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;csv&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;text/plain&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;text/html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;xml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;text/xml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;htm&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;text/html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;css&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;text/css&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;js&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;text/javascript&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;vcf&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;text/vcard&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;plain&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;text/plain&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;vsg&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;image/svg+xml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;ps&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/postscript&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;eps&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/postscript&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;rss&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/rss+xml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;atom&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/atom+xml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;xhtml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/xhtml+xml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Files with these extensions are read as &lt;em&gt;non&lt;/em&gt;-binary
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;open(&amp;quot;foo.text&amp;quot;)&lt;/span&gt;&lt;/tt&gt;) and interpreted as &amp;#8216;UTF-8&amp;#8217;.&lt;/p&gt;
&lt;p&gt;Notice that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;.txt&lt;/span&gt;&lt;/tt&gt; files are not given a MIME type, meaning that they
are written as primitive (unicode) strings to Fluidinfo.&lt;/p&gt;
&lt;p&gt;The extensions for which non-textual types are inferred are listed below.
These files are read as binary files (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;open(&amp;quot;foo.text&amp;quot;,&lt;/span&gt; &lt;span class="pre"&gt;'rb')&lt;/span&gt;&lt;/tt&gt;)&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;BINARY_MIMES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;png&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;image/png&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;jpeg&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;image/jpeg&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;jpg&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;image/jpg&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;gif&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;image/gif&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;tif&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;image/tiff&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;tiff&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;image/tiff&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;ico&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;image/vnd.microsoft.icon&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;pdf&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/pdf&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;zip&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/zip&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;gz&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/x-gzip&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;json&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;mp3&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;audio/mpeg&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;mp4&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;audio/mp4&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;ogg&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;audio/ogg&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;wav&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;audio/vnd.wave&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;tar&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/x-tar&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;rar&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;application/x-rar-compressed&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Use the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-M&lt;/span&gt;&lt;/tt&gt; flag to set the MIME type where this mapping is not correct
or where the MIME type is not listed above.&lt;/p&gt;
&lt;p&gt;This feature is experimental and may change in various ways as experience
with it is gained.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-379681087059857447?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/379681087059857447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2012/01/writing-files-to-fluidinfo-with-fish.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/379681087059857447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/379681087059857447'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2012/01/writing-files-to-fluidinfo-with-fish.html' title='Writing Files to Fluidinfo with Fish 4.21'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-2350197756184221332</id><published>2011-12-30T13:15:00.000Z</published><updated>2011-12-30T20:58:30.531Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='svg'/><category scheme='http://www.blogger.com/atom/ns#' term='progress'/><category scheme='http://www.blogger.com/atom/ns#' term='measurement'/><category scheme='http://www.blogger.com/atom/ns#' term='indicators'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><title type='text'>Lies, Damned Lies and Progress Indicators</title><content type='html'>&lt;div class="section" id="lies-damn-lies-and-progress-indicators"&gt;
&lt;p&gt;Here are some you may have met.
(Click start, in a
&lt;a class="reference external" href="http://blog.abouttag.com/2011/12/about-tag-goes-html5-with-embedded-svg.html"&gt;modern non-Microsoft* browser&lt;/a&gt;,
on each one.)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The perfect progress indicator (rarely seen in the wild).&lt;/em&gt;&lt;/p&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="160"&gt;

    &lt;!-- Klee version 1.0.18 output.
         Copyright (c) Stochastic Solutions Limited 2008-2011 --&gt;
    &lt;rect width="100%" height="100%" style="fill:rgb(230,230,230)"/&gt;
    &lt;text x="50" y="87" font-size="16" text-anchor="middle" style="fill:rgb(0,128,0)"&gt;
    START
    &lt;/text&gt;
    &lt;circle id="ccc11" cx="50" cy="80" r="35" fill="rgb(0,0,0)" opacity=".2"/&gt;
    &lt;text x="550" y="87" font-size="16" text-anchor="middle" style="fill:rgb(192,0,0)"&gt;
    DONE
    &lt;/text&gt;
    &lt;circle cx="550" cy="80" r="35" fill="rgb(0,0,0)" opacity=".2"/&gt;
    &lt;g transform="translate(100,50)"&gt;
 &lt;rect id="r" width="400" height="60" style="fill:rgb(200,200,200)"/&gt;
 &lt;rect width="0" height="60" style="fill:rgb(200,0,0)"&gt;
   &lt;animate attributeName="width" begin="ccc11.click" dur="6s" from="0" to="400" fill="freeze"/&gt;
 &lt;/rect&gt;
 &lt;g transform="translate(410,-10)"&gt;
 &lt;rect width="100" height="80" style="fill:rgb(230,230,230)"&gt;
   &lt;animate attributeName="width" begin="ccc11.click" values="100; 100; 0" fill="freeze" keyTimes="0; .999; 1" dur="6s"/&gt;
 &lt;/rect&gt;
 &lt;/g&gt;
    &lt;/g&gt;
    &lt;g transform="translate(650,30)"&gt;
    &lt;path d="M 0 0 l 0 100 l 100 0" fill="none" stroke="black" stroke-width="2"/&gt;
    &lt;path d="M 100 0 l -100 100" fill="none" stroke="rgb(100,100,100)" stroke-width="2"/&gt;
    &lt;circle cx="0" cy="100" r="5" style="fill:rgb(200,0,0)"&gt;
   &lt;animate attributeName="cx" begin="ccc11.click" dur="6s" from="0" to="100" fill="freeze"/&gt;
   &lt;animate attributeName="cy" begin="ccc11.click" dur="6s" from="100" to="0" fill="freeze"/&gt;
    &lt;/circle&gt;
    &lt;/g&gt;
    &lt;text x="650" y="20" font-size="20" text-anchor="middle"&gt;
      predicted
    &lt;/text&gt;
    &lt;text x="750" y="150" font-size="20" text-anchor="middle"&gt;
      actual
    &lt;/text&gt;
&lt;/svg&gt;
&lt;p&gt;&lt;em&gt;The software installer progress bar&lt;/em&gt;&lt;/p&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="160"&gt;

    &lt;!-- Klee version 1.0.18 output.
         Copyright (c) Stochastic Solutions Limited 2008-2011 --&gt;
    &lt;rect width="100%" height="100%" style="fill:rgb(230,230,230)"/&gt;
    &lt;text x="50" y="87" font-size="16" text-anchor="middle" style="fill:rgb(0,128,0)"&gt;
    START
    &lt;/text&gt;
    &lt;circle id="c3" cx="50" cy="80" r="35" fill="rgb(0,0,0)" opacity=".2"/&gt;
    &lt;text x="550" y="87" font-size="16" text-anchor="middle" style="fill:rgb(192,0,0)"&gt;
    DONE
    &lt;/text&gt;
    &lt;circle cx="550" cy="80" r="35" fill="rgb(0,0,0)" opacity=".2"/&gt;
    &lt;g transform="translate(100,50)"&gt;
 &lt;rect id="r" width="400" height="60" style="fill:rgb(200,200,200)"/&gt;
 &lt;rect width="0" height="60" style="fill:rgb(200,0,0)"&gt;
   &lt;animate attributeName="width" begin="c3.click" dur="6s" values="0; 400; 400" keyTimes="0; .4; 1" fill="freeze"/&gt;
 &lt;/rect&gt;
 &lt;g transform="translate(410,-10)"&gt;
 &lt;rect width="100" height="80" style="fill:rgb(230,230,230)"&gt;
   &lt;animate attributeName="width" begin="c3.click" values="100; 100; 0" fill="freeze" keyTimes="0; .999; 1" dur="6s"/&gt;
 &lt;/rect&gt;
 &lt;/g&gt;
    &lt;/g&gt;
    &lt;g transform="translate(650,30)"&gt;
    &lt;path d="M 0 0 l 0 100 l 100 0" fill="none" stroke="black" stroke-width="2"/&gt;
    &lt;g transform="translate(0,100)"&gt;
    &lt;path id="p3" d="M 0 0 l 40 -100 l 60 0" fill="none" stroke="rgb(100,100,100)" stroke-width="2"/&gt;
    &lt;circle cx="0" cy="0" r="5" style="fill:rgb(200,0,0)"&gt;
    &lt;animate attributeName="cx" begin="c3.click" dur="6s"
    keyTimes="0; .4; 1" values="0; 40; 100" fill="freeze"/&gt;
    &lt;animate attributeName="cy" begin="c3.click" dur="6s"
    keyTimes="0; .4; 1" values="0; -100; -100" fill="freeze"/&gt;
    &lt;/circle&gt;
    &lt;/g&gt;
    &lt;/g&gt;
    &lt;text x="650" y="20" font-size="20" text-anchor="middle"&gt;
      predicted
    &lt;/text&gt;
    &lt;text x="750" y="150" font-size="20" text-anchor="middle"&gt;
      actual
    &lt;/text&gt;
&lt;/svg&gt;
&lt;p&gt;&lt;em&gt;The software uninstaller progress bar&lt;/em&gt;&lt;/p&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="160"&gt;

    &lt;!-- Klee version 1.0.18 output.
         Copyright (c) Stochastic Solutions Limited 2008-2011 --&gt;
    &lt;rect width="100%" height="100%" style="fill:rgb(230,230,230)"/&gt;
    &lt;text x="50" y="87" font-size="16" text-anchor="middle" style="fill:rgb(0,128,0)"&gt;
    START
    &lt;/text&gt;
    &lt;circle id="c4" cx="50" cy="80" r="35" fill="rgb(0,0,0)" opacity=".2"/&gt;
    &lt;text x="550" y="87" font-size="16" text-anchor="middle" style="fill:rgb(192,0,0)"&gt;
    DONE
    &lt;/text&gt;
    &lt;circle cx="550" cy="80" r="35" fill="rgb(0,0,0)" opacity=".2"/&gt;
    &lt;g transform="translate(100,50)"&gt; &lt;rect id="r" width="400" height="60" style="fill:rgb(200,200,200)"/&gt;
 &lt;rect width="0" height="60" style="fill:rgb(200,0,0)"&gt;
   &lt;animate attributeName="width" begin="c4.click" dur="6s" values="0; 0; 400" keyTimes="0; .6; 1" fill="freeze"/&gt;
 &lt;/rect&gt;
 &lt;g transform="translate(410,-10)"&gt;
 &lt;rect width="100" height="80" style="fill:rgb(230,230,230)"&gt;
   &lt;animate attributeName="width" begin="c4.click" values="100; 100; 0" fill="freeze" keyTimes="0; .999; 1" dur="6s"/&gt;
 &lt;/rect&gt;
 &lt;/g&gt;
    &lt;/g&gt;
    &lt;g transform="translate(650,30)"&gt;
    &lt;path d="M 0 0 l 0 100 l 100 0" fill="none" stroke="black" stroke-width="2"/&gt;
    &lt;g transform="translate(0,100)"&gt;
    &lt;path id="p4" d="M 0 0 l 60 0 l 40 -100" fill="none" stroke="rgb(100,100,100)" stroke-width="2"/&gt;
    &lt;circle cx="0" cy="0" r="5" style="fill:rgb(200,0,0)"&gt;
    &lt;animate attributeName="cx" begin="c4.click" dur="6s"
    keyTimes="0; .6; 1" values="0; 60; 100" fill="freeze"/&gt;
    &lt;animate attributeName="cy" begin="c4.click" dur="6s"
    keyTimes="0; .6; 1" values="0; 0; -100" fill="freeze"/&gt;
    &lt;/circle&gt;
    &lt;/g&gt;
    &lt;/g&gt;
    &lt;text x="650" y="20" font-size="20" text-anchor="middle"&gt;
      predicted
    &lt;/text&gt;
    &lt;text x="750" y="150" font-size="20" text-anchor="middle"&gt;
      actual
    &lt;/text&gt;
&lt;/svg&gt;
&lt;p&gt;&lt;em&gt;The media-download progress bar.&lt;/em&gt;&lt;/p&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="160"&gt;

    &lt;!-- Klee version 1.0.18 output.
         Copyright (c) Stochastic Solutions Limited 2008-2011 --&gt;
    &lt;rect width="100%" height="100%" style="fill:rgb(230,230,230)"/&gt;
    &lt;text x="50" y="87" font-size="16" text-anchor="middle" style="fill:rgb(0,128,0)"&gt;
    START
    &lt;/text&gt;
    &lt;circle id="c2" cx="50" cy="80" r="35" fill="rgb(0,0,0)" opacity=".2"/&gt;
    &lt;text x="550" y="87" font-size="16" text-anchor="middle" style="fill:rgb(192,0,0)"&gt;
    DONE
    &lt;/text&gt;
    &lt;circle cx="550" cy="80" r="35" fill="rgb(0,0,0)" opacity=".2"/&gt;
    &lt;g transform="translate(100,50)"&gt;
 &lt;rect id="r" width="400" height="60" style="fill:rgb(200,200,200)"/&gt;
 &lt;rect width="0" height="60" style="fill:rgb(200,0,0)"&gt;
   &lt;animate attributeName="width" begin="c2.click" dur="6s" values="0; 0; 0; 5; 10; 200; 390; 395; 400; 400; 400" keyTimes="0; .1; .2; .3; .4; .5; .6; .7; .8; .9; 1" fill="freeze"/&gt;
 &lt;/rect&gt;
 &lt;g transform="translate(410,-10)"&gt;
 &lt;rect width="100" height="80" style="fill:rgb(230,230,230)"&gt;
   &lt;animate attributeName="width" begin="c2.click" values="100; 100; 0" fill="freeze" keyTimes="0; .999; 1" dur="6s"/&gt;
 &lt;/rect&gt;
 &lt;/g&gt;
    &lt;/g&gt;
    &lt;g transform="translate(650,30)"&gt;
    &lt;path d="M 0 0 l 0 100 l 100 0" fill="none" stroke="black" stroke-width="2"/&gt;
    &lt;g transform="translate(0,100)"&gt;
    &lt;path id="p2" d="M 0 0 c 40 0 50 -10 50 -50 c 0 -40 10 -50 50 -50" fill="none" stroke="rgb(100,100,100)" stroke-width="2"/&gt;
    &lt;circle cx="0" cy="0" r="5" style="fill:rgb(200,0,0)"&gt;
   &lt;animateMotion begin="c2.click" dur="6s" calcMode="spline"
    keyTimes="0; 1" values="0; 6"
                  keySplines=".5 0 0.5 1" fill="freeze"&gt;
&lt;mpath xlink:href="#p2"/&gt;
   &lt;/animateMotion&gt;
    &lt;/circle&gt;
    &lt;/g&gt;
    &lt;/g&gt;
    &lt;text x="650" y="20" font-size="20" text-anchor="middle"&gt;
      predicted
    &lt;/text&gt;
    &lt;text x="750" y="150" font-size="20" text-anchor="middle"&gt;
      actual
    &lt;/text&gt;
&lt;/svg&gt;
&lt;p&gt;&lt;em&gt;The software update progress bar.&lt;/em&gt;&lt;/p&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="160"&gt;

    &lt;!-- Klee version 1.0.18 output.
         Copyright (c) Stochastic Solutions Limited 2008-2011 --&gt;
    &lt;rect width="100%" height="100%" style="fill:rgb(230,230,230)"/&gt;
    &lt;text x="50" y="87" font-size="16" text-anchor="middle" style="fill:rgb(0,128,0)"&gt;
    START
    &lt;/text&gt;
    &lt;circle id="c5" cx="50" cy="80" r="35" fill="rgb(0,0,0)" opacity=".2"/&gt;
    &lt;text x="550" y="87" font-size="16" text-anchor="middle" style="fill:rgb(192,0,0)"&gt;
    DONE
    &lt;/text&gt;
    &lt;circle cx="550" cy="80" r="35" fill="rgb(0,0,0)" opacity=".2"/&gt;
    &lt;g transform="translate(100,50)"&gt;
 &lt;rect id="r" width="400" height="60" style="fill:rgb(200,200,200)"/&gt;
 &lt;rect width="0" height="60" style="fill:rgb(200,0,0)"&gt;
   &lt;animate attributeName="width" begin="c5.click" dur="15s" values="0; 400; 0; 400; 0; 400; 0; 400" keyTimes="0; 0.25; 0.26; 0.5; 0.51; 0.75; 0.76; 1" fill="freeze"/&gt;
 &lt;/rect&gt;
 &lt;g transform="translate(410,-10)"&gt;
 &lt;rect width="100" height="80" style="fill:rgb(230,230,230)"&gt;
   &lt;animate attributeName="width" begin="c5.click" values="100; 100; 0" fill="freeze" keyTimes="0; .999; 1" dur="15s"/&gt;
 &lt;/rect&gt;
 &lt;/g&gt;
    &lt;/g&gt;
    &lt;g transform="translate(650,30)"&gt;
    &lt;path d="M 0 0 l 0 100 l 100 0" fill="none" stroke="black" stroke-width="2"/&gt;
    &lt;g transform="translate(0,100)"&gt;
    &lt;path id="p5" d="M 0 0 l 25 -100 l 0 100 l 25 -100 l 0 100 l 25 -100 l 0 100l 25 -100" fill="none" stroke="rgb(100,100,100)" stroke-width="2"/&gt;
    &lt;circle cx="0" cy="0" r="5" style="fill:rgb(200,0,0)"&gt;
    &lt;animate attributeName="cx" begin="c5.click" dur="15s"
      keyTimes="0; .25; .26; .5; .52; .75; .76; 1"
             values="0; 25; 25; 50; 50; 75; 75; 100" fill="freeze"/&gt;
    &lt;animate attributeName="cy" begin="c5.click" dur="15s"
      keyTimes="0; .25; .26; .5; .52; .75; .76; 1"
      values="0; -100; 0; -100; 0; -100; 0; -100" fill="freeze"/&gt;
    &lt;/circle&gt;
    &lt;/g&gt;
    &lt;/g&gt;
    &lt;text x="650" y="20" font-size="20" text-anchor="middle"&gt;
      predicted
    &lt;/text&gt;
    &lt;text x="750" y="150" font-size="20" text-anchor="middle"&gt;
      actual
    &lt;/text&gt;
&lt;/svg&gt;
&lt;p&gt;No wonder so many cop out and use one of these:&lt;/p&gt;
&lt;img alt="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/red-spinner.gif" src="http://fluiddb.fluidinfo.com/about/abouttag/njr/image/red-spinner.gif" /&gt;
&lt;p&gt;* [Why non-Microsoft? Before going all HTML5 and SVG on this blog I made
a point of testing things with Internet Explorer 9 and was delighted
to find that everything seemed to work fine there.   Unfortunately,
I didn&amp;#8217;t think to test SMIL-based SVG animation, which works (you guessed it)
on Chrome, Safari, Firefox, Opera, iPhone, iPad and even newer Androids,
but not, in fact, Internet Explorer 9.]&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-2350197756184221332?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/2350197756184221332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/12/lies-damn-lies-and-progress-indicators.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/2350197756184221332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/2350197756184221332'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/12/lies-damn-lies-and-progress-indicators.html' title='Lies, Damned Lies and Progress Indicators'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-5891976615813600550</id><published>2011-12-27T15:54:00.000Z</published><updated>2011-12-29T00:15:55.487Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='about'/><category scheme='http://www.blogger.com/atom/ns#' term='tag'/><category scheme='http://www.blogger.com/atom/ns#' term='library'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='metadata'/><category scheme='http://www.blogger.com/atom/ns#' term='bibliography'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='british'/><category scheme='http://www.blogger.com/atom/ns#' term='national'/><title type='text'>The British Library Catalogue / British National Bibliography</title><content type='html'>&lt;div class="section" id="the-british-library-catalogue-british-national-bibliography"&gt;
&lt;p&gt;I have added to Fluidinfo information on approximately 2.5 million books
drawn from the roughly 3 million records in the
&lt;a class="reference external" href="http://www.archive.org/details/BritishLibraryRdf"&gt;British National Bibliography&lt;/a&gt;,
which documents the British Library&amp;#8217;s Catalogue.&lt;/p&gt;
&lt;p&gt;As ever, I have used the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book-u&lt;/span&gt;&lt;/tt&gt; convention
(implemented using the Python
&lt;a class="reference external" href="https://github.com/njr0/abouttag"&gt;abouttag&lt;/a&gt; library)
to select &lt;em&gt;about&lt;/em&gt; tags for the objects, and have tagged the books
in Fluidinfo under the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book&lt;/span&gt;&lt;/tt&gt; user.
Data specific to the British National Biography (BNB) is stored in the
namespace &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/bnb&lt;/span&gt;&lt;/tt&gt;, while more generic data (derived from
the information contained in the Bibliography) is stored
directly in the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book&lt;/span&gt;&lt;/tt&gt; namespace.&lt;/p&gt;
&lt;p&gt;Here is an example of a book that has been augmented with data
from the British National Library.
The book is George Orwell&amp;#8217;s &lt;em&gt;Animal Farm&lt;/em&gt;,
and it is illustrated using the
&lt;a class="reference external" href="https://abouttag.appspot.com/simplebook"&gt;About Tag&lt;/a&gt;
visualizer.
(If you can&amp;#8217;t see the picture below, upgrade to the latest version of
your browser or see
&lt;a class="reference external" href="/http://blog.abouttag.com/2011/12/html5-and-svg-test.html"&gt;here&lt;/a&gt;
for information on why you might be having trouble.)
The green tags are the new ones.&lt;/p&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1004.0" height="952.0"&gt;

    &lt;!-- Klee version 1.0.18 output.
         Copyright (c) Stochastic Solutions Limited 2008-2011 --&gt;

    &lt;g transform="translate(90,466)"&gt;
 &lt;g transform="scale(0.8000, 0.8000)"&gt;
     &lt;text x="0" y="50.0" font-size="200" font-family="Times,Times-Roman,serif" style="fill:#808080" opacity="1.0" text-anchor="middle"&gt;ﬁ&lt;/text&gt;
     &lt;text x="0" y="75.0" font-size="28" font-family="Times,Times-Roman,serif" style="fill:#808080" opacity="1.0" text-anchor="middle"&gt;ﬂuidinfo&lt;/text&gt;
     &lt;circle cx="0" cy="0" r="100.0" style="fill:#A00000; opacity:0.850000"/&gt;
     &lt;text x="0" y="-37" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;1529c459-&lt;/text&gt;
     &lt;text x="0" y="-14" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;f3f2-&lt;/text&gt;
     &lt;text x="0" y="9" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;45e1-&lt;/text&gt;
     &lt;text x="0" y="32" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;90f4-&lt;/text&gt;
     &lt;text x="0" y="55" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;3ff3040ad6df&lt;/text&gt;
     &lt;g transform="rotate(0.000000) translate(86.602540,-50.000000)"&gt;
  &lt;path d="M0 0 l38.397460 -490.000000 l370.000000 0 l0 -30.000000 l-370.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="53.3974596216" y="-500.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;alice/comment=&amp;quot;So disappointing.&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(88.443328,-46.666667)"&gt;
  &lt;path d="M0 0 l36.556672 -456.333333 l180.000000 0 l0 -30.000000 l-180.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="51.5566722572" y="-466.333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;alice/has-read&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(90.123372,-43.333333)"&gt;
  &lt;path d="M0 0 l34.876628 -422.666667 l210.000000 0 l0 -30.000000 l-210.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="49.8766277694" y="-432.666666667" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;alice/likes=False&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(91.651514,-40.000000)"&gt;
  &lt;path d="M0 0 l33.348486 -389.000000 l180.000000 0 l0 -30.000000 l-180.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="48.3484861009" y="-399.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;alice/rating=2&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(93.035238,-36.666667)"&gt;
  &lt;path d="M0 0 l31.964762 -355.333333 l420.000000 0 l0 -30.000000 l-420.000000 0 Z" style="fill:darkorange; opacity:0.70"/&gt;
  &lt;text x="46.9647617536" y="-365.333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;bert/comment=&amp;quot;What a book: I love it!&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(94.280904,-33.333333)"&gt;
  &lt;path d="M0 0 l30.719096 -321.666667 l170.000000 0 l0 -30.000000 l-170.000000 0 Z" style="fill:darkorange; opacity:0.70"/&gt;
  &lt;text x="45.7190958418" y="-331.666666667" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;bert/has-read&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(95.393920,-30.000000)"&gt;
  &lt;path d="M0 0 l29.606080 -288.000000 l170.000000 0 l0 -30.000000 l-170.000000 0 Z" style="fill:darkorange; opacity:0.70"/&gt;
  &lt;text x="44.6060798583" y="-298.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;bert/rating=8&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(96.378882,-26.666667)"&gt;
  &lt;path d="M0 0 l28.621118 -254.333333 l310.000000 0 l0 -30.000000 l-310.000000 0 Z" style="fill:#006000; opacity:0.70"/&gt;
  &lt;text x="43.6211180347" y="-264.333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/author=&amp;quot;George Orwell&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(97.239681,-23.333333)"&gt;
  &lt;path d="M0 0 l27.760319 -220.666667 l280.000000 0 l0 -30.000000 l-280.000000 0 Z" style="fill:#006000; opacity:0.70"/&gt;
  &lt;text x="42.7603190279" y="-230.666666667" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/bnb/contributors={}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(97.979590,-20.000000)"&gt;
  &lt;path d="M0 0 l27.020410 -187.000000 l480.000000 0 l0 -30.000000 l-480.000000 0 Z" style="fill:#006000; opacity:0.70"/&gt;
  &lt;text x="42.0204102887" y="-197.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/bnb/creator=&amp;quot;Orwell, George, 1903-1950&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(98.601330,-16.666667)"&gt;
  &lt;path d="M0 0 l26.398670 -153.333333 l940.000000 0 l0 -30.000000 l-940.000000 0 Z" style="fill:#006000; opacity:0.70"/&gt;
  &lt;text x="41.3986702817" y="-163.333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/bnb/id={&amp;quot;GB9689279&amp;quot;, &amp;quot;GBB005647&amp;quot;, &amp;quot;GB8416414&amp;quot;, &amp;quot;GBA0Y6010&amp;quot;, &amp;quot;GB9330497&amp;quot;, &amp;quot;GB7301513&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.107125,-13.333333)"&gt;
  &lt;path d="M0 0 l25.892875 -119.666667 l500.000000 0 l0 -30.000000 l-500.000000 0 Z" style="fill:#006000; opacity:0.70"/&gt;
  &lt;text x="40.8928750179" y="-129.666666667" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/dewey={&amp;quot;823.912&amp;quot;, &amp;quot;823/.912&amp;quot;, &amp;quot;823/.9/1&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.498744,-10.000000)"&gt;
  &lt;path d="M0 0 l25.501256 -86.000000 l960.000000 0 l0 -30.000000 l-960.000000 0 Z" style="fill:#006000; opacity:0.70"/&gt;
  &lt;text x="40.5012562893" y="-96.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/isbn={&amp;quot;070898200X&amp;quot;, &amp;quot;185715150X&amp;quot;, &amp;quot;0582275245&amp;quot;, &amp;quot;0582434475&amp;quot;, &amp;quot;0435121650&amp;quot;, &amp;quot;978141...}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.777530,-6.666667)"&gt;
  &lt;path d="M0 0 l25.222470 -52.333333 l250.000000 0 l0 -30.000000 l-250.000000 0 Z" style="fill:#006000; opacity:0.70"/&gt;
  &lt;text x="40.222469686" y="-62.3333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/r=0.170613118849&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.944429,-3.333333)"&gt;
  &lt;path d="M0 0 l25.055571 -18.666667 l980.000000 0 l0 -30.000000 l-980.000000 0 Z" style="fill:#006000; opacity:0.70"/&gt;
  &lt;text x="40.0555709962" y="-28.6666666667" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/source={&amp;quot;BNBrdfdc13.xml-201011150#088316&amp;quot;, &amp;quot;BNBrdfdc13.xml-201011150#029879&amp;quot;, &amp;quot;BNBrdf...}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(100.000000,0.000000)"&gt;
  &lt;path d="M0 0 l25.000000 15.000000 l280.000000 0 l0 -30.000000 l-280.000000 0 Z" style="fill:#006000; opacity:0.70"/&gt;
  &lt;text x="40.0" y="5.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/title=&amp;quot;Animal farm&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.944429,3.333333)"&gt;
  &lt;path d="M0 0 l25.055571 48.666667 l520.000000 0 l0 -30.000000 l-520.000000 0 Z" style="fill:#A00000; opacity:0.70"/&gt;
  &lt;text x="40.0555709962" y="38.6666666667" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;fluiddb/about=&amp;quot;book:animal farm (george orwell)&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.777530,6.666667)"&gt;
  &lt;path d="M0 0 l25.222470 82.333333 l430.000000 0 l0 -30.000000 l-430.000000 0 Z" style="fill:gold; opacity:0.70"/&gt;
  &lt;text x="40.222469686" y="72.3333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;girafind/books/author={&amp;quot;George Orwell&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.498744,10.000000)"&gt;
  &lt;path d="M0 0 l25.501256 116.000000 l430.000000 0 l0 -30.000000 l-430.000000 0 Z" style="fill:gold; opacity:0.70"/&gt;
  &lt;text x="40.5012562893" y="106.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;girafind/books/language=&amp;quot;[&amp;quot;$_english&amp;quot;]&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.107125,13.333333)"&gt;
  &lt;path d="M0 0 l25.892875 149.666667 l380.000000 0 l0 -30.000000 l-380.000000 0 Z" style="fill:gold; opacity:0.70"/&gt;
  &lt;text x="40.8928750179" y="139.666666667" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;girafind/books/title=&amp;quot;Animal Farm&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(98.601330,16.666667)"&gt;
  &lt;path d="M0 0 l26.398670 183.333333 l370.000000 0 l0 -30.000000 l-370.000000 0 Z" style="fill:steelblue; opacity:0.70"/&gt;
  &lt;text x="41.3986702817" y="173.333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;miro/books/author=&amp;quot;George Orwell&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(97.979590,20.000000)"&gt;
  &lt;path d="M0 0 l27.020410 217.000000 l320.000000 0 l0 -30.000000 l-320.000000 0 Z" style="fill:steelblue; opacity:0.70"/&gt;
  &lt;text x="42.0204102887" y="207.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;miro/books/forename=&amp;quot;George&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(97.239681,23.333333)"&gt;
  &lt;path d="M0 0 l27.760319 250.666667 l280.000000 0 l0 -30.000000 l-280.000000 0 Z" style="fill:steelblue; opacity:0.70"/&gt;
  &lt;text x="42.7603190279" y="240.666666667" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;miro/books/guardian-1000&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(96.378882,26.666667)"&gt;
  &lt;path d="M0 0 l28.621118 284.333333 l310.000000 0 l0 -30.000000 l-310.000000 0 Z" style="fill:steelblue; opacity:0.70"/&gt;
  &lt;text x="43.6211180347" y="274.333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;miro/books/surname=&amp;quot;Orwell&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(95.393920,30.000000)"&gt;
  &lt;path d="M0 0 l29.606080 318.000000 l340.000000 0 l0 -30.000000 l-340.000000 0 Z" style="fill:steelblue; opacity:0.70"/&gt;
  &lt;text x="44.6060798583" y="308.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;miro/books/title=&amp;quot;Animal Farm&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(94.280904,33.333333)"&gt;
  &lt;path d="M0 0 l30.719096 351.666667 l240.000000 0 l0 -30.000000 l-240.000000 0 Z" style="fill:steelblue; opacity:0.70"/&gt;
  &lt;text x="45.7190958418" y="341.666666667" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;miro/books/year=1945&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(93.035238,36.666667)"&gt;
  &lt;path d="M0 0 l31.964762 385.333333 l230.000000 0 l0 -30.000000 l-230.000000 0 Z" style="fill:steelblue; opacity:0.70"/&gt;
  &lt;text x="46.9647617536" y="375.333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;miro/class=&amp;quot;record&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(91.651514,40.000000)"&gt;
  &lt;path d="M0 0 l33.348486 419.000000 l190.000000 0 l0 -30.000000 l-190.000000 0 Z" style="fill:darkslateblue; opacity:0.70"/&gt;
  &lt;text x="48.3484861009" y="409.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;njr/index/about&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(90.123372,43.333333)"&gt;
  &lt;path d="M0 0 l34.876628 452.666667 l170.000000 0 l0 -30.000000 l-170.000000 0 Z" style="fill:darkslateblue; opacity:0.70"/&gt;
  &lt;text x="49.8766277694" y="442.666666667" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;njr/rating=10&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(88.443328,46.666667)"&gt;
  &lt;path d="M0 0 l36.556672 486.333333 l200.000000 0 l0 -30.000000 l-200.000000 0 Z" style="fill:#663300; opacity:0.70"/&gt;
  &lt;text x="51.5566722572" y="476.333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;otoburb/has-read&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(86.602540,50.000000)"&gt;
  &lt;path d="M0 0 l38.397460 520.000000 l200.000000 0 l0 -30.000000 l-200.000000 0 Z" style="fill:#663300; opacity:0.70"/&gt;
  &lt;text x="53.3974596216" y="510.0" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;otoburb/rating=8&lt;/text&gt;
     &lt;/g&gt;
 &lt;/g&gt;
    &lt;/g&gt;
&lt;/svg&gt;
&lt;p&gt;Notice that, because of the careful normalization inherent in the
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book-u&lt;/span&gt;&lt;/tt&gt; convention, where the book is already in Fluidinfo,
the new data has generally been added to the existing object
corresponding to that book, as in the case above.&lt;/p&gt;
&lt;p&gt;The core data that should almost always be present is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;the &lt;em&gt;about&lt;/em&gt; tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fluiddb/about&lt;/span&gt;&lt;/tt&gt;, normalized using the
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book-u&lt;/span&gt;&lt;/tt&gt; convention:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book:animal&lt;/span&gt; &lt;span class="pre"&gt;farm&lt;/span&gt; &lt;span class="pre"&gt;(george&lt;/span&gt; &lt;span class="pre"&gt;orwell)&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/author&lt;/span&gt;&lt;/tt&gt; tag, containing the best author information
I was able to extract, in this case&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;George&lt;/span&gt; &lt;span class="pre"&gt;Orwell&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Where there is more than one author, they are generally shown
separated by commas, with the last joined with an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;and&lt;/span&gt;&lt;/tt&gt; (with
no &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Serial_comma"&gt;Oxford Comma&lt;/a&gt;).
For example, &lt;em&gt;The Feynman Lectures on Physics&lt;/em&gt;,
by Feynman, Leighton and Sands has&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show -a 'book:the feynman lectures on physics (richard p feynman; robert b leighton; matthew l sands)'
/book/author

Object with about="book:the feynman lectures on physics (richard p feynman; robert b leighton; matthew l sands)":
  /book/author = "Richard P. Feynman, Robert B. Leighton and Matthew L. Sands"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or, graphically:&lt;/p&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1020.0" height="330.4"&gt;

    &lt;!-- Klee version 1.0.18 output.
         Copyright (c) Stochastic Solutions Limited 2008-2011 --&gt;

    &lt;g transform="translate(90,155)"&gt;
 &lt;g transform="scale(0.8000, 0.8000)"&gt;
     &lt;text x="0" y="50.0" font-size="200" font-family="Times,Times-Roman,serif" style="fill:#808080" opacity="1.0" text-anchor="middle"&gt;ﬁ&lt;/text&gt;
     &lt;text x="0" y="75.0" font-size="28" font-family="Times,Times-Roman,serif" style="fill:#808080" opacity="1.0" text-anchor="middle"&gt;ﬂuidinfo&lt;/text&gt;
     &lt;circle cx="0" cy="0" r="100.0" style="fill:#A00000; opacity:0.850000"/&gt;
     &lt;text x="0" y="-37" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;aeaa654c-&lt;/text&gt;
     &lt;text x="0" y="-14" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;35b0-&lt;/text&gt;
     &lt;text x="0" y="9" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;4b00-&lt;/text&gt;
     &lt;text x="0" y="32" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;866b-&lt;/text&gt;
     &lt;text x="0" y="55" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;c7deda8959c4&lt;/text&gt;
     &lt;g transform="rotate(0.000000) translate(86.602540,-50.000000)"&gt;
  &lt;path d="M0 0 l38.397460 -101.500000 l770.000000 0 l0 -30.000000 l-770.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="53.3974596216" y="-111.5" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/author=&amp;quot;Richard P. Feynman, Robert B. Leighton and Matthew L. Sands&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(92.128466,-38.888889)"&gt;
  &lt;path d="M0 0 l32.871534 -75.611111 l870.000000 0 l0 -30.000000 l-870.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="47.8715336012" y="-85.6111111111" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/bnb/contributors={&amp;quot;Leighton, Robert B.&amp;quot;, &amp;quot;Sands, Matthew L. (Matthew Linzee)&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(96.064536,-27.777778)"&gt;
  &lt;path d="M0 0 l28.935464 -49.722222 l730.000000 0 l0 -30.000000 l-730.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="43.9354640789" y="-59.7222222222" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/bnb/creator=&amp;quot;Feynman, Richard P. (Richard Phillips), 1918-1988.&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(98.601330,-16.666667)"&gt;
  &lt;path d="M0 0 l26.398670 -23.833333 l420.000000 0 l0 -30.000000 l-420.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="41.3986702817" y="-33.8333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/bnb/id={&amp;quot;GBA901036&amp;quot;, &amp;quot;GBA645628&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.845560,-5.555556)"&gt;
  &lt;path d="M0 0 l25.154440 2.055556 l220.000000 0 l0 -30.000000 l-220.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="40.1544402466" y="-7.94444444444" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/dewey={&amp;quot;530&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.845560,5.555556)"&gt;
  &lt;path d="M0 0 l25.154440 27.944444 l420.000000 0 l0 -30.000000 l-420.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="40.1544402466" y="17.9444444444" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/isbn={&amp;quot;0805390499&amp;quot;, &amp;quot;0805390669&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(98.601330,16.666667)"&gt;
  &lt;path d="M0 0 l26.398670 53.833333 l250.000000 0 l0 -30.000000 l-250.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="41.3986702817" y="43.8333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/r=0.893236319082&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(96.064536,27.777778)"&gt;
  &lt;path d="M0 0 l28.935464 79.722222 l860.000000 0 l0 -30.000000 l-860.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="43.9354640789" y="69.7222222222" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/source={&amp;quot;BNBrdfdc16.xml-201011150#096269&amp;quot;, &amp;quot;BNBrdfdc14.xml-201011150#132062&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(92.128466,38.888889)"&gt;
  &lt;path d="M0 0 l32.871534 105.611111 l480.000000 0 l0 -30.000000 l-480.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="47.8715336012" y="95.6111111111" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/title=&amp;quot;The Feynman lectures on physics&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(86.602540,50.000000)"&gt;
  &lt;path d="M0 0 l38.397460 131.500000 l1000.000000 0 l0 -30.000000 l-1000.000000 0 Z" style="fill:#A00000; opacity:0.70"/&gt;
  &lt;text x="53.3974596216" y="121.5" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;fluiddb/about=&amp;quot;book:the feynman lectures on physics (richard p feynman; robert b leighton; m...&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
 &lt;/g&gt;
    &lt;/g&gt;
&lt;/svg&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/author&lt;/span&gt;&lt;/tt&gt; tag has had a lot of processing done to it,
as described below.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/title&lt;/span&gt;&lt;/tt&gt; field, which is usually almost identical to that
in the BNB data.   In this case it is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Animal&lt;/span&gt; &lt;span class="pre"&gt;farm&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I have not altered the capitalization, which is therefore
generally consistent with some entry in the BNB database
(though I would really prefer it were in Title Case).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/source&lt;/span&gt;&lt;/tt&gt; tag shows where the base data was taken from.
This tag&amp;#8217;s value is a set of strings, each of which corresponds
an entry in one of the 17 files from which the BNB data was extracted.
The entries consist of&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;the name of the file (always &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;BNBrdfdcNN.xml&lt;/span&gt;&lt;/tt&gt;)
where &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;NN&lt;/span&gt;&lt;/tt&gt; runs from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;01&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;17&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;a dash &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;the datestamp on that file (always 20101115 at present)&lt;/li&gt;
&lt;li&gt;the digit zero  (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;0&lt;/span&gt;&lt;/tt&gt;) and a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;#&lt;/span&gt;&lt;/tt&gt; sign&lt;/li&gt;
&lt;li&gt;the record number in the file, starting from 1, with
six digits.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since multiple bibliographic entries can correspond to the
same work, there is sometimes more than one of these.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/r&lt;/span&gt;&lt;/tt&gt; tag is a pseudo-random floating point value with
0.0 ≤ &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/r&lt;/span&gt;&lt;/tt&gt; &amp;lt; 1.0.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some of the raw data has also been added, with almost no cleaning up,
under the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/bnb&lt;/span&gt;&lt;/tt&gt; namespace.   The BNB data uses
the &lt;a class="reference external" href="http://dublincore.org/"&gt;Dublin Core&lt;/a&gt; metadata standard,
and includes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bnb/creator&lt;/span&gt;&lt;/tt&gt;, which is the person or organization primarily responsible
for the creation of the work.   This is sometimes blank, and is stored
as a single string value.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bnb/contributors&lt;/span&gt;&lt;/tt&gt;, which is a list of contributors, sometimes
including the creator and sometimes not.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bnb/dewey&lt;/span&gt;&lt;/tt&gt; is the set of Dewey Decimal classifications found on the
records corresponding to this book.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bnb/isbn&lt;/span&gt;&lt;/tt&gt; is the set of international standard book numbers found on the
records corresponding to this book.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bnb/id&lt;/span&gt;&lt;/tt&gt; is the set of British Library IDs found on the
records corresponding to this book.   (I&amp;#8217;m not entirely clear what
this identifier is, but it appears to be important and well populated.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Other information is available in the data (including classification
information), and I will probably extract this and add it at a later time.&lt;/p&gt;
&lt;div class="section" id="finding-inspecting-and-tagging-books-in-fluidinfo"&gt;
&lt;h2&gt;Finding, Inspecting and Tagging Books in Fluidinfo&lt;a class="headerlink" href="#finding-inspecting-and-tagging-books-in-fluidinfo" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are multiple ways of retrieving book data from Fluidinfo
and of tagging it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Probably the easiest and most general method is to go to
&lt;a class="reference external" href="http://artoftagging.com"&gt;http://artoftagging.com&lt;/a&gt; and do a search that involves a
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book&lt;/span&gt;&lt;/tt&gt; and some keywords from the title and/or author.
A list of results should come back and you can see a visualization
of any of them by clicking the link
If you have a Fluidinfo account, you can create an account at
artoftagging.com and then save your Fluidinfo details there.
Once logged in, you will then be able to add your own tags to
any object you find.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;If you just want to construct the &lt;em&gt;about&lt;/em&gt; tag for a book,
you can do that using the
online version of
&lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;the Fluidinfo Shell, Fish&lt;/a&gt;.
Once there, type, for example:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish&amp;gt; about book "Animal Farm" "George Orwell"
book:animal farm (george orwell)

fish&amp;gt; about book "The Feynman Lectures on Physics' 'Richard P. Feynman"
"Robert B. Leighton" "Matthew L. Sands"
book:the feynman lectures on physics (richard p feynman; robert b leighton; matthew l sands)&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;(The quotes tell Fish that &amp;#8220;Animal Farm&amp;#8221; is the title and &amp;#8220;George Orwell&amp;#8221;
a single author.)
Alternatively, you can download and install Fish on your own machine.
(It is &lt;a class="reference external" href="https://github.com/njr0/fish"&gt;available from Github&lt;/a&gt;.)
You can then type the same commands, after &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;, e.g.:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish&amp;gt; about book "Animal Farm" "George Orwell"
book:animal farm (george orwell)&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can then use any Fluidinfo tool, including the new
&lt;a class="reference external" href="http://fluidinfo.com"&gt;Object Browser&lt;/a&gt;,
to work with that object, signing in with Twitter if you like.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Another easy way of finding an &lt;em&gt;about&lt;/em&gt; tag for a book
is to find it on Amazon (US or UK, for now) and use the
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;az-fish&lt;/span&gt;&lt;/tt&gt; bookmarklet available at the top of
the &lt;a class="reference external" href="http://shell-fish.appspot.com/"&gt;online Fish&lt;/a&gt;
(drag it to your browser&amp;#8217; toolbar).
The bookmarklet will take the item on the current Amazon page
and issue the appropriate Fish command to find the &lt;em&gt;about&lt;/em&gt; tag.
(You don&amp;#8217;t need to log into Fish or Fluidinfo to do this.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="the-hierarchy-of-books-works-and-manifestations"&gt;
&lt;h2&gt;The Hierarchy of Books: Works and Manifestations&lt;a class="headerlink" href="#the-hierarchy-of-books-works-and-manifestations" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The International Federation of Library Associations
(&lt;a class="reference external" href="http://www.ifla.org"&gt;IFLA&lt;/a&gt;) describes a hierarchy of
four kinds of &amp;#8220;book&amp;#8221; entities in its report
&lt;a class="reference external" href="http://www.ifla.org/files/cataloguing/frbr/frbr_2008.pdf"&gt;Functional Requirements for Bibliographic Records&lt;/a&gt;.
These are:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;em&gt;works&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;expressions&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;manifestations&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;items&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Quoting from that report:&lt;/p&gt;
&lt;blockquote&gt;
&amp;#8220;The entities defined as work (a distinct intellectual or artistic
creation) and expression (the intellectual or artistic realization
of a work) reflect intellectual or artistic content. The entities
defined as manifestation (the physical embodiment of an expression
of a work) and item (a single exemplar of a manifestation), on the
other hand, reflect physical form.&amp;#8221;&lt;/blockquote&gt;
&lt;p&gt;Loosely, a &lt;em&gt;work&lt;/em&gt; is the conceptual book, usually described by the
combination of a title and author&amp;#8212;&lt;em&gt;Animal Farm&lt;/em&gt; by George Orwell.&lt;/p&gt;
&lt;p&gt;The report describes an expression of a work as &amp;#8220;the intellectual or artistic
realization of a work in the form of alpha-numeric, musical, or
choreographic notation, sound, image, object, movement, etc., or any
combination of such forms.&amp;#8221;   Thus George Orwell&amp;#8217;s &lt;em&gt;Animal Farm&lt;/em&gt;
can be translated into different languages, laid out differently,
typeset on pages, or in digital form, or recorded as spoken words,
and these correspond to different expressions of that same book.
There may also be different editions, printings etc., which may have
slightly different content.   Again, these are different expressions
of the same conceptual work.   (Occasionally, expressions may encompass
several works, such as in the case of compendia.)&lt;/p&gt;
&lt;p&gt;Moving down the hierarchy, a &lt;em&gt;manifestation&lt;/em&gt; is a particular rendering
of a work into physical form &amp;#8212; &amp;#8220;the physical embodiment of an
expression of a work.&amp;#8221;  Note that &amp;#8220;[A]s an entity, manifestation
represents all the physical objects that bear the same
characteristics, in respect to both intellectual content and physical
form.&amp;#8221;   Thus, all the copies of the same printing of the same edition
of Animal Farm that are essentially indistinguishable collectively
correspond to a manifestation of George Orwell&amp;#8217;s &lt;em&gt;Animal Farm&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Finally, an item is an individual copy of a book: &amp;#8220;a single exemplar
of a manifestation.&amp;#8221;&lt;/p&gt;
&lt;p&gt;The entries in the British Library&amp;#8217;s catalogue correspond literally to
items, but conceptually to &lt;em&gt;manifestations&lt;/em&gt;,
but the objects to which I have attached the data in Fluidinfo correspond
to &lt;em&gt;works&lt;/em&gt;.   This is why the c. 3 million records reduce to c. 2.5 million
Fluidinfo objects, and why some of the objects have multiple ISBNs etc.
It is entirely possible to create further objects at the level of
manifestations (and even items, if someone really wants to do so),
and even more so at the level of expressions, but I have not done this
yet.&lt;/p&gt;
&lt;p&gt;The reason I have concentrated on works rather than manifestations is
that this seems much the most important level to represent in a system
like Fluidinfo: with important exceptions, when people want to rate or
comment on a book, it is most often the work, rather than the
manifestation, that they are interested in.  Moreover, collecting
together information about the different ISBNs associated with a
single work is positively helpful.  That is not to say that there
isn&amp;#8217;t a case for creating other objects at the level of expressions
or manifestations.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="further-work"&gt;
&lt;h2&gt;Further Work&lt;a class="headerlink" href="#further-work" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is a great deal more that can be usefully done with the
fabulous data from the British Library.   While I am not
committing to doing these, tasks on my list list include:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Authors&lt;/em&gt;.  Creating an object corresponding to each
creator/author/contributor.  I plan to use &lt;em&gt;about&lt;/em&gt; tags of the
form &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;author:normalized&lt;/span&gt; &lt;span class="pre"&gt;name&lt;/span&gt; &lt;span class="pre"&gt;(birth-year)&lt;/span&gt;&lt;/tt&gt; for these,
e.g. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;author:George&lt;/span&gt; &lt;span class="pre"&gt;Orwell&lt;/span&gt; &lt;span class="pre"&gt;(1903)&lt;/span&gt;&lt;/tt&gt;.  The required data is
largely available in the BNB dataset.  I would then plan to add a
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/related-authors&lt;/span&gt;&lt;/tt&gt; tag to each book, pointing to its
authors&amp;#8217; objects and, on the author objects, corresponding sets of
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/related-books&lt;/span&gt;&lt;/tt&gt; tags pointing back to their works.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Upload Checking&lt;/em&gt;.  Checking the everything uploaded OK.  I
count 2,558,738 unique books (as works) in the BNB dataset, and I
appeared to upload all of these successfully (getting HTTP 204
statuses back from Fluidinfo).  However, when I count objects
having a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/r&lt;/span&gt;&lt;/tt&gt; tag, I get only 2,468,661, a shortfall of
90,077.&lt;/p&gt;
&lt;p&gt;Whether this indicates a problem or not is unclear, as if I count
the number of books with a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/source&lt;/span&gt;&lt;/tt&gt; but no &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/r&lt;/span&gt;&lt;/tt&gt;,
with the query&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;has book/source except has book/r&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;it reports 18,921 such books, but as far as I can tell, all those it
finds in fact have a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book/r&lt;/span&gt;&lt;/tt&gt;, so it appears that Fluidinfo is
having some difficulty executing some queries correctly at the moment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;About Tag Checking&lt;/em&gt;.   I had to use some fairly hairy code to
coerce the BNB data into the correct form to generate canonical
&lt;em&gt;about&lt;/em&gt; tags in the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book-u&lt;/span&gt;&lt;/tt&gt; convention, and it has definitely
failed in some cases.   For example, I have seen at least one example
where the surname of an author in the BNB data preceded the
forename but without a comma, so that forename and surname will
have been reversed.   To the extent that I can detect these problems,
I will try to fix them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Recent additions.&lt;/em&gt;   I believe the British Library has issued
updates with recent additions (since November 2010); I certainly
plan to get that data and import it in a similar fashion, and
then to set up a CRON job to do that regularly.
In this way, I hope the dataset will be living and always current.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Categorizations&lt;/em&gt;.   The BNB data includes subject categories for the
records, which I have not imported thus far.   I will do so.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Year information&lt;/em&gt;.   There is information about publication dates
in the BNB data, but it is not in a very structured form.
If I am able to extract it with a satisfactory degree of reliability,
I will get this too.   Obviously, different manifestations will have
different publication dates, so this will probably be a set-valued tag.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Enjoy the data, and let me know if you find problems.&lt;/p&gt;
&lt;p&gt;I expect I will write a number of other posts on issues associated with
this data.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-5891976615813600550?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/5891976615813600550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/12/british-library-catalogue-british.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/5891976615813600550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/5891976615813600550'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/12/british-library-catalogue-british.html' title='The British Library Catalogue / British National Bibliography'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-3203783424558305751</id><published>2011-12-27T14:58:00.000Z</published><updated>2011-12-27T14:59:10.572Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='about'/><category scheme='http://www.blogger.com/atom/ns#' term='svg'/><category scheme='http://www.blogger.com/atom/ns#' term='tag'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='browser'/><title type='text'>About Tag Goes HTML5 with Embedded SVG: Browser Requirements</title><content type='html'>&lt;p&gt;
This page uses HTML5 and an embedded Scalable Vector Graphics (SVG) diagram,
and acts as a test.
From this point on (27th December 2011) my plan is to use HTML5 with embedded
SVG as the default format for posts, and therefore if you use a browser
(or feed reader) that does not support this, you will miss out.
&lt;/p&gt;
 
&lt;p&gt;
You should see an elegant diagram below.
If you not, it probably means that you are not using a modern, standards-compliant HTML5 Browser.
&lt;/p&gt;

&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1020.0" height="330.4"&gt;

    &lt;!-- Klee version 1.0.18 output.
         Copyright (c) Stochastic Solutions Limited 2008-2011 --&gt;

    &lt;g transform="translate(90,155)"&gt;
 &lt;g transform="scale(0.8000, 0.8000)"&gt;
     &lt;text x="0" y="50.0" font-size="200" font-family="Times,Times-Roman,serif" style="fill:#808080" opacity="1.0" text-anchor="middle"&gt;ﬁ&lt;/text&gt;
     &lt;text x="0" y="75.0" font-size="28" font-family="Times,Times-Roman,serif" style="fill:#808080" opacity="1.0" text-anchor="middle"&gt;ﬂuidinfo&lt;/text&gt;
     &lt;circle cx="0" cy="0" r="100.0" style="fill:#A00000; opacity:0.850000"/&gt;
     &lt;text x="0" y="-37" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;aeaa654c-&lt;/text&gt;
     &lt;text x="0" y="-14" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;35b0-&lt;/text&gt;
     &lt;text x="0" y="9" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;4b00-&lt;/text&gt;
     &lt;text x="0" y="32" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;866b-&lt;/text&gt;
     &lt;text x="0" y="55" font-size="20" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="middle"&gt;c7deda8959c4&lt;/text&gt;
     &lt;g transform="rotate(0.000000) translate(86.602540,-50.000000)"&gt;
  &lt;path d="M0 0 l38.397460 -101.500000 l770.000000 0 l0 -30.000000 l-770.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="53.3974596216" y="-111.5" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/author=&amp;quot;Richard P. Feynman, Robert B. Leighton and Matthew L. Sands&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(92.128466,-38.888889)"&gt;
  &lt;path d="M0 0 l32.871534 -75.611111 l870.000000 0 l0 -30.000000 l-870.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="47.8715336012" y="-85.6111111111" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/bnb/contributors={&amp;quot;Leighton, Robert B.&amp;quot;, &amp;quot;Sands, Matthew L. (Matthew Linzee)&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(96.064536,-27.777778)"&gt;
  &lt;path d="M0 0 l28.935464 -49.722222 l730.000000 0 l0 -30.000000 l-730.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="43.9354640789" y="-59.7222222222" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/bnb/creator=&amp;quot;Feynman, Richard P. (Richard Phillips), 1918-1988.&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(98.601330,-16.666667)"&gt;
  &lt;path d="M0 0 l26.398670 -23.833333 l420.000000 0 l0 -30.000000 l-420.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="41.3986702817" y="-33.8333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/bnb/id={&amp;quot;GBA901036&amp;quot;, &amp;quot;GBA645628&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.845560,-5.555556)"&gt;
  &lt;path d="M0 0 l25.154440 2.055556 l220.000000 0 l0 -30.000000 l-220.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="40.1544402466" y="-7.94444444444" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/dewey={&amp;quot;530&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(99.845560,5.555556)"&gt;
  &lt;path d="M0 0 l25.154440 27.944444 l420.000000 0 l0 -30.000000 l-420.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="40.1544402466" y="17.9444444444" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/isbn={&amp;quot;0805390499&amp;quot;, &amp;quot;0805390669&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(98.601330,16.666667)"&gt;
  &lt;path d="M0 0 l26.398670 53.833333 l250.000000 0 l0 -30.000000 l-250.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="41.3986702817" y="43.8333333333" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/r=0.893236319082&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(96.064536,27.777778)"&gt;
  &lt;path d="M0 0 l28.935464 79.722222 l860.000000 0 l0 -30.000000 l-860.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="43.9354640789" y="69.7222222222" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/source={&amp;quot;BNBrdfdc16.xml-201011150#096269&amp;quot;, &amp;quot;BNBrdfdc14.xml-201011150#132062&amp;quot;}&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(92.128466,38.888889)"&gt;
  &lt;path d="M0 0 l32.871534 105.611111 l480.000000 0 l0 -30.000000 l-480.000000 0 Z" style="fill:darkslategrey; opacity:0.70"/&gt;
  &lt;text x="47.8715336012" y="95.6111111111" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;book/title=&amp;quot;The Feynman lectures on physics&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
     &lt;g transform="rotate(0.000000) translate(86.602540,50.000000)"&gt;
  &lt;path d="M0 0 l38.397460 131.500000 l1000.000000 0 l0 -30.000000 l-1000.000000 0 Z" style="fill:#A00000; opacity:0.70"/&gt;
  &lt;text x="53.3974596216" y="121.5" font-size="16" font-family="&amp;quot;Courier New&amp;quot;, Courier,monospace" font-weight="bold" style="fill:black" text-anchor="start"&gt;fluiddb/about=&amp;quot;book:the feynman lectures on physics (richard p feynman; robert b leighton; m...&amp;quot;&lt;/text&gt;
     &lt;/g&gt;
 &lt;/g&gt;
    &lt;/g&gt;
&lt;/svg&gt;

&lt;p&gt;
I have tested this page on the following:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;A Macbook Pro running OS X 10.7.2 (Lion) with Safari 5.1.2, Chrome 16.0.912.63, Firefox 8.0.1, Opera 11.6&lt;/li&gt;
  &lt;li&gt;A Mac Pro running OS X 10.6.8 (Snow Leopard) with the same browsers.&lt;/li&gt;
  &lt;li&gt;An iPad running iOS 5.0.1 (in Safari, naturally)&lt;/li&gt;
  &lt;li&gt;An iPhone running iOS 5.0.1 (again, Safari, of course)&lt;/li&gt;
  &lt;li&gt;A Sony Vaio running Windows 7 with Internet Explorer 9&lt;/li&gt;
  &lt;li&gt;A prehistoric Dell latitude laptop running Chrome 16 and Firefox 9&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
and everything looks good.   It does *not* work with Internet Explorer 8,
but then, what does?
It also does not work with many older versions of Firefox, Chrome,
Safari or Opera.   So this is a good time to upgrade.
I don't know which Android or Linux growers it works with, but I would guess it will work with some.
&lt;/p&gt;

&lt;p&gt;
I imagine the diagrams will not show up in most feed readers, and that is unfortunate, but I think this is a time to push forward, so that is what I am doing.
&lt;/p&gt;

&lt;p&gt;
Among the other marvellous benefits of SVG, it is scalable (just like the S
says), which means that if you zoom the browser (generally command-plus on
macs, and control-plus on Windows) the diagram will scale too, without
looking terrible.
Wonder of wonders.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-3203783424558305751?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/3203783424558305751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/12/about-tag-goes-html5-with-embedded-svg.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3203783424558305751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3203783424558305751'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/12/about-tag-goes-html5-with-embedded-svg.html' title='About Tag Goes HTML5 with Embedded SVG: Browser Requirements'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-5144282408493205040</id><published>2011-12-19T19:00:00.000Z</published><updated>2011-12-19T19:00:08.444Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='aliases'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='sequences'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='cache'/><title type='text'>Fish 4.18 Released: Aliases, Sequences, Duck Typing and More</title><content type='html'>&lt;div class="section" id="fish-4-18-released-aliases-sequences-duck-typing-and-more"&gt;
&lt;p&gt;It has been an unconsionably long time since I last pushed a version
of Fish to Github.   The reason for this is mostly that, while
adding various features, I broke a few things and wanted to get them
all fixed before inflicting them on people.   I believe they are
now fixed (but do disabuse me of this notion if you discover otherwise.)&lt;/p&gt;
&lt;p&gt;There is much that is new, though almost all changes are backwards compatible.
Everything is documented in the new green-themed documentation,
available (as usual) in Fluidinfo itself at&lt;/p&gt;
&lt;blockquote&gt;
&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;http://fluiddb.fluidinfo.com/about/fish/fish/index.html&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;The main changes are as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;You can omit the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-i&lt;/span&gt;&lt;/tt&gt; on the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tag&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;untag&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;show&lt;/span&gt;&lt;/tt&gt;,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;get&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tags&lt;/span&gt;&lt;/tt&gt; commands.   If you do so, Fish will use the first
argument instead, assuming that if it looks like a UUID, it is a
UUID, and if not, that it isn&amp;#8217;t.   For these purposes, UUIDs
must be expressed with lower-case hex digits and include the dashes
in 88888888-4444-4444-4444-cccccccccccc formation.
So now the following both work where before they would have generated
errors:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show Paris rating /about /id
Object with about="Paris":
  /njr/rating = 10
  /fluiddb/about = "Paris"
  /id = "17ecdfbc-c148-41d3-b898-0b5396ebe6cc"

$ fish show 17ecdfbc-c148-41d3-b898-0b5396ebe6cc rating /about /id
Object 17ecdfbc-c148-41d3-b898-0b5396ebe6cc:
  /njr/rating = 10
  /fluiddb/about = "Paris"
  /id = "17ecdfbc-c148-41d3-b898-0b5396ebe6cc"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Needless to say, the longer &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-i&lt;/span&gt;&lt;/tt&gt; forms work,
and are useful if you want to tag multiple objects in one command
(since they may be repeated).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tags&lt;/span&gt;&lt;/tt&gt; command now displays the tags in alphabetical order,
except for the &lt;em&gt;about&lt;/em&gt; tag, which is always listed first.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Fish now supports simple aliases, which effectively allow you to
add commands to Fish.   A simple example is:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish alias eiffel 'show -a "Eiffel Tower"'&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;which allows commands like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;eiffel&lt;/span&gt; &lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; to be used in place of
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;show&lt;/span&gt; &lt;span class="pre"&gt;-a&lt;/span&gt; &lt;span class="pre"&gt;&amp;quot;Eiffel&lt;/span&gt; &lt;span class="pre"&gt;Tower&amp;quot;&lt;/span&gt; &lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Aliases are stored in Fluidinfo, with private tags on objects
whose &lt;em&gt;about&lt;/em&gt; tag is the name of the alias.  For example, with the
alias definition above, the object with about tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;paris&lt;/span&gt;&lt;/tt&gt; has a tag
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/.fish/alias&lt;/span&gt;&lt;/tt&gt; added to it with its value set to the expansion text
for the alias:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish alias paris
paris:
  njr/.fish/alias = "show -a "Paris""&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;(Obviously, the quoting here is slightly unfortunate; I will fix that
some time.)&lt;/p&gt;
&lt;p&gt;Aliases are also cached locally in the file-system; the cache is
updated from Fluidinfo using the new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/tt&gt; command or whenever
Fish is entered in interactive mode (by typing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Fish&lt;/span&gt;&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;Because aliases are stored in Fluidinfo, they can be shared between
multiple copies of Fish, and also with the online version
&lt;a class="reference external" href="http://shell-fish.appspot.com/"&gt;Shell-Fish&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The cache can be viewed with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;showcache&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Support for sequences has been added.  Sequences provide a
convenient way of storing a numbered collection of items that are
added to over time.  They are described in a previous blog post
(&lt;a class="reference external" href="http://blog.abouttag.com/2011/08/sequences-in-fluidinfo.html"&gt;Sequences in Fluidinfo&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Briefly, in the simplest case, a sequence of remarks is defined
by saying:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish mkseq remark&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This creates two new aliases:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;remark&lt;/span&gt;&lt;/tt&gt; is used to add a new remark, using the alias&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish alias
remark:
  njr/.fish/alias = "seq /njr/remark"&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;remarks&lt;/span&gt;&lt;/tt&gt; is used to look at (or search) remarks, using the alias
remarks:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;njr/.fish/alias = "listseq /njr/remark"&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Thus if we say:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish mkseq remark
Next remark number: 0

$ fish remark "Isn't this a remarkable first remark"
0: Isn't this a remarkable first remark
2011-12-18

$ fish remark "...and this only slightly less remarkable"
1: ...and this only slightly less remarkable
2011-12-18&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;then we will see:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish remarks
0: Isn't this a remarkable first remark
2011-12-18

1: ...and this only slightly less remarkable
2011-12-18&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;By default, sequences are public, but you can easily make them
private by specifying a tag in a private namespace (typically
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;); you can also specify the plural form.  To set up the
sequence as private, and use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;myremarks&lt;/span&gt;&lt;/tt&gt; to list and search
remarks, you would instead say:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ mkseq remark remarks private/remark&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;For more details, see the previous &lt;a class="reference external" href="http://blog.abouttag.com/2011/08/sequences-in-fluidinfo.html"&gt;blog post&lt;/a&gt;
or the &lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/seq.html"&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Non-primitive types are now shown more sensibly (by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;show&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tags&lt;/span&gt;&lt;/tt&gt;).
Previously, Fish would attempt to print even non-primitive types,
with sometimes unfortunately consequences both in terms of the volume
of output and its effects on terminals.   For non-primitive types,
output is now shown as below:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show fish /fish/index.html
Object with about="fish":
  /fish/index.html = &amp;lt;Non-primitive value of type text/html (size 8907)&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Display of set-valued tags is also improved, e.g.:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish tags 'artist:led zeppelin'
Object with about="artist:led zeppelin":
  /fluiddb/about = "artist:led zeppelin"
  /musicbrainz.org/artist
  /musicbrainz.org/artist/end-date = "1980-09-25"
  /musicbrainz.org/artist/members = {
    "Jimmy Page"
    "John Bonham"
    "John Paul Jones"
    "Robert Plant"
  }
  /musicbrainz.org/artist/name = "Led Zeppelin"
  /musicbrainz.org/artist/sort-name = "Led Zeppelin"
  /musicbrainz.org/artist/start-date = "1968-01-01"
  /musicbrainz.org/artist/type = "group"
  /musicbrainz.org/mbid = "678d88b2-87b0-403b-b63d-5da7465aecc3"&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The Fish API has been updated to take account of the renaming of
FluidDB to Fluidinfo, and various tests have been changed to
use more esoteric unicode characters.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Some operations are faster (because more use is made of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/values&lt;/span&gt;&lt;/tt&gt;
endpoint).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Finally, when Fish starts it checks the environment for the presence
of the variable FISHUSER.   If this is defined, the credentials in
the startup file identified by the string specified in FISHUSER
will be used, rather than the default ones.   (This is mainly helpful
if you want to use Fish with different Fluidinfo accounts in different
shells concurrently.)   Thus, if FISHUSER is set to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;foo&lt;/span&gt;&lt;/tt&gt; (on UNIX),
the credentials from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.fluidDBcredentials.foo&lt;/span&gt;&lt;/tt&gt; will be used, rather
than those in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.fluidDBcredentials&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, obviously, there are quite a lot of changes, and though I&amp;#8217;ve been
using it for a while, some things might have broken.   (I fixed some
bugs yesterday; always dangerous!)&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-5144282408493205040?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/5144282408493205040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/12/fish-418-released-aliases-sequences.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/5144282408493205040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/5144282408493205040'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/12/fish-418-released-aliases-sequences.html' title='Fish 4.18 Released: Aliases, Sequences, Duck Typing and More'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-4004980659006659314</id><published>2011-12-15T13:11:00.000Z</published><updated>2011-12-15T13:40:10.422Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='abouttag'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='URLs'/><category scheme='http://www.blogger.com/atom/ns#' term='URIs'/><category scheme='http://www.blogger.com/atom/ns#' term='normalization'/><title type='text'>Fragmentation and URL Normalization</title><content type='html'>&lt;div class="section" id="fragmentation-and-url-normalization"&gt;
&lt;p&gt;I have updated the &lt;a class="reference external" href="https://github.com/njr0/abouttag"&gt;abouttag.py&lt;/a&gt;
library to use a new, better convention for normalizing URLs.
The two main changes people will notice are:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;URLs that represent directories will now include, rather than
exclude, a trailing slash:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;http://fluidinfo.com/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;rather than&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;http://fluidinfo.com&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;There is now a dependency on the excellent
&lt;a class="reference external" href="http://pypi.python.org/pypi/urlnorm"&gt;urlnorm.py&lt;/a&gt;,
by Jehiah Czebotar.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;div class="section" id="the-issue-fragmentation"&gt;
&lt;h2&gt;The Issue: Fragmentation&lt;a class="headerlink" href="#the-issue-fragmentation" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The twin evils that the abouttag.py library and this blog exist
to fight are &lt;em&gt;fragmentation&lt;/em&gt; and &lt;em&gt;overloading&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Fragmentation occurs in Fluidinfo when different users store
information about the same thing on different objects, while
overloading occurs when people store information about
different things on the same object.   In general, both of these
are undesirable.   Fragmentation reduces data sharing and makes
it harder to extract information from the system, whereas overloading
creates ambiguity and confusion.&lt;/p&gt;
&lt;p&gt;One of the more common uses for Fluidinfo is for tagging web pages,
and it is very natural to use the URL as the &lt;em&gt;about&lt;/em&gt; tag,
as almost everyone does.  There is not much
of a problem with overloading in this case (except to the extent that
URLs point to web pages that change over time), but there is definitely
fragmentation.&lt;/p&gt;
&lt;p&gt;I would distinguish between two kinds of fragmentation in the case of URLs.&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Different representations of the same URL.&lt;/em&gt;
Perhaps the most obvious example is the trailing slash on many URLs.
Punctilious persons with good knowledge of W3C standards
(and in particular &lt;a class="reference external" href="http://tools.ietf.org/html/rfc3986"&gt;RFC3986&lt;/a&gt;)
prefer the inclusion of a trailing slash on URLs (and more generally,
on &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Uniform_resource_identifier"&gt;URIs&lt;/a&gt;)
&lt;em&gt;where appropriate&lt;/em&gt;, and thus prefer&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;http://fluidinfo.com/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;to the more colloquial&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;http://fluidinfo.com&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Technically, these are different URLs, but web servers so routinely
and uniformly redirect the latter to the former that they can be
considered for all practical purposes the same.
It seems highly desirable for any convention for &lt;em&gt;about&lt;/em&gt; tags for URLs
to map these two forms, along with other similar representational variants,
to a common &lt;em&gt;about&lt;/em&gt; tag.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Different URLs that may or may not represent the same web page.&lt;/em&gt;
The most obvious example of this is the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;www.&lt;/span&gt;&lt;/tt&gt; that used to be
&lt;em&gt;de rigeur&lt;/em&gt; and is now commonly (but not reliably) redundant.
Most right-thinking webmasters (webmistresses?) routinely redirect
these to the same place,
there is no general guarantee that the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;www.&lt;/span&gt;&lt;/tt&gt; form
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://www.fluidinfo.com/&lt;/span&gt;&lt;/tt&gt;)
and the bare form (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://fluidinfo.com/&lt;/span&gt;&lt;/tt&gt;) will produce the same
page, nor even that they should both work.&lt;/p&gt;
&lt;p&gt;Standardizing this would therefore seem to be a normalization too far.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="the-old-and-new-behaviour-of-abouttag-py"&gt;
&lt;h2&gt;The Old and New Behaviour of abouttag.py&lt;a class="headerlink" href="#the-old-and-new-behaviour-of-abouttag-py" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Fluidinfo is far from the only system with an interest in developing
a canonical or normalized form for URLs.   Search engines and social
bookmarking sites (such as &lt;a class="reference external" href="http://pinboard.in/"&gt;Pinboard&lt;/a&gt;
and &lt;a class="reference external" href="http://delicious.com"&gt;Delicious&lt;/a&gt;) work better if different
URLs representing the same resource are collapsed, and as mentioned
above, there is even a standard
(&lt;a class="reference external" href="http://tools.ietf.org/html/rfc3986"&gt;RFC3986&lt;/a&gt;)
for how to perform the canonicalization.&lt;/p&gt;
&lt;p&gt;The relevant &lt;a class="reference external" href="http://en.wikipedia.org/wiki/URL_normalization"&gt;Wikipedia&lt;/a&gt;
page describes six normalizations that preserve URL semantics.
These are:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Converting the scheme and host to lower case.
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;HTTP://&lt;/span&gt;&lt;/tt&gt; → &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;FLUIDINFO.COM&lt;/span&gt;&lt;/tt&gt; → &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fluidinfo.com&lt;/span&gt;&lt;/tt&gt;).&lt;/li&gt;
&lt;li&gt;Capitalizing letters in escape sequences (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;%3a&lt;/span&gt;&lt;/tt&gt; → &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;%3A&lt;/span&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;Decoding percent-encoded octets of unreserved characters
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;%7E&lt;/span&gt;&lt;/tt&gt; → &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~&lt;/span&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;Adding a trailing slash where appropriate
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://fluidinfo.com&lt;/span&gt;&lt;/tt&gt; → &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://fluidinfo.com/&lt;/span&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;Removing the default port (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://fluidinfo.com:80/&lt;/span&gt;&lt;/tt&gt; →
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://fluidinfo.com/&lt;/span&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;Removing dot-segments (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://fluidinfo.com/accounts/./new/&lt;/span&gt;&lt;/tt&gt; →
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://fluidinfo.com/accounts/new/&lt;/span&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Happily, libraries to perform these normalizations already
exist and are freely for a number of programming languages,
including Python.
As noted above, Jehiah Czebotar&amp;#8217;s
&lt;a class="reference external" href="http://pypi.python.org/pypi/urlnorm"&gt;urlnorm.py&lt;/a&gt; performs
the task admirably in Python,
so in the version of &lt;a class="reference external" href="https://github.com/njr0/abouttag"&gt;abouttag.py&lt;/a&gt;
that I just pushed to Github (version 0.6) I have made added a new
convention, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;uri-2&lt;/span&gt;&lt;/tt&gt;, corresponding to this behaviour and have made
that the default.
So now:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;abouttag.uri&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;URI&lt;/span&gt;

&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;http://fluidinfo.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;u&amp;#39;http://fluidinfo.com/&amp;#39;&lt;/span&gt;

&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;HTTP://FLUIDINFO.com:80&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;u&amp;#39;http://fluidinfo.com/&amp;#39;&lt;/span&gt;

&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;HTTP://FLUIDINFO.com:80&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;u&amp;#39;http://fluidinfo.com/&amp;#39;&lt;/span&gt;

&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;http://fluidinfo.com/a/./b/?arg=&lt;/span&gt;&lt;span class="si"&gt;%7E&lt;/span&gt;&lt;span class="s"&gt;alice&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;u&amp;#39;http://fluidinfo.com/a/b/?arg=~alice&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This is different from the old behaviour, which can be obtained by
explicitly adding a convention argument of &amp;#8216;uri-1&amp;#8217;:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;http://fluidinfo.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;convention&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;uri-1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;u&amp;#39;http://fluidinfo.com&amp;#39;&lt;/span&gt;
&lt;span class="go"&gt;# note no trailing slash&lt;/span&gt;

&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;HTTP://FLUIDINFO.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;convention&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;uri-1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;u&amp;#39;http://fluidinfo.com&amp;#39;&lt;/span&gt;
&lt;span class="go"&gt;# Same downcasing, but again no trailing slash&lt;/span&gt;

&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;http://fluidinfo.com:80&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;convention&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;uri-1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;u&amp;#39;http://fluidinfo.com:80&amp;#39;&lt;/span&gt;
&lt;span class="go"&gt;# uri-1 didn&amp;#39;t strip default ports&lt;/span&gt;

&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;http://fluidinfo.com/a/./b/?arg=&lt;/span&gt;&lt;span class="si"&gt;%7E&lt;/span&gt;&lt;span class="s"&gt;alice&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;convention&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;uri-1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;u&amp;#39;http://fluidinfo.com/a/./b/?arg=%7Ealice&amp;#39;&lt;/span&gt;
&lt;span class="go"&gt;# nor did it undo unnecessary %-encoding or strip . &amp;amp; .. path segments.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Both the new and the old versions perform one additional normalization,
which is to add a leading &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://&lt;/span&gt;&lt;/tt&gt; if no scheme is present in the input.
This is not because there is not a distinction between a domain
and a URL, but rather because by calling the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;URI&lt;/span&gt;&lt;/tt&gt; function the user is
clearly indicating that this is a URI, which requires a scheme, and
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://&lt;/span&gt;&lt;/tt&gt; is clearly the appropriate default scheme:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;fluidinfo.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;u&amp;#39;http://fluidinfo.com/&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="why"&gt;
&lt;h2&gt;Why...?&lt;a class="headerlink" href="#why" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The reader may be wondering why I did not adhere to the RFC previously,
and issued forth older versions of the abouttag library with the
altogether inferior behaviour of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;uri-1&lt;/span&gt;&lt;/tt&gt;.
Ignorance, pure and simple.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-4004980659006659314?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/4004980659006659314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/12/fragmentation-and-url-normalization.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4004980659006659314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4004980659006659314'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/12/fragmentation-and-url-normalization.html' title='Fragmentation and URL Normalization'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-7127931384059165897</id><published>2011-12-10T17:38:00.001Z</published><updated>2011-12-10T17:52:26.714Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='siri'/><category scheme='http://www.blogger.com/atom/ns#' term='command line'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Siri: The Command Line for Everyone Else</title><content type='html'>&lt;div class="section" id="siri-the-command-line-for-everyone-else"&gt;
&lt;p&gt;Perhaps the biggest difference between the way in which &amp;#8220;real&amp;#8221; people
use computers and geeks use computers is this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Real people use Graphical User Interfaces because they find them
intuitive and efficient.&lt;/p&gt;
&lt;p&gt;Geeks generally prefer the command line,
which they find easier, more precise and faster than GUIs.
For geeks, GUIs tend to get in the way, limit and interfere.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here&amp;#8217;s a GUI for my files:&lt;/p&gt;
&lt;a href="http://www.flickr.com/photos/njradcliffe/6487664105/" title="Finder by njradcliffe, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7010/6487664105_5ae6873c56_b.jpg" width="884" height="552" alt="Finder"&gt;&lt;/a&gt;
&lt;p&gt;It has all the advantages of clickability, a set of icons for actions,
and a few extra things hidden on menus and right-click (&amp;#8220;content&amp;#8221;) menus.
But it is very limited.&lt;/p&gt;
&lt;p&gt;Here, in contrast, is a command line, in its spare, minimalist glory:&lt;/p&gt;
&lt;a href="http://www.flickr.com/photos/njradcliffe/6487651549/" title="CommandLine by njradcliffe, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7154/6487651549_23d6e178da_b.jpg" width="684" height="504" alt="CommandLine"&gt;&lt;/a&gt;
&lt;p&gt;If you don&amp;#8217;t know what to type, the command line is intimidating,
unhelpful and limiting.  But if you do know, you can do almost
anything: far from limiting, the command line is open and alive with
virtually unbounded possibilities.  Instead of having to nagivate
menus and finders and buttons and icons, the command line allows you
to access almost anything the machine can do, all from one place,
just by typing.&lt;/p&gt;
&lt;p&gt;There are two major things that stop real people from benefitting
from the command line and its liberating possibilities:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;People don&amp;#8217;t know the commands or the right syntax for them.&lt;/li&gt;
&lt;li&gt;People don&amp;#8217;t like typing. &lt;a class="footnote-reference" href="#fn1" id="id1"&gt;[1]&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;div class="section" id="enter-siri"&gt;
&lt;h2&gt;Enter Siri&lt;a class="headerlink" href="#enter-siri" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Just like a command line, Siri has the potential to allow me to access
anything my phone can do with no navigation: if I want to call Alex, I
say &amp;#8220;call Alex&amp;#8221;.  If I want to find out the height of Mount Everest, I
just say &amp;#8220;How high is Mount Everest?&amp;#8221;. If I want to send a Tweet, I
say &amp;#8220;text Bird&amp;#8221; and it will send a Tweet for me.  (OK, this last one
is a hack: if I say &amp;#8220;Tweet this&amp;#8221;, Siri knows exactly what I mean, but
refuses saying &amp;#8220;Sorry, Nicholas, I can&amp;#8217;t help you with Twitter.&amp;#8221;  But
I can send a tweet as a text message by saying &amp;#8220;text Bird&amp;#8221; because I
have the Twitter short-code listed under Bird Parker.  &amp;#8220;Why not under
Twitter?&amp;#8221;, you ask?  Because Siri &lt;i&gt;still&lt;/i&gt; refuses if I list it under
Twitter!  Go figure!)&lt;/p&gt;
&lt;p&gt;Of course, unlike the command line, I don&amp;#8217;t have to get the syntax right
with Siri.   I just issue commands in plain English, and a reasonable
proportion of the time it &amp;#8220;understands&amp;#8221; me.&lt;/p&gt;
&lt;p&gt;Before Siri, the nearest thing to a syntax-free command line for real
people was Google—a little box into which you can type anything in the
reasonable hope that the search will return some relevant
information. But Google is largely a one-trick pony, and even though
it&amp;#8217;s a good trick, it&amp;#8217;s nothing like as powerful as when the software
makes an attempt to understand the command and has the ability to take
actions.  (By offering a list of the top dozen or so &amp;#8220;hits&amp;#8221;, Google
also hedges its bets, getting the user to pick the best-looking
&amp;#8220;answer&amp;#8221;: quite apart from speech recognition and &amp;#8220;comprehension&amp;#8221;,
Siri goes for broke by putting all its money on a single interpretation of
what you said, only asking for clarification occasionally.)&lt;/p&gt;
&lt;p&gt;Horace Dediu, his podcast &lt;a class="reference external" href="http://5by5.tv/criticalpath/9"&gt;Getting to Know You&lt;/a&gt; makes the case that the significance
of Siri is that it allows Apple to learn much more about its users,
allowing a new level of lock-in, power and service.  That&amp;#8217;s an
interesting and important perspective that may prove to be right.
But after a day with Siri, I think the more direct and immediate
consequence is exactly that Siri could bring all the power of the
command line to the masses.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="fn1" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Actually, most geeks don&amp;#8217;t really like typing either, and
have myriad ways to reduce typing, from &lt;em&gt;globbing&lt;/em&gt;
(wild-card expansion) to command-line completion;
but the basic point stands.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-7127931384059165897?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/7127931384059165897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/12/siri-command-line-for-everyone-else.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/7127931384059165897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/7127931384059165897'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/12/siri-command-line-for-everyone-else.html' title='Siri: The Command Line for Everyone Else'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-4850324266579280833</id><published>2011-11-26T16:33:00.001Z</published><updated>2011-11-26T16:43:08.605Z</updated><title type='text'>Microsoft, iPads and the Innovator's Dilemma</title><content type='html'>&lt;div class="section" id="microsoft-ipads-and-the-innovator-s-dilemma"&gt;
&lt;p&gt;This article was motivated by listening to &lt;a class="reference external" href="http://5by5.tv/hypercritical/44"&gt;Episode 44 of
Hypercritical&lt;/a&gt;, the episode of
&lt;a class="reference external" href="http://arstechnica.com/author/john-siracusa/"&gt;John Siracusa&lt;/a&gt;&amp;#8216;s
&lt;a class="reference external" href="http://5by5.tv/hypercritical"&gt;weekly podcast&lt;/a&gt; that focused on the
question &amp;#8220;What Ails Microsoft?&amp;#8221;; listen to it for context.  I agreed
with most of Siracusa&amp;#8217;s analysis, but thought he missed a few key
insights and perspectives.&lt;/p&gt;
&lt;p&gt;You should listen to Siracusa&amp;#8217;s podcast, but here are
some of the key points in his analysis of what ails Microsoft are:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Microsoft consistently refuses bet-the-company radical changes
that will be good for the user and its own long-term business
prospects because it are scared of damaging its cash cows
(primarily Windows and Office, but also servers, Exchange etc.);&lt;/li&gt;
&lt;li&gt;Microsoft serves primarily PC vendors, IT departments,
backward-looking developers and perhaps Intel rather than its
end-users; this leads to poor user experiences;&lt;/li&gt;
&lt;li&gt;Microsoft follows rather than leads and so is always behind the
curve (think Bing, XBox, Zune, Windows Phone etc.)&lt;/li&gt;
&lt;li&gt;Microsoft underestimates its own position of strength, which would
in fact allow it to upset its customers more (to everyone&amp;#8217;s
long-term benefit) for fear of losing what it has;&lt;/li&gt;
&lt;li&gt;The demands of its core customers for a roadmap mean Microsoft
always overpromises and underdelivers, has low marketing impact
and never surprises competitors etc.&lt;/li&gt;
&lt;li&gt;Apple is the reverse of all this, repeatedly taking
bet-the-company risks, always focusing on the end user, repeatedly
canibalising its own products, being secretive and never
publishing roadmaps, constantly leading and redefining categories
(without necessarily being first mover), all in manner of what
&lt;a class="reference external" href="http://www.stevedenning.com"&gt;Steve Denning&lt;/a&gt; calls &lt;a class="reference external" href="http://www.stevedenning.com/Radical-Management/default.aspx"&gt;Radical Management&lt;/a&gt;,
which has led to its current position as the world&amp;#8217;s most valuable
company.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;While I agree with most of these points, here is what I think Siracusa missed.&lt;/p&gt;
&lt;div class="section" id="clayton-christensen-and-the-innovator-s-dilemma"&gt;
&lt;h2&gt;Clayton Christensen and The Innovator&amp;#8217;s Dilemma&lt;a class="headerlink" href="#clayton-christensen-and-the-innovator-s-dilemma" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http:/www.claytonchristensen.com"&gt;Clayton Christensen&lt;/a&gt;&amp;#8216;s &lt;a class="reference external" href="http://abouttag.appspot.com/monowing/about/book:the%20innovators%20dilemma%20(clayton%20m%20christensen)"&gt;The
Innovator&amp;#8217;s Dilemma&lt;/a&gt;
is the best business book I&amp;#8217;ve ever read.  Unusually, it contains a
thesis that can&amp;#8217;t be reduced to a single sentence.  His interest is in
how great companies get overthrown by disruptive
innovators.  His key ideas are as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Christensen defines a disruptive technology as one that is &lt;em&gt;worse&lt;/em&gt;
than the incumbent technology on the key metrics that are usually
used to measure quality in that space, but better in some other,
traditionally &lt;em&gt;less important&lt;/em&gt; metrics.&lt;/li&gt;
&lt;li&gt;Although he offers several examples, Christensen&amp;#8217;s clearest
example is disk drives.  Here, the two traditional key metrics are
speed and capacity. Disk technologies have been replaced in
waves, first with 8&amp;#8221; disks being replaced with 5.25&amp;#8221; disks, then
3.5&amp;#8221; disks, then 2.5&amp;#8221; disks then 1&amp;#8221; disks. (Solid-state drives
are now gradually starting to replace rotating disks.)&lt;/li&gt;
&lt;li&gt;Christensen argues that incumbent leaders almost always succeed
with sustaining (non-disruptive) innovations that improve the
performance of the technology against the standard metrics, but
almost always fail to bring to market new disruptive technologies,
even though these are often first developed by the market-leading
company.  He says this happens primarily because leading companies
tend to be &amp;#8220;well managed&amp;#8221;, and are strongly influenced by their
best customers and partners, who are, almost by definition, mostly
bought into the existing metrics. So when, for example, Winchester
(the leading 8&amp;#8221; disk manufacturer) asks its customers &amp;#8220;would you
be interested in lower power, physically smaller disk that has
lower speed and less capacity they say &amp;#8220;no, that&amp;#8217;s a terrible
thing, we need speed and capacity&amp;#8221;.&lt;/li&gt;
&lt;li&gt;New entrants, often start-ups, see an opportunity to serve new
markets, often consisting of people not using the incumbent
technology, for whom the alternative metrics (in this case, size
and power consumption) are more important than the traditional
ones.  For example, 8&amp;#8221; disks didn&amp;#8217;t work for PCs but 5.25&amp;#8221; disks
did; 5.25&amp;#8221; disks didn&amp;#8217;t work for laptops but 3.5&amp;#8221; disks did (and
then 2.5&amp;#8221;); 2.5&amp;#8221; disks didn&amp;#8217;t work for iPods but 1&amp;#8221; disks did.
Now solid-state memory, which is fast but expensive/lower
capacity, works for phones, cameras, tablets etc. in a way that
even 1&amp;#8221; disks didn&amp;#8217;t.&lt;/li&gt;
&lt;li&gt;A key point Christensen makes is that the new market, of
non-consumption, is often unattractive to the incumbent leader, who
typically sees it as small and offering low margins, but is highly
attractive for newcomers, who typically hone themselves on lower
margins as they serve it.&lt;/li&gt;
&lt;li&gt;Over time, sustaining improvements to the new technology tend to
improve it against the traditional metrics as well as the new
ones: current 3.5&amp;#8221; disks have much larger capacities and better
latencies than did early ones.  As they improve, they become more
viable in increasing parts of the &amp;#8220;old&amp;#8221; market, and the old leader
tends to be reduced to ever smaller, more niche parts of the
market.  Eventually, the new technology tends to get good enough
for mainstream use and at this point the advantages of the new
technology start to be more interesting to old customers.  (&amp;#8220;So I
can enough speed and capacity, but with a smaller footprint, less
power consumption and a lower price: well sure!&amp;#8221;)  If it survives
at all, the previous leader ends up serving only the very high end
where the extremes of the old metrics are required.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="ipads-pcs-and-the-innovator-s-dilemma"&gt;
&lt;h2&gt;iPads, PCs and the Innovator&amp;#8217;s Dilemma&lt;a class="headerlink" href="#ipads-pcs-and-the-innovator-s-dilemma" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Apple was not the first to come up with the idea of a Tablet PC.  In
fact, &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Alan_Kay"&gt;Alan Kay&lt;/a&gt; came up with
many of the key ideas in his remarkable &lt;a class="reference external" href="http://www.mprove.de/diplom/gui/Kay72a.pdf"&gt;1972 paper&lt;/a&gt; on the &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Dynabook"&gt;Dynabook&lt;/a&gt;.  But in the more recent
past, Microsoft (especially Bill Gates) championed tablet computers
and brought them to market a decade before Apple built the iPad.
Microsoft, however, saw a tablet, through the ever-present and
distorting lens of its Windows cash cow, as an enhancement to a
traditional Windows PC: you add a touch-screen (and a stylus) to
traditional laptop running (of course) Windows and &lt;em&gt;voilà&lt;/em&gt;, a tablet
is born.&lt;/p&gt;
&lt;p&gt;The iPad received a very luke-warm reception when it was launched, and
was widely derided as (merely) a giant iPod Touch.  It was criticized
for being underpowered, closed, not running even standard Mac
applications, let alone Windows software, not supporting &amp;#8220;true&amp;#8221;
multi-tasking or windowing and more besides. Yet it quickly sold in
the tens of millions and is clearly now replacing PCs for some people.&lt;/p&gt;
&lt;p&gt;With some caveats, this fits Claytonsen&amp;#8217;s model very well. The iPad is
a worse general-purpose computer against the traditional metrics. It
has slower hardware (though rarely feels slow), few ports, no user
accounts, comparatively little storage, no hardware keyboard, limited,
vetted software and (cough) no true multitasking, no Flash, no
replacable battery and limited upgrade options.&lt;/p&gt;
&lt;p&gt;But look at the alternative new metrics, that show all the ways in
which it is better for some people and purposes.  It is extremely
small and light. It is fantastically easy to use. Thanks to Apple&amp;#8217;s
control-freakery, installing software is simple and worry-free. It has
a touch screen. It has no significant issues with viruses etc. Its
battery genuinely lasts over 10 hours even when you use the machine
intensively. It has stores for software, books, music and videos built
in (and it probably already knows your credit card number). It has
numerous sensors (cameras, microphones, accelerometers, gyroscopes and
more). Software for it tends to be really cheap and some of it is of
fantastic quality. It is supremely relaxing to use.&lt;/p&gt;
&lt;p&gt;For people who mostly surf the web, do light email, play games, watch
films, read books etc., the iPad is not just a &amp;#8220;good enough&amp;#8221;
alternative to a laptop or even a desktop PC: it may actually be
signficantly better. The iPad 2 (and iOS 5) followed the pattern of
sustaining improvements, both on the new metrics (usability, weight,
size, sensors etc.) and the old (speed, capacity, ability to link to
an external monitor, multitasking etc.).&lt;/p&gt;
&lt;p&gt;Crucially, while Microsoft saw a tablet as a way to extend the PC, and
added Touch features to Windows and made its tablet PCs full Windows
PCs &amp;#8220;with added Touch&amp;#8221;, Apple redesigned all the upper layers of the
operating system to give the best possible experience for the iPad as
a new class of device. It didn&amp;#8217;t worry about disrupting sales of its
own Mac laptops, still less (naturally) those of Windows PCs: it just
made the iPad as good as it could, in its own right.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="risk-and-perfect-20-20-hindsight"&gt;
&lt;h2&gt;Risk and Perfect 20-20 Hindsight&lt;a class="headerlink" href="#risk-and-perfect-20-20-hindsight" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The other major point I feel Siracusa failed to make, and many people
are missing, is that Steve Jobs&amp;#8217;s and Apple&amp;#8217;s Radical Management is a
genuinely high risk strategy: it can fail as well as succeed, and
frequently does so. I think we need to separate out two ideas that I
feel are being conflated.  The first is &amp;#8220;betting the company&amp;#8221; on an
uncertain new thing, which isn&amp;#8217;t necessarily a good idea for a leading
company, but makes more sense for a struggling company.  The
second is the the aggressive development and marketing of new
technologies that might canibalize your existing business; this
probably is a good idea, even if the new business is lower margin or
lower value, because almost certainly someone will do it, and it&amp;#8217;s
better for the leader to do it to itself than for a competitor to do
so.&lt;/p&gt;
&lt;a href="http://www.flickr.com/photos/pauliantero/4685925036/" title="113/365: Flippin' coins by Pauli Antero, on Flickr"&gt;&lt;img src="http://farm5.staticflickr.com/4057/4685925036_8cf9081123.jpg" width="500" height="500" alt="113/365: Flippin' coins"&gt;&lt;/a&gt;
&lt;p&gt;[Image: &lt;a class="reference external" href="http://www.flickr.com/photos/pauliantero/4685925036/"&gt;Flippin&amp;#8217; Coins&lt;/a&gt; , by
&lt;a class="reference external" href="http://www.flickr.com/photos/pauliantero/"&gt;Pauli Antero&lt;/a&gt; on Flickr,
Creative Commons, some rights reserved.]&lt;/p&gt;
&lt;p&gt;In terms of the risk side, a comparison I like to make is with finding
lucky people.  Contrast two situations.  If I say to you &amp;#8220;Give me a
coin and I&amp;#8217;ll toss it ten times and get heads each time&amp;#8221;, and then I
do it, you&amp;#8217;ll probably think that is quite impressive and either very
lucky or (more likely) manipulated.  But if I take a thousand people
and get each of them to flip a coin repeatedly, and after each round
of flipping I get all the people who got tails to stop, after 10
rounds I might well have a single person who got a sequence of 10
heads.  But there would be nothing odd about that, and it certainly
doesn&amp;#8217;t require the person to have special powers or be &amp;#8220;lucky&amp;#8221;
(in any non-scientific sense).&lt;/p&gt;
&lt;p&gt;Apple now has the largest market capitalization of any company in the
world, with massive success and profits, after a series of audacious,
high-risk moves that worked out. I&amp;#8217;m not saying for a moment that this
is pure luck, or that Apple is like the one-in-a-thousand kid who got
ten heads in a row, but I do think that the world has annointed Apple
after the fact when many other companies have made &amp;#8220;audacious&amp;#8221; moves
that didn&amp;#8217;t work out and, in some cases, sent them under.
(Time-Warner&amp;#8217;s merger with AOL was certainly audacious.)  I think the
modern Apple has made a series of good moves, and combined those with
backtracking where necessary (allowing native apps, giving Final Cut
Pro a stay of execution, allowing various apps and books into the
stores after poorly judged bans etc.), and has won for reasons that combine
skill and luck; but even if Steve Jobs had lived, that doesn&amp;#8217;t mean he
didn&amp;#8217;t have more lemons in him, and that these might not have come out
and eventually hobbled or even killed the company.&lt;/p&gt;
&lt;p&gt;Even today, when Microsoft is routinely left off the list of the key
tech companies (now typically Apple, Google, Facebook, Amazon), or is at
least seen as the laggard among these, it remains massively profitable
and powerful. I think it is in terminal decline, and deserves to be,
but it is far from irrelevant yet.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-4850324266579280833?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/4850324266579280833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/11/microsoft-ipads-and-innovators-dilemma.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4850324266579280833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4850324266579280833'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/11/microsoft-ipads-and-innovators-dilemma.html' title='Microsoft, iPads and the Innovator&apos;s Dilemma'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-6294711920516673274</id><published>2011-11-02T10:48:00.001Z</published><updated>2011-11-06T12:39:14.851Z</updated><title type='text'>Everyone Needs a Little Privacy</title><content type='html'>&lt;div class="section" id="everyone-needs-a-little-privacy"&gt;
&lt;p&gt;I&amp;#8217;m delighted to announce two new features in Fluidinfo—the existence
of a private namespace for everyone, and the creation of a readable
Fluidinfo version number.  Thanks are due to Jamu (&lt;a class="reference external" href="http://twitter.com/jkakar"&gt;&amp;#64;jkakar&lt;/a&gt;) and Manuel (&lt;a class="reference external" href="http://twitter.com/ceronman"&gt;&amp;#64;ceronman&lt;/a&gt;) for implementing these changes.
They were both my requests/suggestions, so blame me if you hate them.&lt;/p&gt;
&lt;div class="section" id="the-private-namespace"&gt;
&lt;h2&gt;The private namespace&lt;a class="headerlink" href="#the-private-namespace" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you have an existing Fluidinfo account, you will now find that you
now have a top-level namespace called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;.  If you had such a
namespace anyway, it won&amp;#8217;t have been touched, but if you did not, it has
been created, and all of its permissions have been set, as the name suggests,
so that only you can access it.&lt;/p&gt;
&lt;p&gt;Using &lt;a class="reference external" href="http://github.com/njr0/fish"&gt;Fish&lt;/a&gt; (or the online version at
&lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;http://shell-fish.appspot.com&lt;/a&gt;), you can see this by using the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt; command.
So for me (logged in as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt;), I can get a Unix-style listing
of the permissions with:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish ls -ld private
nrwc------   njr/private/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or a more detailed, Fluidinfo-style listing by saying&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish ls -Gd private
njr/private/:

NAMESPACE (/namespaces)
  Read
    list (read):        policy: closed; exceptions = [njr]
  Write
    create (create):    policy: closed; exceptions = [njr]
    update (metadata):  policy: closed; exceptions = [njr]
    delete (delete):    policy: closed; exceptions = [njr]
  Control
    control (control):  policy: closed; exceptions = [njr]&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;New users registering from now on will also have this namespace created
for them, with the permissions set to private.&lt;/p&gt;
&lt;p&gt;We have given everyone a private namespace by default for two main reasons:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;It means that, without having to know anything about how the permissions
system works, all Fluidinfo users have any easy way to create both
private and non-private information: if you want your data to be public,
by default all your tags not under the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; namespace are readable
by everyone (but writable only by you); where you want data to be private,
just use a tag in your &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; namespace.&lt;/li&gt;
&lt;li&gt;Just as importantly, we expect that many Fluidinfo applications
will now place some data in a user&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; namespace (as appropriate)
and some at the top level, or in other namespace that aren&amp;#8217;t private
by default.   So an application to allow users to share clipboard between
devices, for example, would probably use private tags by default,
but a rating application would be more likely to use tags that are
public by default.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Just as most people never change any file permissions, we expect that most
Fluidinfo users will not want to be messing around with tag permissions,
and this change means they should not have to do so.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="faq"&gt;
&lt;h2&gt;FAQ&lt;a class="headerlink" href="#faq" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Q1: I hate this: I don&amp;#8217;t want a private namespace! Can I get rid of it?&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A1: Of course. You can safely delete the private namespace.
In Fish, assuming you haven&amp;#8217;t added anything to it you can do
this simply by saying:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish rm private&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;(The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; part of all these commands can be omitted if you
are using the online version of Fish.)&lt;/p&gt;
&lt;p&gt;Or, if you prefer, you can alter the permissions on the namespace
to make it non-private.   For example, if you say&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish perms default private&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;that will reset the permissions on the namespace &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;
to the defaults (making it readable by everyone, but writable
only by you).
I wouldn&amp;#8217;t particularly recommend this course, but it&amp;#8217;s up to you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Q2: I already had a namespace called&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;, &lt;em&gt;but its permissions aren&amp;#8217;t set correctly.   How can I fix them up?&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A2: You can do this with Fish&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt; command:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish perms private private&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that this &lt;em&gt;only&lt;/em&gt; changes the permissions on the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;
namespace itself.  If you have tags or namespaces under it,
their permissions will not be affected, but new tags and
namespace that you create under &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; after this change
will be affected.  (I will add a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-r&lt;/span&gt;&lt;/tt&gt; option to Fish soon,
for recursive permissions changes,
but it isn&amp;#8217;t there at the time of writing.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Q3: I used&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;as a tag: have you just trashed all my&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;tags?&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A3: No.  Fluidinfo is quite happy for you to have a tag and a namespace with the same name.
If you had a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; tag, this
hasn&amp;#8217;t been affected at all by the new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; namespace.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Q4: Is&lt;/em&gt; everything &lt;em&gt;under my&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;namespace private?&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A4: If we&amp;#8217;ve just created the private namespace for you, yes;
but if you had one already, it depends:&lt;/p&gt;
&lt;p&gt;A few months ago we made a change to Fluidinfo so that when a new
tag or namespace is created, it inherits permissions from its
parent namespace.   So everything works as you would expect, and if
you create new tags and namespaces under your private namespace,
everything will work as any reasonable person would expect.&lt;/p&gt;
&lt;p&gt;It is important to note, however, that the Fluidinfo permissions
system is not hierarchical, in the sense that changing the permissions
on a parent namespace has no effect on its existing child namespaces
and tags.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Q5: Will I run into problems if I buck the trend and don&amp;#8217;t have a private namespace called&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;or if I make other tags and namespace private?&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A5: No.  It is obviously possible that Fluidinfo
applications you use might make assumptions that your &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;
namespace is private, or that it exists, or even that tags not under
your &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; namespace are public, but such apps would be
making unjustified assumptions.&lt;/p&gt;
&lt;p&gt;There should certainly be no problem at all with making any tag
or namespace you like private, whether it is under the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;
namespace or not.   Indeed, you can make your top-level namespace
private if you like (though again, doing so will only affect new
top-level tags and namespaces).&lt;/p&gt;
&lt;p&gt;But if you don&amp;#8217;t have a strong philosophical objection, your life
probably be simpler if you go along with having a namespace called
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;, and probably by making its contents private too.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="fluidinfo-api-version-and-release-date"&gt;
&lt;h2&gt;Fluidinfo API Version and Release Date&lt;a class="headerlink" href="#fluidinfo-api-version-and-release-date" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The other small but useful change is that Fluidinfo is now publishing
information about the versions of the code and API deployed.&lt;/p&gt;
&lt;p&gt;Every time a new version of the live Fluidinfo code is deployed,
the tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fluiddb/release-date&lt;/span&gt;&lt;/tt&gt; on the object with &lt;em&gt;about&lt;/em&gt; tag
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fluidinfo&lt;/span&gt;&lt;/tt&gt; will be updated.   This is a plain
text string (MIME type &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;text/plain&lt;/span&gt;&lt;/tt&gt;) in
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/ISO_8601"&gt;ISO8601 extended format&lt;/a&gt;.
Because it is a plain-text string, you can view it in a browser at&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fluidinfo/fluiddb/release-date"&gt;http://fluiddb.fluidinfo.com/about/fluidinfo/fluiddb/release-date&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;or with Fish by saying&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show -a fluidinfo /fluiddb/release-date
Object with about="fluidinfo":
  /fluiddb/release-date = "2011-11-04T17:40:27Z"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The intention and commitment from the team is that every time the
live Fluidinfo code changes, this release date will be updated
(even if there is no intended change to the API).   This obviously
allows library and application writers to make statements such as:&lt;/p&gt;
&lt;blockquote&gt;
Fish version 4.12 has been tested with the Fluidinfo release
of 2011-11-04T17:40:27Z and all tests pass.&lt;/blockquote&gt;
&lt;p&gt;(which is true).&lt;/p&gt;
&lt;p&gt;There is also an API version published using the tag
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fluiddb/api-version&lt;/span&gt;&lt;/tt&gt; on the same object.   Again this has
MIME type &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;text/plain&lt;/span&gt;&lt;/tt&gt;, and can be viewed at&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fluidinfo/fluiddb/api-version"&gt;http://fluiddb.fluidinfo.com/about/fluidinfo/fluiddb/api-version&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It can also be displayed using Fish with the command&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show -a fluidinfo /fluiddb/api-version
Object with about="fluidinfo":
  /fluiddb/api-version = "1.13"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is updated whenever a deliberate change to the API is made.
If, at some point in future, multiple APIs are supported, the intention
is to extend this to be a space-separated list of APIs supported in the
current release.&lt;/p&gt;
&lt;p&gt;The API change log can be viewed at&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://doc.fluidinfo.com/fluidDB/api/changelog.html"&gt;http://doc.fluidinfo.com/fluidDB/api/changelog.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;and I&amp;#8217;m guessing that from this point forward the change log will include
the API version numbers for new features.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-6294711920516673274?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/6294711920516673274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/11/everyone-needs-little-privacy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/6294711920516673274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/6294711920516673274'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/11/everyone-needs-little-privacy.html' title='Everyone Needs a Little Privacy'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-445365661402713457</id><published>2011-10-10T23:36:00.001+01:00</published><updated>2011-10-13T00:15:43.018+01:00</updated><title type='text'>Tagging Music and Bands (or Anything Else) in Fluidinfo</title><content type='html'>&lt;div class="section" id="tagging-music-and-bands-or-anything-else-in-fluidinfo"&gt;
&lt;p&gt;I&amp;#8217;ve put a modified version of the &lt;a class="reference external" href="http://abouttag.appspot.com"&gt;About Tag&lt;/a&gt;
web site up at &lt;a class="reference external" href="http://artoftagging.com"&gt;ArtOfTagging.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a short video that illustrates its use, specifically with
the data from musicbrainz.org that Eric Seidel
(&lt;a class="reference external" href="http://twitter.com/gridaphobe"&gt;&amp;#64;gridaphobe&lt;/a&gt;) heroically imported
into Fluidinfo.&lt;/p&gt;
&lt;iframe width="960" height="720" src="http://www.youtube.com/embed/WQCL6oUmN7s?hd=1" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;p&gt;The new &lt;a class="reference external" href="http://artoftagging.com"&gt;ArtOfTagging.com&lt;/a&gt; allows you to do
search-engine search over the Fluidinfo About Tags,
to look up a specific, known about tag,
to tag objects (if you log in and assiciate a Fluidinfo account)
and to run Fluidinfo queries.   It also includes the latest
incarnation of the object visualizations, now inline and set up
so that they update if you tag something.&lt;/p&gt;
&lt;p&gt;If you want to know more about the about-tag conventions used
in this, see &lt;a class="reference external" href="http://blog.abouttag.com/2011/06/he-music-of-fluidinfo-ii.html"&gt;The Music of Fluidinfo II&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-445365661402713457?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/445365661402713457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/10/tagging-music-and-bands-or-anything.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/445365661402713457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/445365661402713457'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/10/tagging-music-and-bands-or-anything.html' title='Tagging Music and Bands (or Anything Else) in Fluidinfo'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/WQCL6oUmN7s/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-7972279240791245577</id><published>2011-10-10T19:32:00.001+01:00</published><updated>2011-10-11T14:21:18.660+01:00</updated><title type='text'>Python Anywhere (featuring Emacs Anywhere!)</title><content type='html'>&lt;div class="section" id="python-anywhere-featuring-emacs-anywhere"&gt;
&lt;img alt="http://pythonanywhere.com/static/anywhere/images/logo-234x35.png" src="http://pythonanywhere.com/static/anywhere/images/logo-234x35.png" /&gt;
&lt;p&gt;&lt;a class="reference external" href="http://pythonanywhere.com"&gt;Python Anywhere&lt;/a&gt; is a fascinating
new web service (currently in beta) from the good folks
at &lt;a class="reference external" href="http://resolversystems.com"&gt;Resolver Systems&lt;/a&gt;.
I&amp;#8217;m using it to host the &lt;a class="reference external" href="http://artoftagging.com"&gt;Django port&lt;/a&gt; of my
&lt;a class="reference external" href="http://abouttag.appspot.com"&gt;AboutTag&lt;/a&gt;
web application, used, among other things,
for searching Fluidinfo, but I&amp;#8217;ll blog separately about that.&lt;/p&gt;
&lt;p&gt;I first came across Resolver Systems a few years ago when their
main focus was on
&lt;a class="reference external" href="http://www.resolversystems.com/products/resolver-one/"&gt;Resolver One&lt;/a&gt;
a spreadsheet that you program in Python.
This is so obviously a good idea I was strongly rooting for
Resolver, but competing successfully against Excel,
whatever the merits of the alternative,
was always going to be a tall order, and last time I heard
Microsoft still had the edge in the spreadsheet market.&lt;/p&gt;
&lt;p&gt;Python Anywhere grew out of a project Resolver ran to produce a web
service—&lt;a class="reference external" href="http://www.projectdirigible.com/"&gt;Dirigible&lt;/a&gt;—based around
the same fundamental concept of a python-programmable spreadsheet.
Digirible is also notable for its support for grid computing, so it
offers potential to perform really large calculations while exploiting a
spreadsheet structure and all the goodness of Python, Numpy and
parallelism.&lt;/p&gt;
&lt;p&gt;Python Anywhere retains Dirigible&amp;#8217;s concept of writing python in a browser,
but dispenses with the spreadsheet.
So in a nutshell, Python Anywhere is marketed as a Python console
you can access through a browser.   But it&amp;#8217;s actually more than that.&lt;/p&gt;
&lt;p&gt;When you log into the Python Anywhere site, your primary choice is to
launch any of half a dozen different kinds of interactive Python
consoles (Python 2.7, Python 2.6, Python 3.2, IPython 2.7, IPython 2.6
or IPython 3.2).  These are all well configured in terms of libraries,
and seem to work well, and they absolutely allow you just to use Python
interactively.  But so far, I&amp;#8217;ve made very little use of any of those,
for the same reason that most of the time when I write Python on my
own computers I spend comparatively little time in the interactive
Python consoles, and I when I do, I prefer to launch them from a
terminal (or Emacs).&lt;/p&gt;
&lt;p&gt;With Python Anywhere, I almost always use the seventh option, which is
to launch a Bash console.  From there, I have access to all the same
Pythons, and most of the Unix (Linux?) tools you&amp;#8217;d expect.&lt;/p&gt;
&lt;p&gt;Including Emacs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Including Emacs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I am one of those people who spends more time in Emacs than in all the
rest of my applications put together.  And while Emacs in a console in
a browser isn&amp;#8217;t perfect, the achievement in making it work at all (and
quite well) is remarkable, and the result is pretty good.  Even if
Python Anywhere did not actually offer Python, for me the availability
of Emacs, from (almost) any device, through a browser would be very
interesting.&lt;/p&gt;
&lt;p&gt;But while I prefer to do it from bash than in a Python console, the
availability of well-configured Pythons through a browser is also
fascinating.&lt;/p&gt;
&lt;p&gt;One clear use case is access from iPads, iPhones and other devices
that don&amp;#8217;t allow you to run Python on them.  Although this isn&amp;#8217;t
working particularly well yet, this is clearly in Resolver&amp;#8217;s sights,
and I think will be most useful.  (Even I have to admit, however, that
Emacs and the iPad/iPhone don&amp;#8217;t seem like a match made in heaven; I
can see I might have to dust off my vi skills, though maybe the lack
of an escape key on an iPad is a problem even for vi?  Presumably it
can be rebound?)&lt;/p&gt;
&lt;p&gt;The Python Anywhere Platform also offers other services.  There&amp;#8217;s
Dropbox integration for transferring files, and good access to things
like Github.  There&amp;#8217;s the ability to schedule jobs (cron, essentially)
and they are trialling hosted web applications through Django and
other WSGI-compatible frameworks.  My port of &lt;a class="reference external" href="http://abouttag.appspot.com"&gt;AboutTag&lt;/a&gt; (the new version is available at
&lt;a class="reference external" href="http://artoftagging.com"&gt;ArtOfTagging.com&lt;/a&gt;, which redirects to
Python Anywhere) is running on this, and looks great.  Now obviously
there are lots of web hosting platforms around, with various pros and
cons, but I&amp;#8217;m not aware of any others that you console access through
a browser, which I can see being handy for all those critical fixes
when your only available device is a friend&amp;#8217;s machine,
or a phone or an internet café.&lt;/p&gt;
&lt;p&gt;I don&amp;#8217;t know what the future holds for Python Anywhere, but it&amp;#8217;s a
fascinating project from some very smart and friendly
people, so if you like Python (or Emacs, (or vi) or Bash, or any of
that command-liney goodness), head on over and request an invitation
to the beta.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-7972279240791245577?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/7972279240791245577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/10/python-anywhere-featuring-emacs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/7972279240791245577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/7972279240791245577'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/10/python-anywhere-featuring-emacs.html' title='Python Anywhere (featuring Emacs Anywhere!)'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-2012800898993052609</id><published>2011-08-12T08:09:00.002+01:00</published><updated>2011-10-01T17:51:28.757+01:00</updated><title type='text'>Sequences in Fluidinfo</title><content type='html'>  &lt;div class="section" id="sequences-in-fluidinfo"&gt;
&lt;p&gt;I&amp;#8217;ve added a powerful new feature to Fish to allow it manage arbitrary
sequences.  I&amp;#8217;ll introduce the feature first, and then there are a couple
of sections later on that motivate them, for anyone interested.&lt;/p&gt;
&lt;div class="section" id="id1"&gt;
&lt;h2&gt;Sequences in Fluidinfo&lt;a class="headerlink" href="#id1" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A Fish sequence is simply a numbered collection of textual items that
is added to over time.  For example, I have a sequence called
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;thoughts&lt;/span&gt;&lt;/tt&gt; in Fish.  When I have a new thought, I say something like:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish thought "Perhaps savethewords.org would like to add threatened words and their definitions to Fluidinfo"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;to which Fish responds:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;10: Perhaps savethewords.org would like to add threatened words and their definitions to Fluidinfo
2011-08-11&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This provides confirmation that the thought has been recorded (since
this data is read back from Fluidinfo after the write), that it is
thought #10 and that it was recorded on 11th August.&lt;/p&gt;
&lt;p&gt;I can look at my last five thoughts by using this command:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish thoughts 5

6: The Art of Tagging &amp;amp; the Tagging of Art
2011-07-31

7: Integrated fish history across all machines and shell-fish
2011-08-02

8: We need a word for words like suBtle, that are self-descriptive in non-onomatopoeic ways.
2011-08-08

9: A website featuring dodrantal things
2011-08-10

10: Perhaps savethewords.org would like to add threatened words and their definitions to Fluidinfo
2011-08-11&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It defaults to the last 20 if I don&amp;#8217;t specify.   I can also filter by putting search terms on the command line:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish thoughts art
6: The Art of Tagging &amp;amp; the Tagging of Art
2011-07-31&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and I can specify a range of thoughts:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish thoughts 8-9&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;What I&amp;#8217;ve built into Fish isn&amp;#8217;t, of course, a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;thought&lt;/span&gt;&lt;/tt&gt; command, but a general capability to create sequences.   The base command is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mkseq&lt;/span&gt;&lt;/tt&gt;, which makes a new sequence, and whose general form is:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mkseq sequence-name [plural-form [tag]]&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;thought&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;thoughts&lt;/span&gt;&lt;/tt&gt; commands were made using the command:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mkseq thought thoughts private/thought&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The first argument is the name of the command to add an item to the
sequence. The second argument, which is optional, is the plural form,
which is used to list items in the sequence; if it is not specified,
an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;s&lt;/span&gt;&lt;/tt&gt; is added to the singular form.  The final argument, also
optional, is the tag to use for storing the sequence.  In this case, I
wanted to keep my thoughts private, so I chose to use the tag
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/private/thought&lt;/span&gt;&lt;/tt&gt;; if not specified, the name of the sequence
item is used for the tag, in the user&amp;#8217;s top-level namespace,
i.e. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/thought&lt;/span&gt;&lt;/tt&gt; in this case.&lt;/p&gt;
&lt;p&gt;[Readers with intimate knowledge of Fluidinfo&amp;#8217;s permissions system
will spot a flaw with this scheme: since Fluidinfo&amp;#8217;s permissions are
not inherited, simply using the tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/private/thought&lt;/span&gt;&lt;/tt&gt; won&amp;#8217;t make
my thoughts private, even though my &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; namespace has its
permissions set to deny access to others.  However, that will
change next week, when Fluidinfo will gain create-time inheritance of
permissions; and I&amp;#8217;m not going to release this functionality until
then.]&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mkseq&lt;/span&gt;&lt;/tt&gt; command creates two aliases, as we can see using the
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alias&lt;/span&gt;&lt;/tt&gt; command:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish alias
thought:
  njr/.fish/alias = "seq private/thought"

$ thoughts:
  njr/.fish/alias = "listseq private/thought"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This reveals that the other two commands I&amp;#8217;ve added are &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;seq&lt;/span&gt;&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;listseq&lt;/span&gt;&lt;/tt&gt;.  The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;seq&lt;/span&gt;&lt;/tt&gt; command adds to a sequence using the tag
specified, and the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;listseq&lt;/span&gt;&lt;/tt&gt; command lists recent items from the
sequence with the tag specified.&lt;/p&gt;
&lt;p&gt;Because Fish &lt;a class="reference external" href="http://blog.abouttag.com/2011/08/alias-fish-and-sync.html"&gt;stores aliases in Fluidinfo itself&lt;/a&gt;, if I
use Fish from more than one place, I&amp;#8217;m but a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/tt&gt; away from being
able to record thoughts from any of those places.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-organization-of-sequence-data"&gt;
&lt;h2&gt;The organization of sequence data&lt;a class="headerlink" href="#the-organization-of-sequence-data" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are a number of ways that the trinity of sequence commands above
could have been implemented, but this is how I&amp;#8217;ve done it.  I&amp;#8217;m going
to use thoughts as the exemplar, here, but what follows applies to any
Fish sequence.&lt;/p&gt;
&lt;p&gt;The first question is: what object or objects should be used to store
the sequence?  In Fluidinfo, it is very natural to use one object per
thought.  I could have used anonymous objects (one with no &lt;em&gt;about&lt;/em&gt;
tag), and that&amp;#8217;s not a ridiculous idea in this case, where I&amp;#8217;m not
expecting sequences to make significant use of Fluidinfo&amp;#8217;s social
aspects.  In fact, however, what I decided to to was to use the
integers.  So my first thought is stored on the object whose about tag
is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;0&lt;/span&gt;&lt;/tt&gt;, the second is on the object with about tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;1&lt;/span&gt;&lt;/tt&gt; and so
forth.&lt;/p&gt;
&lt;p&gt;Thus, if I use Fish&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tags&lt;/span&gt;&lt;/tt&gt; command, I should see my thought number 10:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish tags -a 10
Object with about="10":
  /fluiddb/about = "10"
  /musicbrainz.org/related-albums = {"album:10 (asleep at the wheel)", "album:10 (box set)", "album:10 (cali gari)", "album:10 (divididos)", "album:10 (dj db)", "album:10 (enuff znuff)", "album:10 (freestyle)", "album:10 (harri marstio)", "album:10 (i8u)", "album:10 (johan johansson)", "album:10 (john anderson)", "album:10 (k s choice)", "album:10 (kate rusby)", "album:10 (linea 77)", "album:10 (liroy)", "album:10 (ll cool j)", "album:10 (mcguffey lane)", "album:10 (mercyme)", "album:10 (miskolci ütősök)", "album:10 (perplex)", "album:10 (sharon kips)", "album:10 (suat suna)", "album:10 (supersilent)", "album:10 (the dramatics)", "album:10 (the fools)", "album:10 (the stranglers)", "album:10 (user)", "album:10 (various artists)", "album:10 (wet wet wet)", "album:10 (тент)"}
  /musicbrainz.org/related-artists = {"artist:10"}
  /njr/index/about
  /njr/private/thought = "Perhaps savethewords.org would like to add threatened words and their definitions to Fluidinfo"
  /njr/private/thought-date = 20110811.0735
  /njr/private/thought-number = 10
  /wordtools/gcide = "10 \10\ adj.
1. denoting a quantity consisting of one more than nine and
one less than eleven; -- representing the number ten as
Arabic numerals

Syn: ten, x
[WordNet 1.5 +PJC]"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And indeed, in amongst other data, you see three &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr-thought&lt;/span&gt;&lt;/tt&gt; tag
and couple of others.  The thought itself is stored on the tag
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/private/thought&lt;/span&gt;&lt;/tt&gt;, as a string.  (Don&amp;#8217;t try this at home though:
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/private&lt;/span&gt;&lt;/tt&gt; is private, notwithstanding publication of select
extacts on this blog, and will be invisible to users who are
not &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt;.)&lt;/p&gt;
&lt;p&gt;Its number is stored, as a numeric value, on the tag
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/thought-number&lt;/span&gt;&lt;/tt&gt;: this might seem redundant, given that the
about tag for the object also stores that information, but the fact it
is numeric is extremely useful, allowing me to query based on the
thought number using inequalities.&lt;/p&gt;
&lt;p&gt;Finally, the date is stored as a numeric value.  Fluidinfo doesn&amp;#8217;t
support a date type, so the way I decided to store dates was as a
numeric value in the form &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;YYYYMMDD.hhmmss&lt;/span&gt;&lt;/tt&gt;.  This again makes it easy
to do queries based on a date range if I want to.  I am just using
the local time and not worrying about time zone issues.  Using
Greenwich Mean Time (GMT; or Coordinated Universal Time, UTC, as I
believe modern anti-imperialists are supposed to call it) would have
ensured that the time ordering of the datestamps was more consistent
with the sequence item numbers, but at the cost of making querying
less natural, especially for people not lucky enough to live near
longitude 0º.&lt;/p&gt;
&lt;p&gt;In addition to using these three tags to store the sequence itself,
Fish uses one further tag to record the next sequence number to
allocate, so as to avoid the need to perform a complex query to know
this.  The tag it uses is, in this case, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/private/thought-next&lt;/span&gt;&lt;/tt&gt;
and it stores this on the object for the user &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt;.  Taking
advantage of command substitution through left-quoting, and Fish&amp;#8217;s
integration of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;abouttag&lt;/span&gt;&lt;/tt&gt; library, we can see this by saying:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show -a "`fish abouttag fi-user njr`" private/thought-next
Object with about="Object for the user named njr":
/njr/private/thought-next = 11&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In case this isn&amp;#8217;t clear, Fish first executes the command&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish abouttag fi-user njr&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;which returns the &lt;em&gt;about&lt;/em&gt; tag Fluidinfo uses for the user object for
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt;.  The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;show&lt;/span&gt;&lt;/tt&gt; command then becomes:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show -a "Object for the user named njr" private/thought-next&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;which yields the expected result, 11.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="that-about-tag-convention"&gt;
&lt;h2&gt;That about tag convention&lt;a class="headerlink" href="#that-about-tag-convention" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I imagine some readers might be raising an eyebrow at my use of the
objects with about tags corresponding to the integers.  Wouldn&amp;#8217;t I
normally argue that about tags should be specific, encourage sharing
and discourage pollution of useful objects with irrelevant
information?&lt;/p&gt;
&lt;p&gt;All these things are true, but I think that, for the most part, they
don&amp;#8217;t apply in this case.  I think most of these sequences will be
private anyway, and in that sense there is no anti-social pollution
involved in using the integer about tags.  More fundamentally,
however, even if they are not private, I don&amp;#8217;t think there is any
great need for these items to be social.  Where data is not social,
and especially when private, the choice of object in Fluidinfo is
purely for the convenience of the user.  There is both logic and
convenience in using the integers.&lt;/p&gt;
&lt;p&gt;There is a partial down-side to using the same objects for different
sequences, and it is that any extra information needs to be stored in
sequence-specific tags.  This is one of the reasons that I used
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/private/thought-date&lt;/span&gt;&lt;/tt&gt; rather than a more generic
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/datestamp&lt;/span&gt;&lt;/tt&gt;.  It also means that if I wanted to add tags to the
object, they would also have to be similarly qualified.  It may be
that it will turn out that these are strong reasons to move away from
the integers, but for the moment I feel the benefits outweight the
disadvantages.  I may add support later for sequences using either
anonyous objects or ones with more specific about tags (like
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;thought-10&lt;/span&gt;&lt;/tt&gt; or even &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/thought-10&lt;/span&gt;&lt;/tt&gt;).
But for now, this is it.&lt;/p&gt;
&lt;p&gt;As always, I&amp;#8217;ll be interested in any thoughts; I hope to roll this
out next week semo time, after the API update.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll finish with a couple of sections describing where the motivation
for sequences in Fluidinfo and Fish came from, in case anyone is interested.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-importance-of-the-palm-pilot"&gt;
&lt;h2&gt;The Importance of the Palm Pilot&lt;a class="headerlink" href="#the-importance-of-the-palm-pilot" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;img alt="_images/PalmVxSmall.jpeg" src="_images/PalmVxSmall.jpeg" /&gt;
&lt;p&gt;Before 1999, I had always had a problem organizing information.
Wherever and however I recorded it, I would struggle to find it or
access it when I needed it.  The information came in many shapes and
sizes—books I wanted to buy, recipes, phone numbers, quotations,
thoughts, plans, ideas, locations of items I had found &amp;#8220;a safe place&amp;#8221;
for and so forth. None of it was very voluminous, but I wanted access
to it everywhere and I wanted to be able to search it and organize it.&lt;/p&gt;
&lt;p&gt;In 1999, I bought a Palm V, and from that point forward it&amp;#8217;s not much
of an exaggeration to say that my problems with information
disappeared.  The Palm became the place to record all (low-volume)
information.  I carried it almost everywhere when I was out, and I
synchronized it to my computer, and this meant I almost always had
access to all of it&lt;/p&gt;
&lt;p&gt;The Palm V was brilliant in a number of ways.  It had four primary
applications—notes, to-do lists, the address
book, and the calendar.  That doesn&amp;#8217;t sound like much, but when
combined with a couple of core feaures of Palm OS, and a little
imagination, it became a tremendously powerful system for organizing
little pieces of information.  For me, the two extra crucial features
were search and categorization.  In 1999, Palm OS had full text search
across all data in the major applications, and it worked superbly.  It
was actually better than most so called full-text search today.  (As a
trivial example, my iPhone today still won&amp;#8217;t search photograph names.)&lt;/p&gt;
&lt;p&gt;The second core feature of Palm OS that added to its organizational
prowess was categories.  Everything could be categorized, and though
they were a little mean in allowing (I think) only 12 categories, that
was just enough.  I could organize my little bits of information into
categories like books, food, travel, work and so forth. Even more
importantly, I could keep separate to-do lists in a dozen or so
categories.&lt;/p&gt;
&lt;p&gt;Perhaps most interesting application to me was the Address Book, which
I subverted as a database for anything to do with people.  I kept a
few categories of contacts in there (friends, family, business etc.),
but I also had categories like books, music and quotations.  For
example, I stored quotations under their originator
in the quotations category.  I stored information about books
under their author in the books category and so forth.  It was mad,
but worked remarkably well.&lt;/p&gt;
&lt;p&gt;By being almost always with me, both at my desk and on the go, and
providing categorization and full-text search, the data in the Palm
could genuinely function as my central repository for little bits of
information.  A problem I had always had went away.&lt;/p&gt;
&lt;p&gt;I moved from a Palm V to a Vx, then to a Sony Clié (also running Palm
OS) and eventually to a Palm T|X, all of which were fine machines, and
the data came with me.  But four years ago, the iPhone was born, and
there was not a moment&amp;#8217;s doubt that this was the device that would
finally allow me to move from carrying a phone and a PDA to a single
device.  (The Handsprings were never tempting, and nothing before or
since, I would argue, comes close to the iPhone in overall power and
utility.)  But marvellous as the iPhone is, despite its
ever-improving synchronization methods, the iPhone + Mac combination
is not as powerful for organizing little bits of information as the
Palm was.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-power-of-logging"&gt;
&lt;h2&gt;The Power of Logging&lt;a class="headerlink" href="#the-power-of-logging" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;img alt="_images/miro.png" src="_images/miro.png" /&gt;
&lt;p&gt;I am not particularly happy about organizations collecting
ever-increasing quantities of data about me, though like most people I
put up with it in some cases because of the benefits that come with,
for example, carrying a device that geolocates me day and night.&lt;/p&gt;
&lt;p&gt;I am, however, much happier about the idea of recording information
myself, for my benefit, under my control.&lt;/p&gt;
&lt;p&gt;For the last four years or so, I have been working on a the Artists
Suite, a set of data analysis tools whose lead component is Miró.
From very early on, I was clear that I wanted the software to log
almost everything it did.  Miró is a command-driven system, and among
things, it records every command issued to it (on a per-session basis)
and all the results it generates.  Miró never deletes any of its
history (though users can, obviously) and as a result I now have
nearly four years of logs detailing how I&amp;#8217;ve used Miró myself—logs of
well over 10,000 analysis sessions.  This has turned out to be even
more useful than I expected.  It helps, I suppose, that as an analysis
tool, Miró can read, search and analyse its own logs.  But the
fundamental power lies simply in recording everything, with no effort
required on my part.  Miró annotates the data, of course, with
datestamps and sequence numbers, and records how the session was
invoked and so forth, and I regularly go back and use the logs to
reconstruct what I did previously in a way I simply would be unable to
do otherwise.  This had made a poerful impression on me.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-2012800898993052609?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/2012800898993052609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/08/sequences-in-fluidinfo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/2012800898993052609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/2012800898993052609'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/08/sequences-in-fluidinfo.html' title='Sequences in Fluidinfo'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-3892797956099197876</id><published>2011-08-11T14:47:00.003+01:00</published><updated>2011-08-11T15:27:27.962+01:00</updated><title type='text'>Gigs in Fluidinfo</title><content type='html'>&lt;div class="section" id="gigs-and-concerts-in-fluidinfo"&gt;
&lt;p&gt;I&amp;#8217;ve written previously on &lt;a class="reference external" href="http://blog.abouttag.com/2011/06/he-music-of-fluidinfo-ii.html"&gt;about-tag conventions for music in Fluidinfo&lt;/a&gt;,
and if you &lt;a class="reference external" href="https://abouttag.appspot.com/search"&gt;search&lt;/a&gt; for almost
any artist or album in Fluidinfo you&amp;#8217;ll see the great progress that
Eric Seidel (&lt;a class="reference external" href="http://twitter.com/gridaphobe"&gt;&amp;#64;gridaphobe&lt;/a&gt;)
has already made in this area, with more to come.&lt;/p&gt;
&lt;p&gt;So far, the main conventions I&amp;#8217;ve discussed concern artists,
albums and tracks, which are exemplified by&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://abouttag.appspot.com/monowing/about/artist:pink%20floyd"&gt;artist:pink floyd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://abouttag.appspot.com/monowing/about/album:the%20dark%20side%20of%20the%20moon%20(pink%20floyd)"&gt;album:the dark side of the moon (pink floyd)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://abouttag.appspot.com/monowing/about/track%3Aspeak%20to%20me%20%28pink%20floyd%29"&gt;track:speak to me (pink floyd)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;What about gigs?&lt;/p&gt;
&lt;p&gt;My first thoughts are the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Most gigs are primarily defined by an artist (or sometimes artists)
and a date.&lt;/li&gt;
&lt;li&gt;Very occasionally an artist may play two gigs in one day;
in that case, adding a venue or a time ought to be sufficient
to disambigate it&lt;/li&gt;
&lt;li&gt;As usual, these things are easy to know if you attend the gig,
have a ticket or a listing, and are pretty unambiguous.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;I therefore think there are two prime options for defining gigs.
The first would to use only the artist and date, in the main case,
and to qualify &lt;em&gt;when necessary&lt;/em&gt; with a disambiguating time
(this being less ambiguous than place).   The second option is to use
artist, date and start time in every case.   (I suppose time zone
considerations could mess up the non-ambiguity of full datestamps,
but I don&amp;#8217;t care.)&lt;/p&gt;
&lt;p&gt;The former has the considerable advantage of simplicity, and I would
imagine will be unique well over 99.9% of the time; the latter is more
precise and uniform, but has the significant disadvantage that start
times are harder to know and less clearly defined.&lt;/p&gt;
&lt;p&gt;On balance, therefore, I am tempted to suggest that gigs be
exemplified by the following:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;gig:dean friedman (2011-08-10)&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;and,  where an artist performs more than once on the same day,
and when it is important to distinguish:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;gig:dean friedman (2011-08-10:21:00)&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;(I think sub-minute accuracy will probably not be required in this case.&lt;/p&gt;
&lt;p&gt;As an example, Dean Friedman, surely one of the finest songwriters
and performers playing today, performed last night, as part of the
Edinburgh Fringe, at the Music Box, at Stevenson College.
Here is the object for that gig&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://abouttag.appspot.com/monowing/about/gig%3Adean%20friedman%20%282011-08-10%29"&gt;gig:dean friedman (2011-08-10)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;and my here is the address of my &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/review&lt;/span&gt;&lt;/tt&gt; tag for it:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;http://fluiddb.fluidinfo.com/about/gig:dean friedman (2011-08-10)/njr/review&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s value is:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show -a 'gig:dean friedman (2011-08-10)' review
Object with about="gig:dean friedman (2011-08-10)":
  /njr/review = "http://fluiddb.fluidinfo.com/about/gig:dean%20friedman%20%282011-08-10%29/njr/review.html"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That URL, points to the review itself, which is stored in Fluidinfo,
in the tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/review.html&lt;/span&gt;&lt;/tt&gt;, which can be view at
&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/gig:dean%20friedman%20%282011-08-10%29/njr/review.html"&gt;http://fluiddb.fluidinfo.com/about/gig:dean friedman (2011-08-10)/njr/review.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A reasonable alternative to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;gig&lt;/span&gt;&lt;/tt&gt; be &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;concert&lt;/span&gt;&lt;/tt&gt;, which I suspect will
be used in preference for classic music, but the ubiquity of the term
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;gig&lt;/span&gt;&lt;/tt&gt; for non-classical music (and even, colloquially, for classical
concerts) suggests that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;gig&lt;/span&gt;&lt;/tt&gt; is the better starting point.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-3892797956099197876?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/3892797956099197876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/08/gigs-in-fluidinfo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3892797956099197876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3892797956099197876'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/08/gigs-in-fluidinfo.html' title='Gigs in Fluidinfo'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-602544875055779702</id><published>2011-08-09T07:56:00.002+01:00</published><updated>2011-09-09T07:00:14.766+01:00</updated><title type='text'>Alias Fish and Sync</title><content type='html'>  &lt;div class="section" id="alias-fish-and-sync"&gt;
&lt;p&gt;I&amp;#8217;ve been making a number of changes to the Fluidinfo shell,
&lt;a class="reference external" href="http://github.com/njr0/fish"&gt;Fish&lt;/a&gt;.   I haven&amp;#8217;t pushed them to
GitHub yet or the online version,
&lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;Shell-Fish&lt;/a&gt;,
yet, for various reasons, but I can start to document them.&lt;/p&gt;
&lt;div class="section" id="aliases"&gt;
&lt;h2&gt;Aliases&lt;a class="headerlink" href="#aliases" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The provision of aliases is a fairly basic part of a shell that Fish has
lacked until now.   I have added a simple form of aliasing that is exemplified
by the following example:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish alias plp 'show -q "has njr/lastpage" /about'&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This creates an alias called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;plp&lt;/span&gt;&lt;/tt&gt; that expands to the text given so that
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;plp&lt;/span&gt;&lt;/tt&gt; will show the &lt;em&gt;about&lt;/em&gt; tags for any objects tagged
with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/lastpage&lt;/span&gt;&lt;/tt&gt; tag.  If I run this command now I get:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish plp
1 object matched
Object f79d5ea3-50c1-4c9e-b98e-7bbe46b69ee1:
  /fluiddb/about = "http://www.guardian.co.uk/"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;because the page tagged with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/lastpage&lt;/span&gt;&lt;/tt&gt; is currently
the Guardian&amp;#8217;s website.&lt;/p&gt;
&lt;p&gt;A couple of syntactic details to note about these aliases:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;The alias only applies to the first (non-flag) word in the command.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Any arguments that follow the aliased term are added to the
substituted command.   So, for example, the alias&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;alias parisrating 'show -a "Paris" rating'&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;if invoked as&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish parisrating /alice/rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;will show both my rating of Paris (as specified in the alias),
and Alice&amp;#8217;s, as specified in the command, viz:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish parisrating /alice/rating
Object with about="Paris":
  /njr/rating = 9
  /alice/rating = "smelly"&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;There is no provision for using positional arguments such as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;$1&lt;/span&gt;&lt;/tt&gt; yet.
This will change, as surely as night follows day.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;So far, so boring.   But here&amp;#8217;s something slightly more interesting:
where should Fish store its aliases?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="storing-aliases-in-fluidinfo"&gt;
&lt;h2&gt;Storing Aliases in Fluidinfo&lt;a class="headerlink" href="#storing-aliases-in-fluidinfo" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The question need only be posed for the answer to present itself:
obviously, Fish should store aliases in Fluidinfo; as it does.
This turns out to be quite interesting.&lt;/p&gt;
&lt;p&gt;Fish stores aliases on objects whose &lt;em&gt;about&lt;/em&gt; tag is the alias;
in other words, the alias &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;parisrating&lt;/span&gt;&lt;/tt&gt; is stored on the object
whose &lt;em&gt;about&lt;/em&gt; tag is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;parisrating&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish tags -a parisrating
Object with about="parisrating":
  /fluiddb/about = "parisrating"
  /njr/.fish/alias = "show -a "Paris" rating"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;As you can see, the alias is stored in a tag called
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/.fish/alias&lt;/span&gt;&lt;/tt&gt;, and the value of that tag is simply the expansion
text.  (I know, I know: the output is confusing, embedding,
as it does, double quotes in a double-quoted string, without any
escaping.   There is an excuse, but not one that&amp;#8217;s worth the electrons.)&lt;/p&gt;
&lt;p&gt;Both the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;.fish&lt;/span&gt;&lt;/tt&gt; namespace and the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;.fish/alias&lt;/span&gt;&lt;/tt&gt; tag are private,
by default, as you can see:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish ls -ld .fish .fish/alias
nrwc------   njr/.fish/
trwc------   njr/.fish/alias&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or if you prefer your permissions Fluidinfo-style:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish ls -Ld .fish .fish/alias

njr/.fish/:
     read: policy: closed; exceptions = [njr]
    write: policy: closed; exceptions = [njr]
  control: policy: closed; exceptions = [njr]


njr/.fish/alias:
     read: policy: closed; exceptions = [njr]
    write: policy: closed; exceptions = [njr]
  control: policy: closed; exceptions = [njr]&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Of course, the user can change this.&lt;/p&gt;
&lt;p&gt;Storing the alias this way involves a small leakage of potentially
private information, in the sense that people can see that an object
with the &lt;em&gt;about&lt;/em&gt; tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;parisrating&lt;/span&gt;&lt;/tt&gt; exists, though not that anyone is
using it as an alias, or who is doing so, or what the alias expands
to.  I could have avoided this by using anonymous objects and another
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;.fish&lt;/span&gt;&lt;/tt&gt; tag instead of the &lt;em&gt;about&lt;/em&gt; tag, but I think the approach
I&amp;#8217;ve adopted is better overall.  If you share my philosphical
perspective that objects for every possible about tag already exist,
but are lazily instantiated, there is no leakage, but obviously in the
non-platonic Amazon server farm where the data is hosted, Plato&amp;#8217;s writ
does not run.  (This is probably a good thing; imagine what Amazon
would charge to host Fluidinfo&amp;#8217;s data if we admitted that every possible
string is stored.)&lt;/p&gt;
&lt;p&gt;The principal advantage of storing the alias in Fluidinfo is that
it is available from anywhere.   So if I have Fish on several machines
(and I do) I can create the alias once and use it from everywhere.
In principle, I can also use it from the online version of Fish
(&lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;Shell-Fish&lt;/a&gt;),
but that isn&amp;#8217;t implemented yet, which is one of the reasons I haven&amp;#8217;t
committed this to GitHub yet.&lt;/p&gt;
&lt;p&gt;There is also a downside to storing aliases in Fluidinfo, which is
that retrieving the definitions requires a Fluidinfo query.
Given that alias expansion precedes command matching (so that
built-in Fish commands can be replaced), this lookup is required
before each command is evaluated; for Fish&amp;#8217;s single-shot mode,
where a single Fish command is entered from a Unix or Windows prompt,
that introduces a delay I am not keen to accept.&lt;/p&gt;
&lt;p&gt;For this reason, the Fish cache has been born.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="caching-fluidinfo-for-fish"&gt;
&lt;h2&gt;Caching Fluidinfo for Fish&lt;a class="headerlink" href="#caching-fluidinfo-for-fish" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The Fish cache is simply a dump of a Fish&amp;#8217;s internal representation
of certain Fluidinfo objects to local storage.   Specifically,
on Unix, Fish writes a file (a pickle file) to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.fishcache.username&lt;/span&gt;&lt;/tt&gt;
where &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;username&lt;/span&gt;&lt;/tt&gt; is the authenticated user&amp;#8217;s username.
When Fish is invoked with arguments, it reads the cache,
which includes all the objects used for aliases.&lt;/p&gt;
&lt;p&gt;When an alias is created (or deleted), Fish first makes the change
in Fluidinfo, then updates the cache.&lt;/p&gt;
&lt;p&gt;There is then a new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/tt&gt; command, which updates the cache from
Fluidinfo.  It is important to be clear that this synchronization does
not involve any kind of mediation: the cache is cleared and updated
from Fluidinfo; Fluidinfo is the source of truth.&lt;/p&gt;
&lt;p&gt;This means that in order to get any aliases (or alias deletions)
performed by a different copy of Fish, you need to perform a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/tt&gt;
operation.&lt;/p&gt;
&lt;p&gt;When Fish is invoked without arguments, Fish performs a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/tt&gt;
before accepting any input.&lt;/p&gt;
&lt;p&gt;The plan for the online version of Fish is very similar to the
interactive version except that instead of using local files,
the online version will store its cache in the &amp;#8220;local&amp;#8221; database
(which, in the case of Google App Engine, means the Data Store).&lt;/p&gt;
&lt;p&gt;I think this approach holds great promise, not only for aliases,
but for other important Fish data, probably including configuration
parameters.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="summary-of-the-alias-unalias-and-sync-and-showcache-commands"&gt;
&lt;h2&gt;Summary of the alias, unalias and sync and showcache commands&lt;a class="headerlink" href="#summary-of-the-alias-unalias-and-sync-and-showcache-commands" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;alias&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alias&lt;/span&gt;&lt;/tt&gt; command is summarized as follows:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;expansion&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With no parameters, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alias&lt;/span&gt;&lt;/tt&gt; lists all aliases and their expansions.&lt;/p&gt;
&lt;p&gt;With a single parameter, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alias&lt;/span&gt;&lt;/tt&gt; lists the expansion for the alias specified
(if it exists).&lt;/p&gt;
&lt;p&gt;With two or more parameters, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alias&lt;/span&gt;&lt;/tt&gt; defines (or redefines) an alias.
It is best to quote the expansion text as a single
parameter to stop Fish from interpreting it, though in simple cases
this is strictly unnecessary.
Here are some examples:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish alias book 'abouttag book'

$ fish book 'Fugitive Pieces' 'Anne Michaels'
book:fugitive pieces (anne michaels)

$ fish alias book
book:
  njr/.fish/alias = "abouttag book"

$ fish alias
book:
  njr/.fish/alias = "abouttag book"

parisrating:
  njr/.fish/alias = "show -a "Paris" rating"

plp:
  njr/.fish/alias = "show -q "has njr/lastpage" /about"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;unalias&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There is also an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;unalias&lt;/span&gt;&lt;/tt&gt; command.   You can probably guess
how it works.   To remove the three aliases above you would say:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish unalias book parisrating plp&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;showcache&lt;/strong&gt; and &lt;strong&gt;sync&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Finally, the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;showcache&lt;/span&gt;&lt;/tt&gt; command can be used to show the contents
of the cache, and the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sync&lt;/span&gt;&lt;/tt&gt; command can be used to update it from
Fluidinfo.&lt;/p&gt;
&lt;p&gt;In this particular case, I deleted the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;parisrating&lt;/span&gt;&lt;/tt&gt; alias on another
machine with this result:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ sync

$ showcache
Cache:

  fluiddb/about="plp":
      njr/.fish/alias = "show -q "has njr/lastpage" /about"

  fluiddb/about="book":
      njr/.fish/alias = "abouttag book"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Today, the cache stores only aliases, so the output from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;showcache&lt;/span&gt;&lt;/tt&gt;
tends to look rather similar to that from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alias&lt;/span&gt;&lt;/tt&gt;, but as other types
of data start to be cached, a sharper distinction will be drawn.&lt;/p&gt;
&lt;p&gt;I have a good feeling about this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Post Script&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you are using Fluidinfo directly, and are not taking advantage
of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/values&lt;/span&gt;&lt;/tt&gt; API, you really should check it out: it is dramatically
faster.   I have been a bit slow to upgrade Fish to use it, but that is
now happening incrementally, and is yielding very significant and
welcome performance improvements everywhere.   Think of the difference
between drinking beer with a straw and glugging it straight from the glass;
there is simply no comparison.&lt;/p&gt;
&lt;p&gt;[Thanks to &lt;a class="reference external" href="http://twitter.com/joannescrub"&gt;&amp;#64;joannescrub&lt;/a&gt; for taking the
time to point out a number of typos in this post.]&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-602544875055779702?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/602544875055779702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/08/alias-fish-and-sync.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/602544875055779702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/602544875055779702'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/08/alias-fish-and-sync.html' title='Alias Fish and Sync'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-1577650244057013666</id><published>2011-07-31T19:44:00.002+01:00</published><updated>2011-08-01T22:06:09.004+01:00</updated><title type='text'>The End of the Fish Wars: The Fluidinfo Shell Version 4.0</title><content type='html'>&lt;div class="section" id="the-end-of-the-fish-wars-the-fluidinfo-shell-version-4-0"&gt;A funny thing happened.   Terry (Jones; Fluidinfo creator, founder, CEO etc.) started using Fish and declared that he preferred using Unix-style paths in it.   Given that the whole reason for adding support for non-Unix-style paths was the distress Unix-style paths appeared to cause Terry, this was a happy surprise.   It turns out that I slightly misunderstood his position.&lt;br /&gt;
So with his complete blessing, the latest version of Fish defaults to Unix-style paths, i.e. except in queries, if a tag path does not start with a leading &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/&lt;/span&gt;&lt;/tt&gt;, it is assumed to be in the authenticated user’s namespace; paths for tags and namespaces of other users are introduced with a leading &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/&lt;/span&gt;&lt;/tt&gt;.   So if I use fish, my rating tag is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt;, but Terry’s is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/terrycojones/rating&lt;/span&gt;&lt;/tt&gt;.&lt;br /&gt;
If you already use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;, this affects you only if you have been using Fluidinfo-style paths without setting that explicitly in your &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.fluidDBcredentials&lt;/span&gt;&lt;/tt&gt; file.  If that’s the case, and you want to continue using Fluidinfo-style long paths, add a third line to that file as follows:&lt;br /&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;username
password
unix-style-paths false&lt;/pre&gt;&lt;/div&gt;Users of te online version, &lt;a class="reference external" href="http://shell-fish.appspot.com/"&gt;Shell-Fish&lt;/a&gt;, won’t see any difference when they’re logged in as the preference will be remembered.   But if you use the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user, it now uses Unix-style paths.&lt;br /&gt;
The new consensual goal is to make Fish &lt;em&gt;report&lt;/em&gt; as much as it can using Fluidinfo-style paths, but to default to unix-style for input. So the abbreviated form is seen primarily as a shortcut for input (which is, indeed, what it is).  The complication is that this makes it harder for Fish to consume its own output; so I will make changes slowly, trying to ensure that things like command substitution with left quoting are facilitated as much as possible.&lt;br /&gt;
There are a few minor improvements to Fish in 4.00 as well as the paths change.   It’s gained &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;exit&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;quit&lt;/span&gt;&lt;/tt&gt; commands to leave the interactive shell (though ^D (unix) and ^Z (Windows) still work). And it’s gained a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;get&lt;/span&gt;&lt;/tt&gt; command, which is like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;show&lt;/span&gt;&lt;/tt&gt;, but more minimal, returning the information you request with no extras.   Compare and contrast:&lt;br /&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show -a Paris rating /about
Object with about="Paris":
  /njr/rating = 10
  /fluiddb/about = "Paris"

$ fish get -a Paris rating /about
10
"Paris"&lt;/pre&gt;&lt;/div&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;get&lt;/span&gt;&lt;/tt&gt; form is motivated partly, again by, a desire to make it as simple as possible for Fish (and other things) to consume the output.&lt;br /&gt;
There’s also better mobile support in the online version, Shell-Fish, but that’s another blog post (coming shortly).&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-1577650244057013666?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/1577650244057013666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/07/end-of-fish-wars-fluidinfo-shell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/1577650244057013666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/1577650244057013666'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/07/end-of-fish-wars-fluidinfo-shell.html' title='The End of the Fish Wars: The Fluidinfo Shell Version 4.0'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-4915343659583838364</id><published>2011-07-26T20:49:00.000+01:00</published><updated>2011-07-26T20:49:29.727+01:00</updated><title type='text'>Movement and Renaming In Fluidinfo and Fish</title><content type='html'>  &lt;div class="section" id="movement-and-renaming-in-fluidinfo-and-fish"&gt;
&lt;p&gt;The Fluidinfo Shell, &lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;Fish&lt;/a&gt;, already
includes Unix-inspired commands for many tag-management tasks
including listing tags and namespaces (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt;), removing them
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt;), creating them (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;touch&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mkns&lt;/span&gt;&lt;/tt&gt;/&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mkdir&lt;/span&gt;&lt;/tt&gt;) as well an
analogue of the Unix &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;chmod&lt;/span&gt;&lt;/tt&gt; permissions-changing command
(&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt;).  What about copying and renaming?&lt;/p&gt;
&lt;p&gt;The Unix command for renaming files is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; (short for &lt;em&gt;move&lt;/em&gt;).  I
imagine this is briefly confusing for newcomers to Unix, but the
command is actually well named when all its functions are considered.
In Unix, to rename a file from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;foo&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bar&lt;/span&gt;&lt;/tt&gt; one says:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv foo bar&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The same form can be used to rename a directory, say from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;
to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;secret&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv private secret&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The true appropriateness of the name &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; becomes apparent only when
the command is used for it third form, in which the destination is an
existing directory.  If &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;etc&lt;/span&gt;&lt;/tt&gt; is such an existing directory then&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv foo etc&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;will &lt;em&gt;move&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;foo&lt;/span&gt;&lt;/tt&gt; into the directory &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;etc&lt;/span&gt;&lt;/tt&gt;; or, if you prefer, it
&lt;em&gt;renames&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;foo&lt;/span&gt;&lt;/tt&gt; as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;etc/foo&lt;/span&gt;&lt;/tt&gt;.   The same thing happens with a
directory, i.e.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv private etc&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;will move the directory &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; into &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;etc&lt;/span&gt;&lt;/tt&gt; as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;etc/private&lt;/span&gt;&lt;/tt&gt;.
We can also move several files at the same time:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv foo private etc&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;will move both &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;foo&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; to etc., which is handy.&lt;/p&gt;
&lt;p&gt;Should Fish do something similar?&lt;/p&gt;
&lt;div class="section" id="moving-tags-and-values-in-fish"&gt;
&lt;h2&gt;Moving Tags and Values in Fish&lt;a class="headerlink" href="#moving-tags-and-values-in-fish" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There seems to be every reason to support a similar &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; command in
Fish.  As with files, we may wish to rename a tag or
namespace, or to move it within the tag hierarchy, and Unix provides
a well-thought-through, powerful and convenient template for this.
Tags would behave like files, and namespaces like directories.
But there is a complication, as we shall see.&lt;/p&gt;
&lt;p&gt;In Fluidinfo, a named tag, such as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/rating&lt;/span&gt;&lt;/tt&gt; is an &lt;em&gt;abstract&lt;/em&gt;
entity: it doesn&amp;#8217;t really store any significant information itself.
The tag may be attached to many objects, with different values or none
on each.  We can think of those tags-attached-to-objects as &lt;em&gt;concrete&lt;/em&gt; tags
or &lt;em&gt;tag instances&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;So if Fish implemented an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mv&lt;/span&gt;&lt;/tt&gt; command as above, then if authenticated
as user &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt; (and using Unix-style paths in Fish), the command&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv rating star-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;would change the name of the tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/rating&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/star-rating&lt;/span&gt;&lt;/tt&gt;
not just in one place, but everywhere it occurs in the system.
Similarly, if &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/private&lt;/span&gt;&lt;/tt&gt; is a namespace,&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv private secret&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;would rename not only the tags in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/private&lt;/span&gt;&lt;/tt&gt;, but on every object
to which those tags are attached.&lt;/p&gt;
&lt;p&gt;This is not so much a problem as an opportunity.   There is definitely
a need for an easy way to rename and move whole named abstract tags
and namespaces, but it would also be useful to be able to move and
rename individual concrete tags.   For example,
maybe I want to rename my &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/rating&lt;/span&gt;&lt;/tt&gt; tag on &lt;em&gt;Citizen Kane&lt;/em&gt;
from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/rating&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/star-rating&lt;/span&gt;&lt;/tt&gt; (preserving its value).
(After all, film ratings are all about stars, right?)&lt;/p&gt;
&lt;p&gt;The obvious thing to do there would be to add a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt; to specify
the about tag for the object:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv -a 'film:citizen kane (1941)' rating star-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It could also accept &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-i&lt;/span&gt;&lt;/tt&gt;, to specify by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ID&lt;/span&gt;&lt;/tt&gt;, or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-q&lt;/span&gt;&lt;/tt&gt; to choose a set
of objects for which to apply the renaming with a Fluidinfo query.&lt;/p&gt;
&lt;p&gt;So far, so good.  But what if it is a &lt;em&gt;different&lt;/em&gt; kind of movement
that I desire?  What if I want to move the tag to a different
&lt;em&gt;object&lt;/em&gt;?  Perhaps I&amp;#8217;ve used the wrong object, or wish to swap to a
different convention for about tags.  As an example, let&amp;#8217;s suppose I
missed out the year required in the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;film-u&lt;/span&gt;&lt;/tt&gt; convention when
constructing the about tag for the film &lt;em&gt;Citizen Kane&lt;/em&gt;.  How would I
move the tag from one object to another?&lt;/p&gt;
&lt;p&gt;Perhaps the most obvious approach would be to repeat the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt;
flag to specify two different about tags.  The library Fish uses for
processing command-line options does allow them to be repeated, so the
command could be&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv -a 'film:citizen kane' -a 'film:citizen kane (1941)' rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Notice that there tag appears only once, because here, it&amp;#8217;s not being
renamed.  However, I really don&amp;#8217;t like repeated tags; they are quite
rare in Unix and feel sloppy to me.  I&amp;#8217;d be more tempted to use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-b&lt;/span&gt;&lt;/tt&gt;
for the second one (from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;a&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;b&lt;/span&gt;&lt;/tt&gt;; &lt;em&gt;geddit?&lt;/em&gt;).  So then it would
be:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv -a 'film:citizen kane' -b 'film:citizen kane (1941)' rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You could also perform a renaming at the same time:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv -a 'film:citizen kane' -b 'film:citizen kane (1941)' rating star-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;which you might prefer to express as&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv -a 'film:citizen kane'/rating -b 'film:citizen kane (1941)' star-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We could do something similar with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-i&lt;/span&gt;&lt;/tt&gt; (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-j&lt;/span&gt;&lt;/tt&gt; for the second, I
suppose); it doesn&amp;#8217;t really apply in the case of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-q&lt;/span&gt;&lt;/tt&gt; since it would
be optimistic in the extreme to expect pairs of about tags from two
different queries to align correctly.&lt;/p&gt;
&lt;p&gt;What I&amp;#8217;ve described so far seems fairly workable, and is my current best
guess at what I&amp;#8217;ll try to implement.   A &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; command would be fairly
similar, and would probably require a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt; flag for recursion.&lt;/p&gt;
&lt;p&gt;But there is an alternative that seems worth discussing, even if only
to reject it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-endpoint-approach"&gt;
&lt;h2&gt;The endpoint approach&lt;a class="headerlink" href="#the-endpoint-approach" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I generally think of tags as being attached to objects,
sometimes with values, pretty much exactly as the diagrams
generated by &lt;a class="reference external" href="http://abouttag.appspot.com"&gt;http://abouttag.appspot.com&lt;/a&gt; show them.   Here&amp;#8217;s an example
for &lt;em&gt;Citizen Kane&lt;/em&gt;.&lt;/p&gt;
&lt;a href="http://www.flickr.com/photos/njradcliffe/5976095592/" title="citizen-kane-object.png by njradcliffe, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6003/5976095592_44fd768e9b_z.jpg" width="528" height="187" alt="citizen-kane-object.png"&gt;&lt;/a&gt;
&lt;p&gt;(You can generate this live, in a modern browser, by visiting
&lt;a class="reference external" href="https://abouttag.appspot.com/butterfly/about/film:citizen%20kane%20(1941)"&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;And I think of the (abstract) tags and namespaces as living in a tree,
exactly like the directory structure in a hierarchical file system.
Something like this, where the yellow folder icons represent namespaces
and the tags are red.&lt;/p&gt;
&lt;a href="http://www.flickr.com/photos/njradcliffe/5978261679/" title="FluidinfoTagHierarchy.png by njradcliffe, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6015/5978261679_3dd0a15e9f.jpg" width="458" height="351" alt="FluidinfoTagHierarchy.png"&gt;&lt;/a&gt;
&lt;p&gt;The analogy can even be extended further by thinking of the value on a
tag as being like a file&amp;#8217;s contents; this seems particularly apt in
cases where the tag values really do correspond to file contents, as
is the case with Fish&amp;#8217;s documentation.  Using a pair of tricks stolen
from &lt;a class="reference external" href="http://ntoll.org"&gt;Nicholas Tollervery&lt;/a&gt; (&lt;a class="reference external" href="http://twitter.com/ntoll"&gt;&amp;#64;ntoll&lt;/a&gt;), the documentation is actually stored in
Fluidinfo, with the content of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;index.html&lt;/span&gt;&lt;/tt&gt; file stored in a
&lt;em&gt;tag&lt;/em&gt; called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;index.html&lt;/span&gt;&lt;/tt&gt; under the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; namespace.  So the full
path for the tag that stores the front page of Fish&amp;#8217;s documentation is
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish/index.html&lt;/span&gt;&lt;/tt&gt; and this (concrete) tag is stored on the object
with the about tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;.  The URL for the documentation is then
&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;http://fluiddb.fluidinfo.com/about/fish/fish/index.html&lt;/a&gt;.  The second
&amp;#8220;trick&amp;#8221; is to set the MIME type of the value of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish/index.html&lt;/span&gt;&lt;/tt&gt; on
the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; object to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;text/html&lt;/span&gt;&lt;/tt&gt;, which causes Fluidinfo to
serve the content with that MIME type, so that as far as the internet
is concerned, &lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;http://fluiddb.fluidinfo.com/about/fish/fish/index.html&lt;/a&gt;
&lt;em&gt;is&lt;/em&gt; regular HTML web content.  The same applies to all the other
pages.  It will come as no surprise to learn that the fish
documentation is published programmatically, and that I have vague
plans to add a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;publish&lt;/span&gt;&lt;/tt&gt; command to Fish to allow a directory tree
of files to be uploaded to Fluidinfo as a set of tags on namespaces on
a nominated object.&lt;/p&gt;
&lt;p&gt;It will not have escaped your attention in this digression, that a
crucial difference between a file in a filesystem and a tag in
Fluidinfo is that the tag may have arbitrarily many &lt;em&gt;different&lt;/em&gt;
values, each attached to a different object.  It&amp;#8217;s like having your
file system partially replicated on every computer in the world, with
different content on the subset of files stored on each.&lt;/p&gt;
&lt;p&gt;This suggests a different way of thinking about the relationship
between the tag hierarchy and objects, which is really the way that
Fluidinfo&amp;#8217;s &lt;em&gt;end-points&lt;/em&gt; use them.   In this view, each object has
a partial copy of the (abstract) tag hierarchy instantiated on it,
with values that are specific (and hopefully appropriate) to that object.&lt;/p&gt;
&lt;p&gt;This is neatly illustrated by looking at a recursive listing of
the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user&amp;#8217;s top-level namespace:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish ls -R

fish:
_static/            h                   p                   tags.html
a                   help.html           perms.html          test.html
about.html          i                   pwd.html            touch.html
abouttag.html       index.html          pwn.html            u
amazon.html         install.html        q                   unixlike.html
b                   j                   r                   untag.html
c                   k                   rm.html             v
cli.html            l                   s                   version.html
commands.html       ls.html             search.html         w
count.html          m                   searchindex.js      whoami.html
d                   mkdir.html          shell-fish.html     x
e                   mkns.html           show.html           y
f                   n                   su.html             z
g                   normalize.html      t
genindex.html       o                   tag.html

fish/_static:
basic.css           default.css         fish-doc-logo.png   pygments.css
def.css             doctools.js         jquery.js           searchtools.js&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;All the tags that look like filenames (the ones containing a dot)
are tags that exist in exactly one place—on the object with the
about tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;.   (They could occur in multiple places, however.
For example, I could publish the full set of documentation to
version-numbered objects &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt; &lt;span class="pre"&gt;v3.12&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt; &lt;span class="pre"&gt;v3.11&lt;/span&gt;&lt;/tt&gt; etc.,
rather than constantly replacing the old with the new, as I do now.)&lt;/p&gt;
&lt;p&gt;The other tags (those with single-letter names) are there to allow
anyone playing with the online version of Fish (&lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;shell-fish&lt;/a&gt;) to tag things with a set of
different tags, and might exist on any set of objects in Fluidinfo.&lt;/p&gt;
&lt;p&gt;In this view, the full path for a concrete tag can be expressed
either in terms of its about tag (if it has one) or its ID.
In the case of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish/index.html&lt;/span&gt;&lt;/tt&gt;, the only concrete instantiation
taht exists today lives under the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/about&lt;/span&gt;&lt;/tt&gt; endpoint, at&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;/about/fish/fish/index.html&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;or, for those of you who prefer UUIDs, under the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/objects&lt;/span&gt;&lt;/tt&gt; endpoint, at&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;/objects/0e7b94c7-1b37-41c2-bd7f-1a376786aa4e/fish/index.html&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This suggests an alternative possible syntax for moving concrete tags.
We could recast&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv -a 'film:citizen kane' /rating -b 'film:citizen kane (1941)' star-rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;as&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv '/about/film:citizen kane/njr/rating' '/about/film:citizen kane (1941)/star-rating'&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This approach is not without its attractions.  It is rather elegant
and unambiguous, and it completely eliminates the need for flags in
this case, which can hardly fail to be a benefit.  On balance,
however, I think it&amp;#8217;s probably not the way to go.  It feels somewhat
inconsistent with thre rest of Fish, it forces me to put the username
in (which I don&amp;#8217;t really want to do) and—to me—it feels slightly
inverted (if logical).   There&amp;#8217;s also a potential problem that there&amp;#8217;s
technically ambiguity with respect to a potential user called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;about&lt;/span&gt;&lt;/tt&gt;,
but that probably isn&amp;#8217;t such a worry.&lt;/p&gt;
&lt;p&gt;But the more important reason is that I dont want to have to repeat
the object specification if I do something like&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;mv '/about/film:citizen kane (1941)/njr/rating' '/about/film:citizen kane (1941)/star-rating'&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In that case, the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt; tag feels much better, and that seems like a
strong reason for with with either &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-b&lt;/span&gt;&lt;/tt&gt; or repeated &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt;
flags when shifting between different objects.&lt;/p&gt;
&lt;p&gt;So at the moment I&amp;#8217;m leaning strongly towards the first suggestions
introduced above, using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-b&lt;/span&gt;&lt;/tt&gt; as required.  As ever,
however, I&amp;#8217;m interested in opinions.  I expect it will be a while
before I get around to implementing this anyway.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-4915343659583838364?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/4915343659583838364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/07/movement-and-renaming-in-fluidinfo-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4915343659583838364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4915343659583838364'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/07/movement-and-renaming-in-fluidinfo-and.html' title='Movement and Renaming In Fluidinfo and Fish'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm7.static.flickr.com/6003/5976095592_44fd768e9b_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-1358106569932388549</id><published>2011-07-21T10:06:00.001+01:00</published><updated>2011-07-21T10:06:43.090+01:00</updated><title type='text'>Command Substitution and the Interactive Fish Shell</title><content type='html'>
&amp;nbsp;
&lt;div class="section" id="command-substitution-and-the-interactive-fish-shell"&gt;


The Fluidinfo Shell, &lt;a class="reference external" href="https://github.com/njr0/fish"&gt;Fish&lt;/a&gt;
(documented &lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;here&lt;/a&gt;)
has a gained a few important new features. &amp;nbsp; In summary, these are


&lt;blockquote&gt;


&lt;ol class="arabic"&gt;

&lt;li&gt;&lt;div class="first"&gt;
&lt;em&gt;Interactive Shell.&lt;/em&gt; &amp;nbsp; If invoked without any parameters,&lt;/div&gt;
Fish will start an interactive session that allows you to issue
a sequences of Fish commands (without prefixing them by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;).


&lt;div class="highlight-python"&gt;
&lt;pre&gt;$ fish
This is fish version 3.12.
&amp;gt; whoami
alice
&amp;gt; ls
books/ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;favourite-things &amp;nbsp; &amp;nbsp;private/ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;test-fish/
comment &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; has-read &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;rating &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;to-read
&amp;gt; show -a 'book:animal farm (george orwell)' alice/rating
Object with about="book:animal farm (george orwell)":
&amp;nbsp;&amp;nbsp;alice/rating = 2
&amp;gt; show -a "`about book 'animal farm' 'george orwell'`" alice/rating
Object with about="book:animal farm (george orwell)":
&amp;nbsp;&amp;nbsp;alice/rating = 2
&amp;gt; ^D
$&lt;/pre&gt;

&lt;/div&gt;


Points to note include:


&lt;blockquote&gt;


&lt;ul class="simple"&gt;

&lt;li&gt;If the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;readline&lt;/span&gt;&lt;/tt&gt; library is available to python, it will
be used, allowing Emacs key bindings to be used to edit the
command line (as well as arrow keys) and saving a command
history, which may be navigated with CTRL-P and CTRL-N or up
and down arrows. &amp;nbsp;You can also view the history by
typing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;history&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;h&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;

&lt;/ul&gt;


&lt;blockquote&gt;


&lt;ul&gt;

&lt;li&gt;&lt;div class="first"&gt;
The interactive session is exited by typing the end-of-file&lt;/div&gt;
character—CTRL-D on Unix and CTRL-Z on Windows.

&lt;/li&gt;


&lt;li&gt;&lt;div class="first"&gt;
Command substitution with left quoting (“backticks”) is supported&lt;/div&gt;
as illustraed in the last example of the interactive session
shown (explanation below).

&lt;/li&gt;


&lt;li&gt;&lt;div class="first"&gt;
Single and double quotes may be used interchangeably, and&lt;/div&gt;
are protected by each other. &amp;nbsp; Quotes and other special
characters may be escaped using backslash, which also escapes
itself. &amp;nbsp; So, for example, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Alice's&lt;/span&gt; &lt;span class="pre"&gt;Adventures&lt;/span&gt; &lt;span class="pre"&gt;in&lt;/span&gt; &lt;span class="pre"&gt;Wonderland&lt;/span&gt;&lt;/tt&gt;
may be passed as a parameter with


&lt;div class="highlight-python"&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="s"&gt;"Alice's Adventures in Wonderland"&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;/div&gt;


or


&lt;div class="highlight-python"&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="s"&gt;'Alice&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s"&gt;s Adventures in Wonderland'&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;/div&gt;

&lt;/li&gt;


&lt;li&gt;&lt;div class="first"&gt;
Obviously, on Unix, when using the interactive shell, the&lt;/div&gt;
Unix shell does not process the command line, meaning,
among other things, that there is no globbing (wildcard
expansion).

&lt;/li&gt;

&lt;/ul&gt;

&lt;/blockquote&gt;

&lt;/blockquote&gt;

&lt;/li&gt;


&lt;li&gt;&lt;div class="first"&gt;
&lt;em&gt;Command Substitution.&lt;/em&gt; &amp;nbsp; &amp;nbsp;Unix users will be familiar with&lt;/div&gt;
command substitution, which now comes to Fish. &amp;nbsp; The way this works in
Unix shells is that any part of a command enclosed in left
quotes (“backticks”) is evaluated before the enclosing command,
and its output replaces it in that enclosing command.
This is particularly relevant to the commands that build Fluidinfo
about tags—&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;abouttag&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;amazon&lt;/span&gt;&lt;/tt&gt; and the new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;normalize&lt;/span&gt;&lt;/tt&gt; command
(see below).


In Unix shells, it has always been possible to say:


&lt;div class="highlight-python"&gt;
&lt;pre&gt;$ fish show -a "`fish abouttag book 'animal farm' 'george orwell'`" alice/rating&lt;/pre&gt;

&lt;/div&gt;


The shell first evaluates the subcommand, which produces the
output &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book:animal&lt;/span&gt; &lt;span class="pre"&gt;farm&lt;/span&gt; &lt;span class="pre"&gt;(george&lt;/span&gt; &lt;span class="pre"&gt;orwell)&lt;/span&gt;&lt;/tt&gt; and then, after substitution,
the shell executes:


&lt;div class="highlight-python"&gt;
&lt;pre&gt;$ fish show -a "book:animal farm (george orwell)" alice/rating&lt;/pre&gt;

&lt;/div&gt;


In Unix, double quotes are weaker than single quotes, and command
substitution can still occur inside them, which is exactly what we
need in this case.


Fish now makes almost identical functionality available in its
new interactive mode. &amp;nbsp; &amp;nbsp;In the interactive shell you can say


&lt;div class="highlight-python"&gt;
&lt;pre&gt;&amp;gt; show -a "`about book 'animal farm' 'george orwell'`" alice/rating&lt;/pre&gt;

&lt;/div&gt;


This command is identical except that the leading &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; is no
longer needed within the substitution command (though it can be
used), just as it not needed in the outer show command.

&lt;/li&gt;


&lt;li&gt;&lt;div class="first"&gt;
&lt;em&gt;Command substitution in Shell-Fish.&lt;/em&gt; &amp;nbsp; The online version of&lt;/div&gt;
Fish, &lt;a class="reference external" href="http://shell-fish.appspot.com/"&gt;Shell-Fish&lt;/a&gt; also benefits
from the new command substution capabilities, but does not yet
include the history feature. &amp;nbsp; Whether readline-like command line
editing is available is a feature of the browser (today).

&lt;/li&gt;


&lt;li&gt;&lt;div class="first"&gt;
&lt;em&gt;The new&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;normalize&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;command.&lt;/em&gt; &amp;nbsp; A new normalize command has&lt;/div&gt;
been added to Fish. &amp;nbsp; This simply performs some standardization
on text, consisting primarily of mapping to lower case, removing
most punctuation and standardizing whitespace; accents are preserved.
If multiple arguments are passed, the components are joined with
colons. &amp;nbsp; For example:


&lt;div class="highlight-python"&gt;
&lt;pre&gt;$ fish normalize 'A *very* strange (and &amp;nbsp; &amp;nbsp;wonderful) fish'
a very strange and wonderful fish

$ fish normalize golfer 'Darren Clarke'
golfer:darren clarke&lt;/pre&gt;

&lt;/div&gt;

&lt;/li&gt;

&lt;/ol&gt;

&lt;/blockquote&gt;


Happy fishing!

&lt;/div&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-1358106569932388549?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/1358106569932388549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/07/command-substitution-and-interactive.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/1358106569932388549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/1358106569932388549'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/07/command-substitution-and-interactive.html' title='Command Substitution and the Interactive Fish Shell'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-6706240991306869847</id><published>2011-07-11T08:36:00.002+01:00</published><updated>2011-07-11T08:37:54.556+01:00</updated><title type='text'>Fish 3.07: More compact longer listings</title><content type='html'>&lt;div class="section" id="fish-3-07"&gt;
I made a minor update to Fish, available from
&lt;a class="reference external" href="https://github.com/njr0/fish"&gt;Github&lt;/a&gt;.
This fixed a rather nasty bug that had broken many aspects of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt;
command and which also modified the behaviour of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-L&lt;/span&gt;&lt;/tt&gt; command
(longer listing, including Fluidinfo-style permissions summary).
The behaviour that was previously generated by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-L&lt;/span&gt;&lt;/tt&gt; is still available
with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-G&lt;/span&gt;&lt;/tt&gt;, which is exemplified by
&lt;div class="highlight-python"&gt;
&lt;pre&gt;$ fish ls -G njr/rating

njr/rating:

ABSTRACT TAG (/tags)
  Write
    update (metadata):   policy: closed; exceptions = [njr, miro]
    delete (delete):     policy: closed; exceptions = [njr, miro]
  Control
    control (acontrol):  policy: closed; exceptions = [njr, miro]

TAG (/tag-values)
  Read
    read (read):         policy: open; exceptions = []
  Write
    create (tag):        policy: closed; exceptions = [njr, miro]
    delete (untag):      policy: closed; exceptions = [njr, miro]
  Control
    control (tcontrol):  policy: closed; exceptions = [njr, miro]&lt;/pre&gt;
&lt;/div&gt;
The new behaviour for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-L&lt;/span&gt;&lt;/tt&gt; will present a more compact summary
in the large majority of cases where the four write permissions for tags
are identical and the two control permissions are the same.   This simplified
view is:
&lt;div class="highlight-python"&gt;
&lt;pre&gt;$ fish ls -L njr/rating

njr/rating:
     read: policy: open; exceptions = []
    write: policy: closed; exceptions = [njr, miro]
  control: policy: closed; exceptions = [njr, miro]&lt;/pre&gt;
&lt;/div&gt;
The longer view is generated when the permissions cannot be shown accurately
in this more compact form.
Analogous behaviour occurs for namespaces when their three write permissions
are identical.   For example:
&lt;div class="highlight-python"&gt;
&lt;pre&gt;$ fish ls -Gn njr/fi

njr/fi/:

NAMESPACE (/namespaces)
  Read
    list (read):        policy: closed; exceptions = [njr, miro]
  Write
    create (create):    policy: closed; exceptions = [njr, miro]
    update (metadata):  policy: closed; exceptions = [njr, miro]
    delete (delete):    policy: closed; exceptions = [njr, miro]
  Control
    control (control):  policy: closed; exceptions = [njr]&lt;/pre&gt;
&lt;/div&gt;
reduces to:
&lt;div class="highlight-python"&gt;
&lt;pre&gt;$ fish ls -Ln njr/fi

njr/fi/:
     read: policy: closed; exceptions = [njr, miro]
    write: policy: closed; exceptions = [njr, miro]
  control: policy: closed; exceptions = [njr]&lt;/pre&gt;
&lt;/div&gt;
The very perceptive reader will also notice that the longest listing
now includes the write update (&lt;em&gt;metadata&lt;/em&gt;) permission that controls
access to writing the namespace description; this was missing in previous
releases as a result of a typographical error in the source.
(Computers can be &lt;em&gt;so&lt;/em&gt; picky.)&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-6706240991306869847?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/6706240991306869847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/07/fish-307-more-compact-longer-listings.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/6706240991306869847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/6706240991306869847'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/07/fish-307-more-compact-longer-listings.html' title='Fish 3.07: More compact longer listings'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-5942783043144517465</id><published>2011-07-07T08:27:00.001+01:00</published><updated>2011-07-11T08:34:29.149+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='about'/><category scheme='http://www.blogger.com/atom/ns#' term='abouttag'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='shell-fish'/><category scheme='http://www.blogger.com/atom/ns#' term='abstract tags'/><title type='text'>About Tags In Fish</title><content type='html'>&lt;div class="section" id="about-tags-in-fish"&gt;I’ve added a new command to &lt;a class="reference external" href="https://github.com/njr0/fish"&gt;fish&lt;/a&gt; (and updated the online version, &lt;a class="reference external" href="http://shell-fish.appspot.com/"&gt;Shell-Fish&lt;/a&gt; accordingly) to allow easy construction of standardized about tags using the conventions from the &lt;a class="reference external" href="https://github.com/njr0/abouttag"&gt;abouttag&lt;/a&gt; library.  They make use of a new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;abouttag&lt;/span&gt;&lt;/tt&gt; function, available in the new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;generic.py&lt;/span&gt;&lt;/tt&gt; file in the abouttag library, which takes the object type as its first parameter, and the usual parameters as a variable parameter list.&lt;br /&gt;
The new fish command is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;abouttag&lt;/span&gt;&lt;/tt&gt;, though can also be abbreviated to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;about&lt;/span&gt;&lt;/tt&gt; and its general form is:&lt;br /&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish abouttag &amp;lt;object type&amp;gt; &amp;lt;object specifiers&amp;gt;&lt;/pre&gt;&lt;/div&gt;The object type is something like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;album&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fi-user&lt;/span&gt;&lt;/tt&gt; and the object specifiers are the key parameters used to describe that object, in the same order as they are used in the corresponding function from the abouttag library.&lt;br /&gt;
The easiest way to illustrate and define these is with examples. The following examples are taken from a Unix system; on Windows, use double quotes rather than single around parameters.   In the online version (Shell-Fish), and on Unix, single or double quotes work. In the online version, you don’t need the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; prefix (though it does work).&lt;br /&gt;
I should note that part of the motivation for adding this functionality is a desire to allow the command to be used to specify objects without knowing the exact form of their about tags.  In Unix-like systems (Linux, Mac OS X, Solaris etc.), this is possible by using left quotes, which can be placed inside double quotes.  Thus, the following, slightly ungainly command (using all three forms of quote) works, at least in bash:&lt;br /&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish show -F -a "`fish abouttag book 'Gödel, Escher, Bach: An Eternal Golden Braid' 'Douglas R. Hofstader'`" njr/rating
Object with about="book:gödel escher bach an eternal golden braid (douglas r hofstader)":
  njr/rating = 10&lt;/pre&gt;&lt;/div&gt;I will leave it to the reader to judge whether this is easier than using cut and paste.  For those who don’t know about left quotes in Unix shells, a command enclosed in left quotes within another command is evaluted before its enclosing command; its output replaces the left-quoted phrase on the original command line.  So in the case above, we first run the command&lt;br /&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish abouttag book 'Gödel, Escher, Bach: An Eternal Golden Braid' 'Douglas R. Hofstader'&lt;/pre&gt;&lt;/div&gt;which generates&lt;br /&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;book:gödel escher bach an eternal golden braid (douglas r hofstader)&lt;/pre&gt;&lt;/div&gt;as its output.   In effect, the outer command is then transformed to&lt;br /&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish show -F -a "book:gödel escher bach an eternal golden braid (douglas r hofstader)" njr/rating&lt;/pre&gt;&lt;/div&gt;I hope to extend shell-fish, the on-line version of fish, to support left quotes, but that may take a little while.&lt;br /&gt;
The following examples are taken from the fish documentation, which is available online from &lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;http://fluiddb.fluidinfo.com/about/fish/fish/index.html&lt;/a&gt;.&lt;br /&gt;
&lt;blockquote&gt;&lt;ol class="arabic"&gt;&lt;li&gt;&lt;div class="first"&gt;Books and related items using the book-u convention (book, author)&lt;/div&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish abouttag book 'Gödel, Escher, Bach: An Eternal Golden Braid' 'Douglas R. Hofstader'
book:gödel escher bach an eternal golden braid (douglas r hofstader)

$ fish abouttag book 'The Feynman Lectures on Physics' 'Richard P. Feynman' 'Robert B. Leighton' 'Matthew Sands'
book:the feynman lectures on physics (richard p feynman; robert b leighton; matthew sands)

$ fish abouttag book 'The Oxford English Dictionary: second edition, volume 3', 'John Simpson', 'Edmund Weiner'
book:the oxford english dictionary second edition volume 3 (john simpson; edmund weiner)

$ fish abouttag author 'Douglas R. Hofstadter' 1945 2  15
author:douglas r hofstadter (1945-02-15)&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class="first"&gt;Music-related items (track, album, artist, isrc-recording)&lt;/div&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish abouttag track 'Bamboulé' 'Bensusan and Malherbe'
track:bamboulé (bensusan and malherbe)

$ fish abouttag album 'Solilaï' 'Pierre Bensusan'
album:solilaï (pierre bensusan)

$ fish abouttag artist 'Crosby, Stills, Nash &amp;amp; Young'
artist:crosby stills nash &amp;amp; young

$ fish abouttag isrc-recording 'US-PR3-73-00012'
isrc:USPR37300012&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class="first"&gt;URLs and URIs (URI, URL)&lt;/div&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish abouttag uri FluidDB.fluidinfo.com
http://fluiddb.fluidinfo.com

$ fish abouttag url https://FluidDB.fluidinfo.com/one/two/
https://fluiddb.fluidinfo.com/one/two

$ fish abouttag URI http://fluiddb.fluidinfo.com/one/two/
http://fluiddb.fluidinfo.com/one/two

$ fish abouttag URL 'http://test.com/one/two/?referrer=http://a.b/c'
http://test.com/one/two/?referrer=http://a.b/c&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class="first"&gt;Fluidinfo objects (fi-user, fi-namespace, fi-tag)&lt;/div&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish abouttag fi-user njr
Object for the user named njr

$ fish abouttag fi-namespace njr/misc
Object for the namespace njr/misc

$ fish abouttag fi-ns njr/private
Object for the namespace njr/private

$ fish abouttag fi-tag terrycojones/private/rating
Object for the attribute terrycojones/private/rating&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class="first"&gt;Database components (db-table, db-field)&lt;/div&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish abouttag db-table 'elements'
table:elements

$ fish abouttag db-field 'name' 'elements'
field:name in table:elements&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div class="first"&gt;Miscellaneous (planet, element)&lt;/div&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish abouttag planet 'Mars'
planet:Mars

$ fish abouttag element 'Helium'
element:Helium&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-5942783043144517465?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/5942783043144517465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/07/about-tags-in-fish.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/5942783043144517465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/5942783043144517465'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/07/about-tags-in-fish.html' title='About Tags In Fish'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-266018866044204792</id><published>2011-06-25T14:04:00.000+01:00</published><updated>2011-06-25T14:04:30.137+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='shell-fish'/><category scheme='http://www.blogger.com/atom/ns#' term='terminal'/><title type='text'>Like A Scrolling Terminal</title><content type='html'>&lt;div class="section" id="like-a-scrolling-terminal"&gt;
&lt;p&gt;I have just updated &lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;Shell-Fish&lt;/a&gt;,
the on-line version of the Fluidinfo Shell,
&lt;a class="reference external" href="https://github.com/njr0/fish"&gt;fish&lt;/a&gt;,
so that it acts rather more like a scrolling terminal,
and rather less like a search engine.&lt;/p&gt;
&lt;p&gt;Instead of being a &amp;#8220;one-shot&amp;#8221; application, where each
time you type a fish command the screen is wiped and you lose all
previous context, fish now simply scrolls the output, just a like a
terminal.  If you&amp;#8217;re a command-line kind-of-a person, it will all
look deeply familiar, except for the merest hint of AJAX spinniness.&lt;/p&gt;
&lt;p&gt;The original inspiration for this was Stefan Grothcop&amp;#8217;s
wonderful Google Shell, &lt;a class="reference external" href="http://goosh.org/"&gt;goosh&lt;/a&gt;,
which I&amp;#8217;ve long used as my main interface to Google on Firefox.
If you haven&amp;#8217;t tried &lt;a class="reference external" href="http://goosh.org/"&gt;goosh&lt;/a&gt;,
what are you waiting for?&lt;/p&gt;
&lt;p&gt;Although the new scrolling version of
&lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;Shell-Fish&lt;/a&gt; appears to work fine,
I expect there are bugs: let me know if you find any.
It still lacks a few basics, most obviously a history,
but I plan to add that.
Globbing too.&lt;/p&gt;
&lt;p&gt;All in good time.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-266018866044204792?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/266018866044204792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/06/like-scrolling-terminal.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/266018866044204792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/266018866044204792'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/06/like-scrolling-terminal.html' title='Like A Scrolling Terminal'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-34030365380771242</id><published>2011-06-19T16:39:00.002+01:00</published><updated>2011-06-19T16:39:45.688+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='permissions'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='shell-fish'/><category scheme='http://www.blogger.com/atom/ns#' term='fdb'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Securing shell-fish with fish: Even More on Fluidinfo Permissions</title><content type='html'>&lt;div class="section" id="securing-shell-fish-with-fish-even-more-on-fluidinfo-permissions"&gt;
&lt;p&gt;I mentioned in &lt;a class="reference external" href="http://blog.abouttag.com/2011/06/fishier-still-rm-extra-perms-and-more.html"&gt;my last post&lt;/a&gt;
that I&amp;#8217;ve extended the range of permissions that can
be set with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt; command to cover the whole gamut.
Here, I&amp;#8217;ll describe this in the context of showing how I
have set up permissions for the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user to make them suitable
for use with the online version of
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;&amp;#8212;&lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;shell-fish&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My goal was this.  Shell-fish, the online version of fish, allows
users to log in with their Google account and effectively link it to
one or more Fluidinfo accounts.  Users who do this can use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; to
perform arbitrary Fluidinfo operations using their own tags.  But I
also wanted to allow users to try out Fluidinfo and fish without
setting up an account.  Initially, I did this using the Fluidinfo
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;test&lt;/span&gt;&lt;/tt&gt; user, but that&amp;#8217;s probably not a good long-term solution.  What
I&amp;#8217;d prefer to do is to provide a locked down account that anyone can
use for certain things&amp;#8212;not only for reading but also to try out tagging.
The process of locking down a Fluidinfo account is also useful as an
illustration of the extended &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt; command in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;,
so that is the subject of this post.&lt;/p&gt;
&lt;p&gt;I created the Fluidinfo &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user and switched to it in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish su fish
Credentials set to user fish.

$ fish ls -ld fish
nrwcr--r--   fish/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;As you can see the permissions on fish&amp;#8217;s namespace are the defaults,
with the user having read, write and control permission, and everyone
else having read only.   (See &lt;a class="reference external" href="http://blog.abouttag.com/2011/06/setting-and-changing-permissions-with.html"&gt;this post&lt;/a&gt; or the
&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/ls.html"&gt;fish documentation for the ls command&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The first thing I wanted to do was to transfer control permission
from the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user to me (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt;) so that a user of Shell-Fish
can&amp;#8217;t do arbitrary things.   This wasn&amp;#8217;t possible with the original
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt; command, but I&amp;#8217;ve added three new forms of the command,
each of which follows the general template:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish perms perms-class [open|closed] [except list+of+users] list of tags or namespaces&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;where &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms-class&lt;/span&gt;&lt;/tt&gt; is one of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;read&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;write&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;control&lt;/span&gt;&lt;/tt&gt;.
This simply lets the user set the explicit FLuidinfo permissions,
as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;open&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;closed&lt;/span&gt;&lt;/tt&gt;, with an optional exception list.
The exception list is specfied as a list of users, separated by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;+&lt;/span&gt;&lt;/tt&gt;
signs.   The command only changes the permissions class specified
and changes all the permissions in that class for the tags or namespaces
given.   So valid examples operating on a tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish/rating&lt;/span&gt;&lt;/tt&gt; and
a namespace &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish/private&lt;/span&gt;&lt;/tt&gt; include:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish perms read closed except fish fish/rating fish/private
fish perms write closed fish/rating fish/private
fish perms control closed except fish+njr fish/rating fish/private&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To transfer the control permissions to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt; for the top-level fish namespace,
I used the command (still as the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user at this point):&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish perms -f control closed except njr fish&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The only extra thing to notice here is the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; flag, which forces
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; to make a change it would otherwise resist.   Any change to
permissions that results in the owner of a tag or namespace not having
control permissions falls into this category, and since this is usually
undesirable, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; requires the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; flag to force this to happen.
(Tranferring permission to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt; is, of course, irreversable for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;.)&lt;/p&gt;
&lt;p&gt;Having made this change, if we repeat the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt; command we see this:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fish ls -ld fish
(denied)    fish/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Fluidinfo allows only users with control permission to see the
permissions on tags and namespaces, so the fish user can no longer see
them.   (I suppose this is slightly odd: it means that you can&amp;#8217;t even
see that you have write permission if you don&amp;#8217;t have control permission.
But that&amp;#8217;s not a huge problem.)&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s switch to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt; and try.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish su njr
Credentials set to user njr.

$ fish ls -ld fish
nrw-r-cr--   fish/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is as expected.    The owner&amp;#8212;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;&amp;#8212;no longer has control
permission on the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; namespace, but someone in a group does.
We know that someone is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt;.    (We could verify this with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-L&lt;/span&gt;&lt;/tt&gt;,
as we will after making some more changes.)&lt;/p&gt;
&lt;p&gt;So far so good.&lt;/p&gt;
&lt;p&gt;In terms of writing, my initial idea is to provide a set tags with
single-letter names (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;a&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;z&lt;/span&gt;&lt;/tt&gt;) in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;&amp;#8216;s top-level namespace
that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; can write, but not to allow other tags or namespace
to be written.&lt;/p&gt;
&lt;p&gt;First, let&amp;#8217;s create those tags as the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish su fish
Credentials set to user fish.

$ fish -U touch a b c d e f g h i j k l m n o p q r s t u v w x y z&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;touch&lt;/span&gt;&lt;/tt&gt; command on a non-existent tag creates the tag, and the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-U&lt;/span&gt;&lt;/tt&gt;
says use Unix-style paths, i.e. assume they&amp;#8217;re in the authenticated
user&amp;#8217;s namespace unless introduced with a leading &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/&lt;/span&gt;&lt;/tt&gt;.
So this creates the 26 single-letter tags I want.&lt;/p&gt;
&lt;p&gt;Next, we need to remove write permission from fish on the fish namespace,
so that it can&amp;#8217;t create new tags or namespaces.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish su njr
Credentials set to user njr.

$ fish perms write closed except njr fish

$ fish ls -ld fish
nr--rwcr--   fish/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now let&amp;#8217;s think about the permissions on the tags we have just created.
There is currently nothing hierarchical about Fluidinfo&amp;#8217;s permissions.
So switching back to the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user, we see:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish su fish
Credentials set to user fish.

$ fish ls -l
trwcr--r--   fish/a
trwcr--r--   fish/b
...
trwcr--r--   fish/z&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So even though &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt; has control of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; namespace, the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;
user has control of the tags it created.
I don&amp;#8217;t want that, so let&amp;#8217;s transfer them over:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish -U perms -f control closed except njr a b c d e f g h i j k l m n o p q r s t u v w x y z

$ fish ls -l a
trw-r-cr--   fish/a&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;[Again, the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-U&lt;/span&gt;&lt;/tt&gt; saves me having to prefixed each tag with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/&lt;/span&gt;&lt;/tt&gt;.
Of course, adding globbing (wild-carding) to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; would be even
more helpful; I&amp;#8217;ll probably do that soon, though interaction with the
Unix shell&amp;#8217;s globbing will be a slight issue there.]&lt;/p&gt;
&lt;p&gt;So this is pretty good: the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user has read and write permissions,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr&lt;/span&gt;&lt;/tt&gt; has read and control, and everyone else has read only.&lt;/p&gt;
&lt;p&gt;The one remaining problem is that there are several different write
permissions on tags&amp;#8212;permission to tag things with the tag (in native
Fluidinfo API terms, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;create&lt;/span&gt;&lt;/tt&gt; permission on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/tag-values&lt;/span&gt;&lt;/tt&gt;),
permission to untag objects currently tagged with the tag (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;delete&lt;/span&gt;&lt;/tt&gt;
permission on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/tag-values&lt;/span&gt;&lt;/tt&gt;) permission to change the description of
the tag (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;update&lt;/span&gt;&lt;/tt&gt; permission on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/tags&lt;/span&gt;&lt;/tt&gt;) and permission to
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;delete&lt;/span&gt;&lt;/tt&gt; the tag itself (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;delete&lt;/span&gt;&lt;/tt&gt; permission on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/tags&lt;/span&gt;&lt;/tt&gt;).  The
last of these is the problem: I don&amp;#8217;t really want a random user of the
Shell-fish tags to be able to delete any of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish/a&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish/z&lt;/span&gt;&lt;/tt&gt;.
To start with, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; couldn&amp;#8217;t recreate them (because I&amp;#8217;ve removed
write permission from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; on the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; namespace) and if it
did, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; would get control permission over that tag, which is
what I&amp;#8217;ve been trying to avoid.  So I need to remove the fine-grained
Fluidinfo permission to annihilate the tags from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;In order to allow this, I added a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-X&lt;/span&gt;&lt;/tt&gt; option to the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt;
command.  This &amp;#8220;eXtra&amp;#8221; specification restricts which particular
permissions within the class specified should actually be modified.
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-X&lt;/span&gt;&lt;/tt&gt; is followed by the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; name for a low-level Fluidinfo
permission, as shown in the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-L&lt;/span&gt;&lt;/tt&gt; &amp;#8220;longer&amp;#8221; listing.  Let&amp;#8217;s look at
the detailed permissions on one of our tags:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish su njr
Credentials set to user njr.

$ fish ls -L /fish/a

fish/a:

ABSTRACT TAG (/tags)
  Write
    update (metadata):  policy: closed; exceptions = [fish]
    delete (delete):    policy: closed; exceptions = [fish]
  Control
    control (acontrol): policy: closed; exceptions = [njr]

TAG (/tag-values)
  Read
    read (read):        policy: open; exceptions = []
  Write
    create (tag):       policy: closed; exceptions = [fish]
    delete (untag):     policy: closed; exceptions = [fish]
  Control
    control (tcontrol): policy: closed; exceptions = [njr]&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here, the Fluidinfo name for the low-level permission is shown
first, and then parentheses, the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; name is shown.
The fish names are unique for each kind of permission that exists
on tags, and the one we are concerned with is the ability to
delete the tag itself&amp;#8212;the &lt;em&gt;abstract&lt;/em&gt; tag.    This has the same name,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;delete&lt;/span&gt;&lt;/tt&gt;, in both systems.   So I used the command:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish perms -f write -X delete closed except njr /fish/a

$ fish ls -L fish/a

fish/a:

ABSTRACT TAG (/tags)
  Write
    update (metadata):  policy: closed; exceptions = [fish]
    delete (delete):    policy: closed; exceptions = [njr]
  Control
    control (acontrol): policy: closed; exceptions = [njr]

TAG (/tag-values)
  Read
    read (read):        policy: open; exceptions = []
  Write
    create (tag):       policy: closed; exceptions = [fish]
    delete (untag):     policy: closed; exceptions = [fish]
  Control
    control (tcontrol): policy: closed; exceptions = [njr]&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;As you can see, this changed &lt;em&gt;only&lt;/em&gt; the delete permission from
the specified write class, which is what we wanted.   (If I had
wanted to change several, I could have repeated the -X option.)
I repeated this using the other 25 tags.   If we now look at
the result using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-g&lt;/span&gt;&lt;/tt&gt;, we get this:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fish ls -g /fish
tr/-r/cr--   fish/a
tr/-r/cr--   fish/b
...
tr/-r/cr--   fish/z&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Reading across:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;t&lt;/span&gt;&lt;/tt&gt; means that this is tag&lt;/li&gt;
&lt;li&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;r/-&lt;/span&gt;&lt;/tt&gt; means that the tag&amp;#8217;s owner, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;, has read and &lt;em&gt;some&lt;/em&gt;
write permissions on the tag&amp;#8212;in this case, all except the
delete permission on the abstract tag&lt;/li&gt;
&lt;li&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;r/c&lt;/span&gt;&lt;/tt&gt; means that there is some group of users with control
and read permissions, but only some write permissions.  That group
is in fact the singleton &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[njr]&lt;/span&gt;&lt;/tt&gt;, and he has delete permission
only.  (I could have actually just made the delete policy
closed&amp;#8212;no one needs to be able to delete the tag, and I have
control anyway.  Equally, I could have given myself all the other
write permissions; but I didn&amp;#8217;t.)&lt;/li&gt;
&lt;li&gt;The final &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;r--&lt;/span&gt;&lt;/tt&gt; means that the world has read permission, but not
write or control.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;So that&amp;#8217;s it.  The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user can now tag and untag things using
the tags &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish/a&lt;/span&gt;&lt;/tt&gt; through &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish/z&lt;/span&gt;&lt;/tt&gt; but has no ability to create
other tags or namespaces, or delete the tag itself, and does not have
control permission.  The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user can also in principle change
tag descriptions, though &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; doesn&amp;#8217;t provide a way of doing that
for existing tags right now.&lt;/p&gt;
&lt;p&gt;I have just switched over &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt; to use the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user for
non-authenticated users, so you can try this out now.  In passing, if
you use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt; to list the fish namespace, you&amp;#8217;ll see this:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;_static/        genindex.html   mkdir.html      s               unixlike.html
a               h               mkns.html       search.html     untag.html
b               help.html       n               searchindex.js  v
c               i               o               show.html       version.html
cli.html        index.html      p               su.html         w
commands.html   install.html    perms.html      t               whoami.html
count.html      j               pwd.html        tag.html        x
d               k               pwn.html        tags.html       y
e               l               q               test.html       z
f               ls.html         r               touch.html
g               m               rm.html         u&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you&amp;#8217;re wondering what all these tags-that-look-like-web-pages are,
they&amp;#8217;re tags that I use to store the HTML fish documentation in Fluidinfo
itself.    If you look carefully at the documentation
path &amp;#8212; &lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;http://fluiddb.fluidinfo.com/about/fish/fish/index.html&lt;/a&gt; &amp;#8212; you
will see that its root is a tag on the Fluidinfo object having the
about tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;.   The name of that tag is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish/index.html&lt;/span&gt;&lt;/tt&gt;,
and its content is the HTML for the index page.   The trick lies partly
in the tag name and partly in setting its content type to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;text/html&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;I have a script that does that, which will probably become a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;
command called Something like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;upload&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;publish&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;files2fi&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-34030365380771242?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/34030365380771242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/06/securing-shell-fish-with-fish-even-more.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/34030365380771242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/34030365380771242'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/06/securing-shell-fish-with-fish-even-more.html' title='Securing shell-fish with fish: Even More on Fluidinfo Permissions'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-4352215237839970708</id><published>2011-06-18T20:43:00.002+01:00</published><updated>2011-06-18T20:43:35.893+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rm'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='line'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='command'/><category scheme='http://www.blogger.com/atom/ns#' term='fdb'/><title type='text'>Fishier Still: rm, extra perms and more with fish 3.01</title><content type='html'>&lt;div class="section" id="fishier-still-rm-extra-perms-and-more-with-fish-3-01"&gt;
&lt;p&gt;I&amp;#8217;ve written a bit about the changes I&amp;#8217;ve made to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; as it became
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;.   I wanted to test it a bit more myself before pushing it
to GitHub, but have now done so as well as making some more changes.&lt;/p&gt;
&lt;p&gt;Key things to know:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; 3.0 is simply a renamed version of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt;, reflecting
the change in FluidDB&amp;#8217;s name to Fluidinfo.
It&amp;#8217;s available from &lt;a class="reference external" href="https://github.com/njr0/fish"&gt;https://github.com/njr0/fish&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I haven&amp;#8217;t changed the names of things like the credentials file
(though its default position has moved to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;c:\fish\credentials.txt&lt;/span&gt;&lt;/tt&gt;
on Windows, as I said it would).   I also haven&amp;#8217;t changed the name
of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;FluidDB&lt;/span&gt;&lt;/tt&gt; class internally, though many other internal
names have changed to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;There are a few commands available in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt; &lt;span class="pre"&gt;3.01&lt;/span&gt;&lt;/tt&gt;.
The most significant changes are the addition of an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; command
for removing tags and namespaces, and extensions to the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt;
command to allow more detailed control if required.
(In fact, I believe all possible permissions can now be set with it.)&lt;/li&gt;
&lt;li&gt;There are some new minor commands as well&amp;#8212;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;touch&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mkns/mkdir&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;I&amp;#8217;ve changed the error handling a bit, which should improve things,
at least for some kinds of errors.&lt;/li&gt;
&lt;li&gt;In a minor change, I&amp;#8217;ve decided to allow &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-r&lt;/span&gt;&lt;/tt&gt; to be
used interchangably to specify recursive descent.   At the moment,
that means that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-r&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt; &lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt; will work as well as the
more conventional &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt; &lt;span class="pre"&gt;-r&lt;/span&gt;&lt;/tt&gt;.   In future, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt;
and a planned &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cp&lt;/span&gt;&lt;/tt&gt; will probably support these options too.
Even though, Unix users tend to know which is which, there seems
no reason to insis that the &amp;#8220;right&amp;#8221; one be used in fdb.&lt;/li&gt;
&lt;li&gt;The documentation is in a new (but even more natural) place in
Fluidinfo &amp;#8212; &lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;http://fluiddb.fluidinfo.com/about/fish/fish/index.html&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I haven&amp;#8217;t removed &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; from GitHub.   It&amp;#8217;s more stable and
the rename is a pain, o I&amp;#8217;ll probably leave it there for 6&amp;#8211;12
months before pointing it to fish, which is a new project.
Fish is at &lt;a class="reference external" href="http://github.com/njr0/fish"&gt;http://github.com/njr0/fish&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The new features are all documented in the
&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fish/fish/index.html"&gt;online documentation&lt;/a&gt;,
but I&amp;#8217;ll
outline most fo the changes here as well, except for the extended
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt; options functionality, which I&amp;#8217;ll cover in a separate post
about how I used them to &amp;#8220;secure* the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; user for use with
the online version of fish&amp;#8212;&lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;shell-fish&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="rm"&gt;
&lt;h2&gt;rm&lt;a class="headerlink" href="#rm" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most significant new command is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt;.  If you&amp;#8217;re familiar with
Unix, you&amp;#8217;ll feel right at home, though there&amp;#8217;s no globbing
(wildcarding) yet.  The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; command can be used to remove one or
more empty namespaces or unused tags simply by giving the paths or
paths.  For example, given a tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/rating&lt;/span&gt;&lt;/tt&gt; and a namespace
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;, the following work:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ rm njr/rating
$ rm njr/private
$ rm njr/rating njr/private&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you want to remove a non-empty namespace, use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-r&lt;/span&gt;&lt;/tt&gt; to do a recursive
removal.   This will delete all the tags (removing them from objects
in the process) and sub-namespaces before removing the nominated
namespaces itself:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ rm -r njr/private&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If I followed the Unix analogy slavishly, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; would let you remove
a tag even if it were in use (after all, files don&amp;#8217;t have to be empty
to delete them); however, the potential scale of inadvertant
destruction of information is, in our case, large enough that I feel
some proection is in order.   So to remove a tag that&amp;#8217;s in use, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;
requires use of either the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-r&lt;/span&gt;&lt;/tt&gt; (recurse) or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; (force) flag.&lt;/p&gt;
&lt;p&gt;As on Unix, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-f&lt;/span&gt;&lt;/tt&gt; is intended to encourage &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; just to get on
and remove things if humanly (fishily?) possible, and not to complain
if the things you&amp;#8217;re asking it to remove don&amp;#8217;t exist.   In time,
this will extend to changing permissions, where possible, but right
now if you don&amp;#8217;t have the relevant permissions removal will fail.&lt;/p&gt;
&lt;p&gt;There is no &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rmns&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rmdir&lt;/span&gt;&lt;/tt&gt; command, but &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; will suggest
you use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; if you find yourself typing them inadvertantly.
(I never understood why you can&amp;#8217;t remove an empty direcory with
a plain &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rm&lt;/span&gt;&lt;/tt&gt; on Unix anyway.)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="touch-mkns-and-mkdir"&gt;
&lt;h2&gt;touch, mkns and mkdir&lt;a class="headerlink" href="#touch-mkns-and-mkdir" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Although the Fluidinfo API requires tags to be created before they are
used, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; (like its predecessor &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt;) has always created tags
on first use, including required namespaces, but there are still a
couple of situations in which you might want to create them
explicitly.  One is if you want to pre-permissions;
the other is that you might wish to specify the description that
both tags and namespaces can have.  The relevant commands are:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ touch user/tag
$ mkns user/ns
$ touch -m "tag description" user/ns/tag
$ mkns -m "namespace description" user/ns1/ns2&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The first creates a tag called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tag&lt;/span&gt;&lt;/tt&gt; in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;user&lt;/span&gt;&lt;/tt&gt;&amp;#8216;s namespace,
the second creates a namespace &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ns&lt;/span&gt;&lt;/tt&gt; in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;user&lt;/span&gt;&lt;/tt&gt;&amp;#8216;s namespace,
the third creates a tag called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ns/tag&lt;/span&gt;&lt;/tt&gt; in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;user&lt;/span&gt;&lt;/tt&gt;&amp;#8216;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;user/ns&lt;/span&gt;&lt;/tt&gt;
namespace, creating &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;user/ns&lt;/span&gt;&lt;/tt&gt; if required, and setting the description
(&lt;em&gt;metadata&lt;/em&gt;) to &amp;#8220;tag description&amp;#8221;,
and the last does something similar for a namespace &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;user/ns1/ns2&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-4352215237839970708?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/4352215237839970708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/06/fishier-still-rm-extra-perms-and-more.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4352215237839970708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4352215237839970708'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/06/fishier-still-rm-extra-perms-and-more.html' title='Fishier Still: rm, extra perms and more with fish 3.01'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-3797509506462655340</id><published>2011-06-16T21:55:00.001+01:00</published><updated>2011-06-18T19:33:15.598+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='fdb'/><title type='text'>C:&gt; Using fdb On Windows</title><content type='html'>&lt;div class="section" id="using-fdb-on-windows"&gt;
&lt;p&gt;It has become clear that &lt;a class="reference external" href="https://github.com/njr0/fdb"&gt;fdb&lt;/a&gt; hasn&amp;#8217;t
been tested much on Windows. &lt;a class="footnote-reference" href="#fn1" id="id1"&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, Over the last few days, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; has been used a bit more on
Windows, and as a result I&amp;#8217;ve made some changes to make the experience
on Windows a littler better.&lt;/p&gt;
&lt;p&gt;Here are a couple of things that might be worth knowing if you&amp;#8217;re using it on
Windows. &lt;a class="footnote-reference" href="#fn2" id="id2"&gt;[2]&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Credentials.&lt;/em&gt; In the past, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; would look for a credentials
file (containing username, password and optionally a tag-path
preference) in the user&amp;#8217;s home directory, but to do that reliably
required a non-standard python library.  That seems like an
unnecessary dependency.  So I&amp;#8217;ve changed this.  Now, on Windows,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; consult the environment variable &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;FDB_CREDENTIALS_FILE&lt;/span&gt;&lt;/tt&gt;
to find the location of said file; if it&amp;#8217;s not set, the
credentials file is assumed to be &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;c:\fdb\credentials.txt&lt;/span&gt;&lt;/tt&gt;
(soon to become, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;c:\fish\credentials.txt&lt;/span&gt;&lt;/tt&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Quoting Queries&lt;/em&gt;.
Fluidinfo expects string values in queries to be quoted using
double quotes.   On Unix, the usual way to handle that is to
use single quotes around the query and put double quotes
within.   For example:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb show -q 'fluiddb/about matches "café"' fluiddb/about&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;On Windows, that doesn&amp;#8217;t work.   Instead, you need to use double
quotes in both places.   Because that means having double quotes
within double quotes, the inner double quotes have to be escaped,
and on Windows, the way this is achieved is with &amp;#8220;stuttering&amp;#8221;,
i.e. repeating the quoted quote.   So the Windows equivalent
of the command above is:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;C:&amp;gt; fdb show -q "fluiddb/about matches ""café""" fluiddb/about&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;I guess I should also say that the above is based on Windows XP.
I haven&amp;#8217;t tried it on Vista or Windows 7.    If you try it and
run into different behaviour, or other problems, let me know.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="fn1" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Windows hates me and has always made it abundantly clear that it
considers me to be an idiot, so I try to avoid it much myself.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="fn2" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;When I say &amp;#8220;Windows&amp;#8221;, what I really mean in using the
Windows shell.  I&amp;#8217;m not entirely what the right name for
that is.  I mean thing that you get if you select &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Run...&lt;/span&gt;&lt;/tt&gt;
from the Start menu and then type &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;cmd&lt;/span&gt;&lt;/tt&gt;.  The thing the used
to be called the (MS)-DOS shell.  The Windows command line.
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C:&amp;gt;&lt;/span&gt;&lt;/tt&gt;!  If you&amp;#8217;re using Cygwin, it&amp;#8217;s more-or-less the same
as on Unix-like systems.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-3797509506462655340?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/3797509506462655340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/06/c-using-fdb-on-windows.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3797509506462655340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3797509506462655340'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/06/c-using-fdb-on-windows.html' title='C:&gt; Using fdb On Windows'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-4846397418177566708</id><published>2011-06-15T09:21:00.000+01:00</published><updated>2011-06-15T09:21:25.371+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fluiddb'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='fish.py'/><category scheme='http://www.blogger.com/atom/ns#' term='fish'/><category scheme='http://www.blogger.com/atom/ns#' term='amazon'/><category scheme='http://www.blogger.com/atom/ns#' term='shell-fish'/><category scheme='http://www.blogger.com/atom/ns#' term='fdb'/><title type='text'>Of Fish, Shell-Fish and Fish Py</title><content type='html'>&lt;div class="section" id="of-fish-shell-fish-and-fish-py"&gt;
&lt;p&gt;FluidDB is dead; long live Fluidinfo.&lt;/p&gt;
&lt;p&gt;Whither &lt;a class="reference external" href="https://github.com/njr0/fdb"&gt;fdb&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;Obviously, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; should become fi; it&amp;#8217;s perfect.
Thirty-three-and-a-third per cent shorter is 33⅓% better for a
command-line command.  And &lt;em&gt;fi&lt;/em&gt; is just so beautiful.  It could almost
become a ligature: how perfect would ﬁ be?&lt;/p&gt;
&lt;p&gt;Except, of course, there&amp;#8217;s one tiny problem.   In Unix shells,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fi&lt;/span&gt;&lt;/tt&gt; is reserved as the closing counterpart to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;if&lt;/span&gt;&lt;/tt&gt;.
Even if I &lt;em&gt;could&lt;/em&gt; make &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fi&lt;/span&gt;&lt;/tt&gt; kinda, sorta work,
I wouldn&amp;#8217;t want to.   The closing counterpart to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;if&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;should
be&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fi&lt;/span&gt;&lt;/tt&gt;; it&amp;#8217;s part of the cosmic order.&lt;/p&gt;
&lt;p&gt;So what to do?   The procrastinator&amp;#8217;s dictum to the rescue:&lt;/p&gt;
&lt;blockquote&gt;
&lt;em&gt;Why put off till tomorrow that which doesn&amp;#8217;t really need to be
done until the day after that?&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;Why does &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; need to change at all?   It could be a throwback,
a reminder of glories past, a piece of Fluidinfo&amp;#8217;s cultural legacy
(along with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fluiddb&lt;/span&gt;&lt;/tt&gt; superuser).&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s what I thought.&lt;/p&gt;
&lt;p&gt;Until I decided to put &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; into the sky.  I&amp;#8217;ve long thought it
would be cool to have a browser-based version of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; that anyone
could simply use without installation.  &amp;#8220;No software&amp;#8221;, as Salesforce.com
likes to say.&lt;/p&gt;
&lt;p&gt;For better or for worse, I tend to use Google&amp;#8217;s App Engine to write
web apps at the moment, so I went to register a new app there.&lt;/p&gt;
&lt;div class="section" id="in-search-of-a-google-app-engine-app-name"&gt;
&lt;h2&gt;In Search of a Google App Engine App Name&lt;a class="headerlink" href="#in-search-of-a-google-app-engine-app-name" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Unfortunately, registering a new app is a bit like picking a domain;
most of the desirable onare are gone already, not helped by the fact
that all google usernames are considered taken.  Add to that a
minimum-of-six-characters requirement, and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; looks to be in
trouble.&lt;/p&gt;
&lt;p&gt;As I was doing all this, I was chatting online with Terry
(&lt;a class="reference external" href="http://twitter.com/terrycojones"&gt;&amp;#64;terrycojones&lt;/a&gt;),
who is the leading advocate of taking the DB out of FluidDB,
and who, while entirely willing for me to plough my own furrow,
had a very clear preference for expunging the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;db&lt;/span&gt;&lt;/tt&gt; from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; too.&lt;/p&gt;
&lt;p&gt;Clearly, in reality, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; is a &lt;em&gt;shell&lt;/em&gt; for Fluidinfo.
Unix has a long history of shells.   In roughly chronological
order I have used &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sh&lt;/span&gt;&lt;/tt&gt; (the original &amp;#8220;Bourne&amp;#8221; shell),
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;csh&lt;/span&gt;&lt;/tt&gt; (the C shell), &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;tcsh&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ssh&lt;/span&gt;&lt;/tt&gt; (Simon&amp;#8217;s shell; not the Secure Shell;
though I use that daily too), and now, always, nearly exclusively,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;bash&lt;/span&gt;&lt;/tt&gt;, the truly wonderful &lt;em&gt;Bourne-Again Shell&lt;/em&gt;.
I&amp;#8217;ve also dabbled with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ksh&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;zsh&lt;/span&gt;&lt;/tt&gt; and no doubt various others
that fall into the large &lt;em&gt;things-I-used-to-know&lt;/em&gt; category.&lt;/p&gt;
&lt;p&gt;So give this, what would you call a shell for Fluidinfo?
It just &lt;em&gt;has&lt;/em&gt; to be &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;.   It&amp;#8217;s screaming out to be fish.
The only problem is that it&amp;#8217;s thirty-three per cent &lt;em&gt;worse&lt;/em&gt; (33% &lt;em&gt;more&lt;/em&gt; typing).&lt;/p&gt;
&lt;p&gt;Well, the fact that it&amp;#8217;s 33% worse &lt;em&gt;and&lt;/em&gt; a bit fishy.&lt;/p&gt;
&lt;p&gt;Well, the fact that it&amp;#8217;s 33% worse &lt;em&gt;and&lt;/em&gt; a bit fishy &lt;em&gt;and&lt;/em&gt; isn&amp;#8217;t
actually long enough to be a Google App Engine ID.
(Too long and yet too short; not long enough and yet altogether too long.
Such a paradox.)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="fdb-s-fate-sealed-by-a-typo"&gt;
&lt;h2&gt;FDB&amp;#8217;s Fate Sealed by a Typo&lt;a class="headerlink" href="#fdb-s-fate-sealed-by-a-typo" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As I was checking availability on App ID after App ID, I eventually
got to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt;.   Now shell-fish is just &lt;em&gt;silly&lt;/em&gt;.   I mean,
it&amp;#8217;s redundant (shell-Fluidinfo shell?).   It&amp;#8217;s hyphenated.
It&amp;#8217;s even fishier than fish.
It sounds like a drunken version of selfish.
Clearly, no person in his right mind was never going to choose &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;But then, instead of clicking the &amp;#8220;Check Availability Button&amp;#8221;,
I typed return.
And discovered that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt; was available.
And that I had registered it.&lt;/p&gt;
&lt;p&gt;Now, give me some credit.   I do appreciate that this wasn&amp;#8217;t really &lt;em&gt;it&lt;/em&gt;.
I could have changed it.   But it could have been worse.
I checked availability of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fishnet&lt;/span&gt;&lt;/tt&gt; (taken) and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish-net&lt;/span&gt;&lt;/tt&gt; (available)
and countless dozens I&amp;#8217;ve have to go back to the IRC logs to recall
so memorable were they.   But in the end, I wasn&amp;#8217;t convinced that I was
gong to do better than &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt;.   And it does lock in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;,
which is the perfect name for the Fluidinfo Shell&amp;#8212;well, except for being
33% worse, and fishy, and not available as a Google App Engine ID,
and . . .&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="shell-fish"&gt;
&lt;h2&gt;Shell-Fish&lt;a class="headerlink" href="#shell-fish" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So there it is.
If you wish to be a guinea pig, head on over to
&lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;http://shell-fish.appspot.com&lt;/a&gt;, where you can try &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; online.
It&amp;#8217;s mostly the same as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; was, and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; is, except that&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;you don&amp;#8217;t need to prefix commands with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; (or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;),
obviously.&lt;/li&gt;
&lt;li&gt;you are subject to the Google App Engine, 5&amp;#8211;10 second maximum for
an HTTP request.   This can be an issue; timeouts are not uncommon,
especially for complex queries, and when Fluidinfo is under load.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;#8217;s almost certainly buggy and subject to change.&lt;/p&gt;
&lt;p&gt;Right now, if you don&amp;#8217;t log in, you will use the Fluidinfo &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;test&lt;/span&gt;&lt;/tt&gt; user.
Before too long (when registrations are fixed), it&amp;#8217;ll be a different user.
But you can log in using your own Fluidinfo credentials if you like.&lt;/p&gt;
&lt;p&gt;The way you do that is that you log into the appliction using a Google
Account.   (My app doesn&amp;#8217;t get to see your Google password.)&lt;/p&gt;
&lt;p&gt;Then, if you go into settings, you can add one or more Fluidinfo accounts
by specifying your username and password.
(You can also choose whether to use the default, Fluidinfo-style full paths
for all tags and namespaces (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr/rating&lt;/span&gt;&lt;/tt&gt; etc.) or whether your own
tags and namespaces will be abbreviated to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rating&lt;/span&gt;&lt;/tt&gt; etc., at the cost
of having to use a leading &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/&lt;/span&gt;&lt;/tt&gt; for other people&amp;#8217;s (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/ntoll/rating&lt;/span&gt;&lt;/tt&gt; etc.).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT: PASSWORD SECURITY&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you register a Fluidinfo username and password, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt;
will store these in Google&amp;#8217;s data store.
I&amp;#8217;m not particularly comfortable either with asking people for
their passwords or with storing them, but I don&amp;#8217;t think there&amp;#8217;s
much alternative at the moment.
(There may be in an OAuth future.)&lt;/p&gt;
&lt;p&gt;Obviously, before you hand over your password, you need to consider a few
things:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Do you trust me?   I &lt;em&gt;could&lt;/em&gt; steal your password.&lt;/li&gt;
&lt;li&gt;Do you trust &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;?   Even if you think me worthy of your &lt;em&gt;trust&lt;/em&gt;,
do you consider me competent?   [Disclosure: sometimes, I make
mistakes.   See the discussion above on how &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt; got its name.]&lt;/li&gt;
&lt;li&gt;Are you happy with your password living in Google&amp;#8217;s data store?&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;On the last point, I have taken what might be called minimal precautions.
I do not store your password in plain text, partly so that should anyone
happen to gain access to Google&amp;#8217;s data store, they won&amp;#8217;t just be able
to read your password, and even more so that if &lt;em&gt;I&lt;/em&gt; browse the
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt; Google data store, &lt;em&gt;I&lt;/em&gt; won&amp;#8217;t inadvertantly see your password.
(I&amp;#8217;d have to decide to be evil.)&lt;/p&gt;
&lt;p&gt;But I should also admit that what I&amp;#8217;ve done to the password, while
presumably technically qualifying as &lt;em&gt;encryption&lt;/em&gt;, would probably be
more accurately termed &lt;em&gt;obfuscation&lt;/em&gt;.  Let&amp;#8217;s put it this way: it&amp;#8217;s
better than ROT-13, but it&amp;#8217;s not as strong as PGP.&lt;/p&gt;
&lt;p&gt;The other thing to know is that when you remove a user from your
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt; settings, I simply the datastore (well, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt;
tells the data store) to delete the record.  I certainly don&amp;#8217;t have
access to it after that; whether a &lt;a class="reference external" href="mailto:DrEvil&amp;#37;&amp;#52;&amp;#48;google&amp;#46;com"&gt;DrEvil&lt;span&gt;&amp;#64;&lt;/span&gt;google&lt;span&gt;&amp;#46;&lt;/span&gt;com&lt;/a&gt; could recover it,
I know not.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="id1"&gt;
&lt;h2&gt;Of Fish, Shell-Fish and Fish Py&lt;a class="headerlink" href="#id1" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So there it is.&lt;/p&gt;
&lt;p&gt;I am in the process of changing the name of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;.
(In fact, I&amp;#8217;ve done it locally, but I don&amp;#8217;t plan to push it to
Github for a few days.)&lt;/p&gt;
&lt;p&gt;The web app &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;shell-fish&lt;/span&gt;&lt;/tt&gt; is available at
&lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;http://shell-fish.appspot.com&lt;/a&gt; for brave early adopters.  I&amp;#8217;m fiddling
with it all the time.  It will change a lot (most importantly, I hope it
will end up looking more like a scrolling terminal than a one-shot
search engine&amp;#8212;think &lt;a class="reference external" href="http://goosh.org"&gt;Goosh&lt;/a&gt; rather
than &lt;a class="reference external" href="http://google.com"&gt;Google&lt;/a&gt;.
But right now, it&amp;#8217;s very Google.&lt;/p&gt;
&lt;p&gt;As &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; becomes &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt;, so will &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb.py&lt;/span&gt;&lt;/tt&gt; become &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish.py&lt;/span&gt;&lt;/tt&gt;
(geddit?).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="one-more-thing-amazon-product-pages"&gt;
&lt;h2&gt;One more thing . . . Amazon Product Pages&lt;a class="headerlink" href="#one-more-thing-amazon-product-pages" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ll blog about this separately, but even if you don&amp;#8217;t want to use
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; &lt;em&gt;per se&lt;/em&gt;, you might be interested in one neat little experimental
feature.&lt;/p&gt;
&lt;p&gt;At the top of the page in &lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;shell-fish&lt;/a&gt;, there&amp;#8217;s a link called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;az-fish&lt;/span&gt;&lt;/tt&gt;
(though it might become &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;amazon-fish&lt;/span&gt;&lt;/tt&gt;).  This is bookmarklet.  Don&amp;#8217;t
click on it on the page; rather drag it to your tool bar.
(It works even if you don&amp;#8217;t give &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; details of your Fluidinfo account.)&lt;/p&gt;
&lt;p&gt;Then, click it when you are on an Amazon product page
for a book, an eBook, a CD or an MP3 track.   (I&amp;#8217;ve only tested it
on Amazon UK and Amazon US; it will probably need to tweaked for others,
especially for &lt;em&gt;non-English&lt;/em&gt; others.)
It will take the URL
and give it to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fish&lt;/span&gt;&lt;/tt&gt; (at &lt;a class="reference external" href="http://shell-fish.appspot.com"&gt;shell-fish&lt;/a&gt;),
which will attempt to figure out the about tag for the corresponding
book, album or track in Fludiinfo, using its new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;amazon&lt;/span&gt;&lt;/tt&gt; command
(which may eventually become a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;thing&lt;/span&gt;&lt;/tt&gt; command.)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;How cool is that?&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-4846397418177566708?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/4846397418177566708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/06/of-fish-shell-fish-and-fish-py.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4846397418177566708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/4846397418177566708'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/06/of-fish-shell-fish-and-fish-py.html' title='Of Fish, Shell-Fish and Fish Py'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-814947291518469490</id><published>2011-06-12T11:44:00.000+01:00</published><updated>2011-06-12T11:44:53.925+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='permissions'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='fdb'/><title type='text'>Permissions and Permissiveness</title><content type='html'>&lt;div class="section" id="permissions-and-permissiveness"&gt;
&lt;blockquote&gt;
&lt;em&gt;It is a truth universally acknowledged, that a single namespace in
possession of a good tag bundle must be in want of a good privacy
policy.&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;Over recent weeks I&amp;#8217;ve written quite a lot about the Fluidinfo
permissions system, concentrating on what permissions Fluidinfo
maintains, how we might represent those, list them and change them.
Today I want to look at how they work, in practical terms, from a user&amp;#8217;s
perspective.  There were some surprises for me as I tried them out.
If you don&amp;#8217;t want to read all the detail you can cut the chase by
just reading the &lt;a class="reference internal" href="#take-aways"&gt;Take-aways&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In what follows, I will assume you are familiar with the structure of
Fluidinfo permissions and how &lt;a class="reference external" href="http://github.com/njr0/fdb/tree/master"&gt;fdb&lt;/a&gt; represents them and sets
them.&lt;/p&gt;
&lt;p&gt;If you haven&amp;#8217;t already read the post on
&lt;a class="reference external" href="http://blog.abouttag.com/2011/06/setting-and-changing-permissions-with.html"&gt;listing and setting permissions&lt;/a&gt;,
you will probably find it helpful to do so before continuing.&lt;/p&gt;
&lt;div class="section" id="privacy"&gt;
&lt;h2&gt;Privacy&lt;a class="headerlink" href="#privacy" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In what follows, I&amp;#8217;m generally going to change permissions in one
namespace, as user &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt; and explore the implications of this using
the user &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;miro&lt;/span&gt;&lt;/tt&gt;, which I also control.  If you want to do the same
exploration and only have access to a single account, bear in mind
that you can always user the test user (username &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;test&lt;/span&gt;&lt;/tt&gt;, password
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;test&lt;/span&gt;&lt;/tt&gt;) to try things out.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s set things up first:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb su njr0
Credentials set to user njr0.

$ fdb -F tag -a http://google.com njr0/secret/password="very secret"

$ fdb -F ls -ld njr0/secret njr0/secret/password
nrwcr--r--   njr0/secret/
trwcr--r--   njr0/secret/password

$ fdb -F perms private secret

$ fdb -F ls -ld njr0/secret
nrwc------   njr0/secret/&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So here we&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;set our credentials to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://google.com&lt;/span&gt;&lt;/tt&gt; with a password using a tag called
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;secret/password&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Check the permissions on the namespace (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0/secret&lt;/span&gt;&lt;/tt&gt;)
and the password tag (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0/secret/password&lt;/span&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;See that they&amp;#8217;re open, so change the permissions on
the namespace to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt;.
(In raw Fluidinfo-terms, means setting all permissions to
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;closed&lt;/span&gt;&lt;/tt&gt; with exception lists consisting of the owner&amp;#8212;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt;&amp;#8212;only.&lt;/li&gt;
&lt;li&gt;Verify that only I as the owner (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt;) have any permissions
on my secret namespace.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;[If you&amp;#8217;re wondering what&amp;#8217;s up with all the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-F&lt;/span&gt;&lt;/tt&gt; flags, these tell
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; to use full, Fluidinfo-style paths; I have &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; configured
to use unix-style relative paths that, by default, I don&amp;#8217;t need to put
in the leading &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0/&lt;/span&gt;&lt;/tt&gt;; if you don&amp;#8217;t change the default, you can
omit the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-F&lt;/span&gt;&lt;/tt&gt;.]&lt;/p&gt;
&lt;p&gt;Now let&amp;#8217;s switch to Miró, and see how things look.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb su miro
Credentials set to user miro.

$ fdb -F ls -ld njr0/secret

$ fdb -F show -a http://google.com njr0/secret/password
Object with about="http://google.com":
  njr0/secret/password = "very secret"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There is no output from the first &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt; command because Miró does not have
read permission (&amp;#8220;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;list&lt;/span&gt;&lt;/tt&gt;&amp;#8221; permission, as it is officially known) on the
namespace.  But the last command (the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;show&lt;/span&gt;&lt;/tt&gt; command) might come as
a bit of a surprise.&lt;/p&gt;
&lt;p&gt;Despite the fact that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt; removed read permission on the namespace
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0/secret&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;miro&lt;/span&gt;&lt;/tt&gt; can still read it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Fluidinfo permissions are&lt;/em&gt; &lt;strong&gt;NOT&lt;/strong&gt; &lt;em&gt;heirarchical.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you want to stop tags being read, you have to remove read permission
on each one individually.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;#8217;s not that the permissions system doesn&amp;#8217;t work; it&amp;#8217;s just a bit
more&amp;#8212;er&amp;#8212;&lt;em&gt;permissive&lt;/em&gt; than you might expect.  (Terry calls it
&amp;#8220;bloody-minded&amp;#8221;.)  In effect, Fluidinfo&amp;#8217;s read/list permission on
namespaces is a bit like execute permission on a directory in Unix,
with the difference that there isn&amp;#8217;t another permission to close up
the namespace completely.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s round this part of the discussion off by closing down the permission
on the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;password&lt;/span&gt;&lt;/tt&gt; tag.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb su njr0
Credentials set to user njr0.

$ fdb -F perms private njr0/secret/password

$ fdb -F ls -ld njr0/secret/password
trwc------   njr0/secret/password

$ fdb su miro
Credentials set to user miro.

$ fdb -F show -a http://google.com njr0/secret/password
Object with about="http://google.com":
  (error code 401 (UNAUTHORIZED) attempting to read tag njr0/secret/password)&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You might wonder whether this &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;UNAUTHORIZED&lt;/span&gt;&lt;/tt&gt; error is confirming that
the tag is present on this object, but it isn&amp;#8217;t.   We get the same
error if we try look looking for the tag on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://yahoo.com&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb -F show -a http://yahoo.com njr0/secret/password
Object with about="http://yahoo.com":
(error code 401 (UNAUTHORIZED) attempting to read tag njr0/secret/password)

$ fdb su njr0
fdb su njr0
Credentials set to user njr0.

$ fdb -F show -a http://yahoo.com njr0/secret/password
fdb -F show -a http://yahoo.com njr0/secret/password
Object with about="http://yahoo.com":
  (tag njr0/secret/password not present)&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The current situation is plainly unsatisfactory.&lt;/p&gt;
&lt;p&gt;A key reason for not wanting to make permissions hierarchical in
Fluidinfo is that this would require checking up the hierarchy when
reading them, which could be slow.  We are, however, discussing a
proposal that whenever a tag or namespace is created, the hierarchy be
checked and the permissions be set in a way that is consistent with
the enclosing namespace hierarchy.  If that were the case, most of the
practical problems would dissipate.  Under this proposal, if you were
to create a namespace, and then make it private, everything created
under it would then become private.  And if you decided to make an
existing namespace private, you would only have to change the
permissions on the subnamespaces and tags already in it to ensure that
the whole namespace would be private.  Indeed, if I were to add a
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt; option to the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt; command in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt;, to descend the
hierarchy recursively, this would be a single command.
I will probably do that.&lt;/p&gt;
&lt;p&gt;I hope this proposed change, or something similar, that will
be made in Fluidinfo.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="losing-control-beware-write-permission-on-namespaces"&gt;
&lt;h2&gt;Losing Control: Beware Write Permission on Namespaces&lt;a class="headerlink" href="#losing-control-beware-write-permission-on-namespaces" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s now turn our attention to write permissions.&lt;/p&gt;
&lt;p&gt;Fluidinfo actually maintains a plethora of write permissions,
but &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; normally shows and maniplates them together for simplicity.
Let&amp;#8217;s see what happens if &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt; gives write permission on
a namespace to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;miro&lt;/span&gt;&lt;/tt&gt;.   Specifically, let&amp;#8217;s set things so that
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;miro&lt;/span&gt;&lt;/tt&gt; can read and write the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;secret&lt;/span&gt;&lt;/tt&gt; namespace&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb su njr0
Credentials set to user njr0.

$ fdb -F perms group miro njr0/secret

$ fdb -F ls -gd njr0/secret
nrwcrw----   miro   njr0/secret/

$ fdb -F ls -l njr0/secret
trwc------   njr0/secret/password&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;As you can see, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt; retains read, write and control permissions
on the namespace &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0/secret&lt;/span&gt;&lt;/tt&gt;, but is now allowing miro to read and
write the namespace as well.  We also see that this hasn&amp;#8217;t changed the
permissions on the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0/secret/password&lt;/span&gt;&lt;/tt&gt; tag, which remains private
to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;So let&amp;#8217;s get Miró to tag something for us.
In particular, let&amp;#8217;s get it to give Amsterdam an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0/secret/rating&lt;/span&gt;&lt;/tt&gt; of 2.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb su miro
Credentials set to user miro.

$ fdb -F tag -a Amsterdam njr0/secret/rating=2

$ fdb -F ls -l njr0/secret/rating
tr--rwcr--   njr0/secret/rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Woah!   There&amp;#8217;s a permissions structure you don&amp;#8217;t expect to see very often.
Let&amp;#8217;s expand it using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-g&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb -F ls -g njr0/secret/rating
tr--rwcr--   r:(world)  w:miro   njr0/secret/rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Let&amp;#8217;s read across the permissions and see what they say.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;The leading &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;t&lt;/span&gt;&lt;/tt&gt; just means that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0/secret/rating&lt;/span&gt;&lt;/tt&gt; is a tag.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The next block of three (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;r--&lt;/span&gt;&lt;/tt&gt;) shows the permissions that the
&lt;em&gt;owner&lt;/em&gt;&amp;#8212;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt;&amp;#8212;has for this tag.
The owner only has read permission&amp;#8212;no write permissions on the
tag, and no control permissions.
(The owner is not a happy owner at this point.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Skipping to the final block of three (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;r--&lt;/span&gt;&lt;/tt&gt;), this shows that
the world (everyone, barring any group exceptions) has read permission
on the tag, but no write or control permissions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The &amp;#8220;middle&amp;#8221; block of three (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;rwc&lt;/span&gt;&lt;/tt&gt;) shows the group permissions,
and when listed used the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-g&lt;/span&gt;&lt;/tt&gt; opion, shows us that the read
group is world (shown as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(world)&lt;/span&gt;&lt;/tt&gt;) and the write group is
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;miro&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;So the read permission is as expected.   But the write permissions
are set so that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;miro&lt;/span&gt;&lt;/tt&gt; can write the tag, but the owner, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt;,
&lt;em&gt;cannot&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s worth saying again:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;When someone other than the owner (the person in whose
top-level namespace the tag exists) creates a tag, by
default the write permissions are set so that the&lt;/em&gt; &lt;strong&gt;creator&lt;/strong&gt;
has write permissions, and the &lt;strong&gt;owner&lt;/strong&gt; &lt;em&gt;does not.
The same goes for namespaces created by someone other than
the owner.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;If that weren&amp;#8217;t surprising enough, look at the control
permissions.  The owner doesn&amp;#8217;t have control permissions but
the group does.  The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-g&lt;/span&gt;&lt;/tt&gt; command in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; doesn&amp;#8217;t even
show you who, because, to be honest, I wasn&amp;#8217;t expecting control to
be given away very much.  I should probably make it so that it
lists the control group, when there is a group exception.)
The suspicion would have to be that the creator also gained
control permissions, but let&amp;#8217;s see by using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-L&lt;/span&gt;&lt;/tt&gt;, to give
the longer Fluidinfo view of the permissions, in all their glory.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;fdb -F ls -L njr0/secret/rating

njr0/secret/rating:

ABSTRACT TAG (/tags)
  Write
    update (metadata):  policy: closed; exceptions = [miro]
    delete (delete):    policy: closed; exceptions = [miro]
  Control
    control (control):  policy: closed; exceptions = [miro]

TAG (/tag-values)
  Read
    read (read):        policy: open; exceptions = []
  Write
    create (tag):       policy: closed; exceptions = [miro]
    delete (untag):     policy: closed; exceptions = [miro]
  Control
    control (control):  policy: closed; exceptions = [miro]&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;As suspected, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;miro&lt;/span&gt;&lt;/tt&gt; has expropriated not only write
permission, but also control permissions (the bounder!).
Miró now has it, and there&amp;#8217;s not a thing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt; can do
about it, other than appealing to Miró&amp;#8217;s better nature.&lt;/p&gt;
&lt;p&gt;Since Miró has control and write access, and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt; doesn&amp;#8217;t,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt; can&amp;#8217;t take back control of or delete the tag.
You might think &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt; could take the drastic step
of deleting the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0/secret&lt;/span&gt;&lt;/tt&gt; namespace, but he can&amp;#8217;t
even do that because a namespace has to be empty before
it can be deleted, and &lt;em&gt;njr0 can&amp;#8217;t make it empty&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Again, this is worth emphasizing:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Be very careful granting write permissions on
namespaces in Fluidinfo at the moment.   If you let someone
else write in your namespace, they will gain exclusive&lt;/em&gt;
&lt;strong&gt;write and control&lt;/strong&gt; &lt;em&gt;permissions over any tags and
namespaces they create under the namespace for which
you gave them write permissions, and you can&amp;#8217;t take
them back.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8220;You give an inch, they take a mile.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Obviously, when I say you can&amp;#8217;t take them back,
I mean that the Fluidinfo API won&amp;#8217;t let you take them back.
There really is a superuser in Fluidinfo (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fluidddb&lt;/span&gt;&lt;/tt&gt;)
and if you were to explain your predicament to the
Fluidinfo team, I&amp;#8217;m guessing they&amp;#8217;d be sympathetic.
But even so . . .&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is an extraordinary and bad situation which I&amp;#8217;m sure will be
remedied.  Clearly, it can&amp;#8217;t be right that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;miro&lt;/span&gt;&lt;/tt&gt; can end up have
complete and &lt;em&gt;exclusive&lt;/em&gt; control of a tag or subnamespace in my
namespace without my ever having granted &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;miro&lt;/span&gt;&lt;/tt&gt; control permissions
on anything.&lt;/p&gt;
&lt;p&gt;In effect, at the moment, the creator of the tag is becoming its
virtual &lt;em&gt;owner&lt;/em&gt;.   Indeed, the word &amp;#8220;owner&amp;#8221; becomes slightly
problematical here.   In the unix-like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-l&lt;/span&gt;&lt;/tt&gt; way of showing permissions,
I have used the first group of three control indicators to show
the permissions for the person whose Fluidinfo username is the
first part of the full path to the tag or namespace&amp;#8212;i.e.,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt; in the case of the tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0/secret/rating&lt;/span&gt;&lt;/tt&gt;.
I think this is natural and right, and I don&amp;#8217;t plan to change it.
I would even argue that it is consistent with Fluidinfo&amp;#8217;s view,
because Fluidinfo doesn&amp;#8217;t maintain any separate notion of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;owner&lt;/span&gt;&lt;/tt&gt;
of a tag or namespace.   In fact, in some sense, it doesn&amp;#8217;t have any
notion of an owner at all: tags and namespaces only have permissions,
and those consist of a &lt;em&gt;policy&lt;/em&gt; (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;open&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;closed&lt;/span&gt;&lt;/tt&gt;) and an
&lt;em&gt;exception list&lt;/em&gt; (a list of users to whom the policy is reversed).&lt;/p&gt;
&lt;p&gt;Fluidinfo is perfectly content for &lt;em&gt;no one&lt;/em&gt; to have any permissions
for a tag or namespace (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;000&lt;/span&gt;&lt;/tt&gt;).  Or for &lt;em&gt;everyone in the world
except the person in whose top-level namespace it resides&lt;/em&gt; to have
control permissions (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;policy:&lt;/span&gt; &lt;span class="pre"&gt;open;&lt;/span&gt; &lt;span class="pre"&gt;exceptions&lt;/span&gt; &lt;span class="pre"&gt;[njr0]&lt;/span&gt;&lt;/tt&gt;&amp;#8212;es
exemplified by the James Bond &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;007&lt;/span&gt;&lt;/tt&gt; permission, or even &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;001&lt;/span&gt;&lt;/tt&gt;
permissions).&lt;/p&gt;
&lt;blockquote&gt;
&amp;#8220;Yes, I do do see your predicament, old boy, but I&amp;#8217;m afraid you
really only have yourself to blame.  I suggest you be more careful
next time.  Toodle pip!&amp;#8221;&lt;/blockquote&gt;
&lt;p&gt;Bloody-minded isn&amp;#8217;t the half of it.
The team is aware of the situation, and again, I&amp;#8217;m confident things
will change.&lt;/p&gt;
&lt;p&gt;To round this off, let&amp;#8217;s just confirm that Miró can change things back.&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb su miro
Credentials set to user miro.

$ fdb -F perms default njr0/secret/rating

$ fdb su njr0
Credentials set to user njr0.

$ fdb -F ls -g njr0/secret/rating
trwcr--r--   (world)   njr0/secret/rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Sanity restored.   Unlike Fluidinfo, when you set the permissions to
default with the command&lt;/p&gt;
&lt;blockquote&gt;
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt; &lt;span class="pre"&gt;perms&lt;/span&gt; &lt;span class="pre"&gt;default&lt;/span&gt; &lt;span class="pre"&gt;njr0/secret/rating&lt;/span&gt;&lt;/tt&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; takes &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;default&lt;/span&gt;&lt;/tt&gt; to be the default for the &lt;em&gt;owner&lt;/em&gt; of the tag
(whoever is root namespace the tag lives in), not the creator
of the tag.   Therefore, permissions revert to the default.
(In this case, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;private&lt;/span&gt;&lt;/tt&gt; might have made more sense.)&lt;/p&gt;
&lt;p&gt;This has has the side effect of removing Miró&amp;#8217;s write permission,
since the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt; command doesn&amp;#8217;t have a way, at the moment, of
saying &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;give&lt;/span&gt; &lt;span class="pre"&gt;back&lt;/span&gt; &lt;span class="pre"&gt;control&lt;/span&gt; &lt;span class="pre"&gt;and&lt;/span&gt; &lt;span class="pre"&gt;write,&lt;/span&gt; &lt;span class="pre"&gt;but&lt;/span&gt; &lt;span class="pre"&gt;keep&lt;/span&gt; &lt;span class="pre"&gt;the&lt;/span&gt; &lt;span class="pre"&gt;exception&lt;/span&gt; &lt;span class="pre"&gt;on&lt;/span&gt; &lt;span class="pre"&gt;write&lt;/span&gt;&lt;/tt&gt;.
I might add such a thing, since it&amp;#8217;s clearly useful in the present situation,
or I might just implement &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;chmod&lt;/span&gt;&lt;/tt&gt;, which would probably let you do it
by saying &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt; &lt;span class="pre"&gt;chmod&lt;/span&gt; &lt;span class="pre"&gt;760&lt;/span&gt; &lt;span class="pre"&gt;njr0/secret/rating&lt;/span&gt;&lt;/tt&gt;.   To achieve full
resporation, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;njr0&lt;/span&gt;&lt;/tt&gt; now has to re-grant the appropriate permissions,
and indeed remove world read.
In this case, the relevant commands are&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb su njr0
Credentials set to user njr0.

$ fdb -F perms group miro njr0/secret/rating

$ fdb -F ls -g njr0/secret/rating
trwcrw----   miro   njr0/secret/rating&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here, we&amp;#8217;re back where we expected to be.
But it shouldn&amp;#8217;t have been that hard, even though the last step was only
necessary because the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt; command doesn&amp;#8217;t offer a way to hand back
control permissions to the owner while keeping write permissions (because,
when I implemented &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;perms&lt;/span&gt;&lt;/tt&gt;, I didn&amp;#8217;t know just how bloody-minded
Fluidinfo was.)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="take-aways"&gt;
&lt;h2&gt;Take-aways&lt;a class="headerlink" href="#take-aways" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here are the key take-aways:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;Permissions in Fluidino are entirely non-hierarchical.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;As a consequence of point 1, removing read permission
from a namespace does &lt;em&gt;not&lt;/em&gt; stop people reading tags or
namespace under it.   Any existing tags and namespaces
have to be changed explicitly to remove read access,
and any new tags or namespace created also have to be
protected individually.&lt;/p&gt;
&lt;p&gt;(You can change your defaults for new tags and namespaces using
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/policies&lt;/span&gt;&lt;/tt&gt; if you like; but &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/policies&lt;/span&gt;&lt;/tt&gt; affect all new tags
and namespaces, not just a subset.   It&amp;#8217;s a bit like an non-inverted
version of a Unix &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;umask&lt;/span&gt;&lt;/tt&gt;.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;When a new tag is created, its permissions are set according to
the default permissions the &lt;em&gt;creator&lt;/em&gt;, not the owner.  This
includes control permissions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The direct consequence of point 3 is that, in normal
circumstances, if someone else creates a tag or namespace
somewhere in your namespace (which they can, of course, do only
if you grant them the appropriate write permissions), they not
you will end up with exclusive write and control permissions
unless they explicitly change the permissions to that you have
access.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Practically speaking, I think the consequence of this that
you want to be very cautious granting write permissions on
namespaces.   Granting them on individual tags is much safer,
because permissions are at the level of the whole tag
(the &lt;em&gt;abstract&lt;/em&gt; tag, if you will), rather than at the
level of a particular tag on an object.   As far as
I can see, letting someone else write one of your tags
only allows them exactly what you would expect: they can
write that tag, delete it, change it and so forth,
but &lt;em&gt;not&lt;/em&gt; wrest control from you when you&amp;#8217;re not looking.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-814947291518469490?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/814947291518469490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/06/permissions-and-permissiveness.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/814947291518469490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/814947291518469490'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/06/permissions-and-permissiveness.html' title='Permissions and Permissiveness'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-3305599724599131720</id><published>2011-06-09T09:10:00.005+01:00</published><updated>2011-06-09T14:55:55.564+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='album'/><category scheme='http://www.blogger.com/atom/ns#' term='abouttag'/><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='track'/><category scheme='http://www.blogger.com/atom/ns#' term='artist'/><category scheme='http://www.blogger.com/atom/ns#' term='song'/><category scheme='http://www.blogger.com/atom/ns#' term='conventions'/><title type='text'>The Music of Fluidinfo II</title><content type='html'>&lt;div class="section" id="the-music-of-fluidinfo-ii"&gt;
&lt;p&gt;I pushed an update to the &lt;a class="reference external" href="https://github.com/njr0/abouttag"&gt;abouttag.py&lt;/a&gt;
library last night; it now includes some conventions and normalization
for some music-related items.
This supports work by Eric Seidel (&lt;a class="reference external" href="gridaphone"&gt;&amp;#64;gridaphobe&lt;/a&gt;),
who is looking at importing data from &lt;a class="reference external" href="http://musicbrainz.org"&gt;MusicBrainz&lt;/a&gt;
to Fluidinfo.&lt;/p&gt;
&lt;p&gt;These are similar (but not identical) to the ideas I proposed previously
in the post
&lt;a class="reference external" href="http://blog.abouttag.com/2011/01/music-of-fluiddb-i-albums-tracks-and.html"&gt;The Music of FluidDB I: Albums, Tracks and Songs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The first three kinds of things covered are &lt;em&gt;works&lt;/em&gt;&amp;#8212;named albums and
named tracks respectively.
As with books, this conceptual work seems like the single most important
level to represent in Fluidinfo.   So there may be many different issues,
editions and pressings of
&lt;em&gt;The Dark Side of the Moon&lt;/em&gt; by Pink Floyd, but there is only one
&lt;em&gt;work&lt;/em&gt;.
Even more clearly, Billie Holliday may have recorded
&lt;em&gt;God Bless the Child&lt;/em&gt; a number of times
(I&amp;#8217;m playing through several as I type this) , but there is only one
conceptual work &lt;em&gt;God Bless the Child&lt;/em&gt; sung by &lt;em&gt;Billie Holliday&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Albums (as works)&lt;/em&gt;.    The convention for this, called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;album-u&lt;/span&gt;&lt;/tt&gt;,
is similar, but not identical to the convention for books, having
the general form&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;album:name of album (artist)&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The name of the album and the artist are normalized using the
usual &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;normalize&lt;/span&gt;&lt;/tt&gt; function from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;abouttag.py&lt;/span&gt;&lt;/tt&gt;, removing some
punctuation, regularizing spacing and converting to lower case,
but &lt;em&gt;not&lt;/em&gt; removing accents.   (I think it&amp;#8217;s increasingly clear
that removing accents was a mistake in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book-1&lt;/span&gt;&lt;/tt&gt;; I&amp;#8217;m now
recommending using the relatied &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book-u&lt;/span&gt;&lt;/tt&gt; conventions,
which is like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book-1&lt;/span&gt;&lt;/tt&gt; except that it preserves accents.)&lt;/p&gt;
&lt;p&gt;The other main difference between the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book-u&lt;/span&gt;&lt;/tt&gt; convention
and the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;album-u&lt;/span&gt;&lt;/tt&gt; convention is that in the case of books,
multiple authors are consolidated into a standard list,
separated by semicolons (in fact, a semicolon followed by a space).
This works less well for music, where artists take more different
forms &lt;em&gt;Diana Ross and the Supremes&lt;/em&gt;, &lt;em&gt;Pink Floyd&lt;/em&gt;,
&lt;em&gt;John Renbourn and Stefan Grossman&lt;/em&gt;, &lt;em&gt;Crosby, Stills, Nash &amp;amp; Young&lt;/em&gt; etc.
Since MusicBrainz, in particular, has a well-defined artist field,
which is supposed to be the official recording credit,
Eric is just planning to standardize that.&lt;/p&gt;
&lt;p&gt;Example usage is:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;abouttag.music&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;album&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;quot;Solilaï&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;Pierre Bensusan&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;quot;Déjà   Vu&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;Crosby, Stills, Nash &amp;amp; Young&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;producing&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;album:solilaï (pierre bensusan)
album:déjà vu (crosby stills nash &amp;amp; young)&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Of course, we may also create objects for paricular releases
of an album, but those would use a different convention.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Named Tracks / Recorded Songs&lt;/em&gt;.
These are have a form that is identical to albums except that they
use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;track:&lt;/span&gt;&lt;/tt&gt; as the prefix.
Again, two different recordings of the same song
get consolodated into a single (conceptual) track
(convention &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;track-u&lt;/span&gt;&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;Example usage is:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;abouttag.music&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;track&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;Bamboulé&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;Bensusan and Malherbe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;&amp;#39;&amp;#39;Archie Campbell/Marjorie Campbell/Miss Lyall&amp;#39;s &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
            &lt;span class="s"&gt;u&amp;#39;&amp;#39;&amp;#39;Strathspey/Miss Lyall&amp;#39;s Reel/The St Kilda Wedding&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;u&amp;#39;The Cast&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;producing&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;track:bamboulé (bensusan and malherbe)
track:archie campbell marjorie campbell miss lyalls strathspey miss lyalls reel the st kilda wedding (the cast)&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Recordings&lt;/em&gt;.   In the case of conceptual tracks, it is particularly
clear that same artist may record the same track several times.
Happily, there is a standard identifier for such recordings of
tracks, the
&lt;a class="reference external" href="http://en.wikipedia.org/International_Standard_Recording_Code"&gt;International Standard Recording code&lt;/a&gt;.
This is 12-character code, usually formatted for print
as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;CC-XXX-YYY-NNNNN&lt;/span&gt;&lt;/tt&gt;,
where &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;CC&lt;/span&gt;&lt;/tt&gt; is a registrant country code, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;XXX&lt;/span&gt;&lt;/tt&gt; is a registrant code,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;UU&lt;/span&gt;&lt;/tt&gt; is the last two digits of the registration year and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;NNNNN&lt;/span&gt;&lt;/tt&gt;
identifies the recording.&lt;/p&gt;
&lt;p&gt;Despite minor misgivings on my part (I would have chosen to keep
the dashes, since Fluidinfo generally favours humans over machines),
we have chosen to standardize
this in the form &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;isrn:CCXXXYYYNNNNN&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;aboutag.music&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;isrc_recording&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;isrc_recording&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;US-PR3-73-00012&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;isrc_recording&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;uspr37300012&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;produces&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;isrc:USPR37300012
isrc:USPR37300012&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;em&gt;Artist&lt;/em&gt;. The artist is simply identified by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;artist:name&lt;/span&gt;&lt;/tt&gt;,
where name is normalized as usual.
Since accents are preversed, metal fans need not fear
for their
&lt;a class="reference external" href="http://jonudell.net/udell/gems/umlaut/umlaut.html"&gt;heavy metal umlauts&lt;/a&gt;
(a.k.a. &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Metal_umlaut"&gt;röck döts&lt;/a&gt;).
For example:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;aboutag.music&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;artist&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;artist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;quot;Crosby, Stills, Nash &amp;amp; Young&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;artist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;quot;Motörhead&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;produces:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;artist:crosby stills nash &amp;amp; young'
artist:motörhead'&lt;/pre&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div class="section" id="disambiguation-search-and-the-related-to-tag"&gt;
&lt;h2&gt;Disambiguation, search and the related-to tag&lt;a class="headerlink" href="#disambiguation-search-and-the-related-to-tag" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ll do a longer post on this shortly, but an interesting an useful
&lt;em&gt;metaconvention&lt;/em&gt; is emerging within Fluidinfo.&lt;/p&gt;
&lt;p&gt;I think there is a slightly reluctant but growing consensus within
the Fluidinfo community that it makes sense to use about tags that
exhibit &lt;a class="reference external" href="http://blog.abouttag.com/2011/04/pretty-good-uniqueness.html"&gt;pretty good uniqueness&lt;/a&gt;&amp;#8212;I&amp;#8217;ve suggested that at worst we should probably
aim for conventions that mean that when we deal with a million objects
we are unlikely to get a clash in about tags, not just within the list
but with anything else anyone is ever likely to put into Fluidinfo.&lt;/p&gt;
&lt;p&gt;At the same time, there is natural desire to make it easy for humans
to navigate Fluidinfo via the &lt;cite&gt;natural&lt;/cite&gt; about tags.
Mercury the planet and mercury the element share the natural about
tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mercury&lt;/span&gt;&lt;/tt&gt;, but there is clearly a problem if we just stick
information (like mass, or radius) on the object with about tag
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mercury&lt;/span&gt;&lt;/tt&gt;.
The about tags &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;planet:mercury&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;element:mercury&lt;/span&gt;&lt;/tt&gt; are much
less ambiguous.
(Unfortunately, in the early days I actually used
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;planet:Mercury&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;element:Mercury&lt;/span&gt;&lt;/tt&gt;; in my copious spare time,
I&amp;#8217;ll probably move the data over to the lower-case versions).&lt;/p&gt;
&lt;p&gt;The emerging meta-convention is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Store&lt;/em&gt; data on the most specific, unambiguous object
reasonably available&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;book:animal&lt;/span&gt; &lt;span class="pre"&gt;farm&lt;/span&gt; &lt;span class="pre"&gt;(george&lt;/span&gt; &lt;span class="pre"&gt;orwell)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;album:&lt;/span&gt; &lt;span class="pre"&gt;dark&lt;/span&gt; &lt;span class="pre"&gt;side&lt;/span&gt; &lt;span class="pre"&gt;of&lt;/span&gt; &lt;span class="pre"&gt;the&lt;/span&gt; &lt;span class="pre"&gt;moon&lt;/span&gt; &lt;span class="pre"&gt;(pink&lt;/span&gt; &lt;span class="pre"&gt;floyd)&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;element:mercury&lt;/span&gt;&lt;/tt&gt; etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Help humans&lt;/em&gt; by also using the more natural, ambiguous
objects&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;animal&lt;/span&gt; &lt;span class="pre"&gt;farm&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;dark&lt;/span&gt; &lt;span class="pre"&gt;side&lt;/span&gt; &lt;span class="pre"&gt;of&lt;/span&gt; &lt;span class="pre"&gt;the&lt;/span&gt; &lt;span class="pre"&gt;moon&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mercury&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;as disambiguation nodes (&lt;em&gt;à la&lt;/em&gt; Wikipedia),
adding appropriate &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;related-to&lt;/span&gt;&lt;/tt&gt; tags that point to
the various more specific items.
The convention for these is that they are sets of about tag
strings.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As an example, MusicBrainz might add a tag&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;musicbrainz&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;related&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;album:dark side of the moon (pink floyd)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;to the object with about tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;dark&lt;/span&gt; &lt;span class="pre"&gt;side&lt;/span&gt; &lt;span class="pre"&gt;of&lt;/span&gt; &lt;span class="pre"&gt;the&lt;/span&gt; &lt;span class="pre"&gt;moon&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Similarly, an the Fluidinfo object with the about tag &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;money&lt;/span&gt;&lt;/tt&gt;
might find itself tagged with (for example):&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;musicbrainz&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;related&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;track:money (pink floyd)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;track:money (the flying lizards)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="s"&gt;&amp;quot;track:money (michael jackson)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;album:money (kfmdm)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;miro&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;related&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;book:money (martin amis)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;imf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;related&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;economics:money&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and so forth.   This looks like it could have legs.&lt;/p&gt;
&lt;p&gt;The key principle is: put the data on specific object at the right
conceptual level, disambiguating as early as possible, i.e. don&amp;#8217;t
start by assuming that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;money&lt;/span&gt;&lt;/tt&gt; could only refer to the Pink Floyd
song, and use a convention that works well for all objects in
the class of interest.
Similarly, if you want put data that&amp;#8217;s only applicable to
a particular recording of that song, stick it on a more specific
object (in this case, perhaps the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;isrn:&lt;/span&gt;&lt;/tt&gt; object), probably
adding a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;related-to&lt;/span&gt;&lt;/tt&gt; tag pointing from the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;track:&lt;/span&gt;&lt;/tt&gt; object
to the various &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;isrn:&lt;/span&gt;&lt;/tt&gt; objects.&lt;/p&gt;
&lt;p&gt;My only problem with this convention is that the term &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;related-to&lt;/span&gt;&lt;/tt&gt;
sounds symmetrical, whereas it&amp;#8217;s being use in a fairly directed way.
Perhaps &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;could-refer-to&lt;/span&gt;&lt;/tt&gt; would be better.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829936301057674-3305599724599131720?l=blog.abouttag.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.abouttag.com/feeds/3305599724599131720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.abouttag.com/2011/06/he-music-of-fluidinfo-ii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3305599724599131720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829936301057674/posts/default/3305599724599131720'/><link rel='alternate' type='text/html' href='http://blog.abouttag.com/2011/06/he-music-of-fluidinfo-ii.html' title='The Music of Fluidinfo II'/><author><name>njr</name><uri>http://www.blogger.com/profile/08980758986023344486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829936301057674.post-3071504216885488858</id><published>2011-06-07T22:54:00.002+01:00</published><updated>2011-06-07T23:17:13.706+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='permissions'/><category scheme='http://www.blogger.com/atom/ns#' term='fluidinfo'/><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><category scheme='http://www.blogger.com/atom/ns#' term='fdb'/><title type='text'>Setting and Changing Permissions with FDB</title><content type='html'>&lt;div class="section" id="setting-and-changing-permissions-with-fdb"&gt;
&lt;p&gt;I pushed a significant upgrade to
&lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fdb/njr/index.html"&gt;fdb&lt;/a&gt;
to &lt;a class="reference external" href="http://github.com/njr0/fdb"&gt;GitHub&lt;/a&gt; (version 2.07) today.&lt;/p&gt;
&lt;p&gt;Key new features include:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The ability to change permissions on tags and namespaces&lt;/li&gt;
&lt;li&gt;The ability to list namespaces and tags, with a Unix-style
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt; (list sorted) command, supporting many options
that will be familiar to Unix users&amp;#8212;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-l&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-g&lt;/span&gt;&lt;/tt&gt;,
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-d&lt;/span&gt;&lt;/tt&gt; etc all do something like what you
might expect, and ls -L gives a full Fluidinfo listing
of the permissions structure in all its glory.&lt;/li&gt;
&lt;li&gt;Documentation: there is a complete set of documentation
for the fdb command line, including installation and
configuration notes.   This is supplied (both as source
and built) in the repository and is available directly from
Fluidinfo at &lt;a class="reference external" href="http://fluiddb.fluidinfo.com/about/fdb/njr/index.html"&gt;http://fluiddb.fluidinfo.com/about/fdb/njr/index.html&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;There is basic support for handling multiple Fluidinfo identities
with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;su&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;whoami&lt;/span&gt;&lt;/tt&gt; commands.&lt;/li&gt;
&lt;li&gt;The file &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb.py&lt;/span&gt;&lt;/tt&gt; has been renamed as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fdb&lt;/span&gt;&lt;/tt&gt; to make it even
simpler to use directly from an alias, link or by adding the
fdb directory to a shell path.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The rest of this post will illustrate the new &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt; command,
for listing namespaces and tags and information about them,
and the perms command which is used for changing permissions.&lt;/p&gt;
&lt;div class="section" id="fdb-ls"&gt;
&lt;h2&gt;fdb ls&lt;a class="headerlink" href="#fdb-ls" title="Permalink to this headline"&gt;¶&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt; command is used to view a sorted list of tags or namespaces,
potentially with additional information.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FORM&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;ls [flags] [&amp;lt;namespace&amp;gt;|&amp;lt;tag&amp;gt;]&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;FLAGS&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-l&lt;/span&gt;&lt;/tt&gt; long listing (one per line; showing permissions)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-g&lt;/span&gt;&lt;/tt&gt; group listing (one per line; showing exception groups and permissions)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-L&lt;/span&gt;&lt;/tt&gt; longer listing (show full Fluidinfo-style permissions listing)&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-n&lt;/span&gt;&lt;/tt&gt; list the namesace as an object, rather than the contents of the namespace&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-d&lt;/span&gt;&lt;/tt&gt; same as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-n&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-R&lt;/span&gt;&lt;/tt&gt; recursive (show contents of all subnamespaces, recursively)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;as well as the standard flags like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-s&lt;/span&gt;&lt;/tt&gt; etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EXAMPLES&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;List the tags in the user&amp;#8217;s namespace:&lt;/p&gt;
&lt;p&gt;(Here, we assume we are authenticated as user &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;miro&lt;/span&gt;&lt;/tt&gt;):&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb ls
bestsellers-1998-2010/    first_field_id            n_records
bestsellers1998to2010/    first_record_id           next-field-about
books/                    forename                  next-field-id
class                     has-about-links           next_field_about
consistent                has-field-numbers         next_field_id
description               has-id-links              planets/
elements/                 has-record-numbers        rating
field-name                has_about_links           small/
field-number              has_field_numbers         surname
field_number              has_id_links              table-name
first-field-about         has_record_numbers        testconvtag
first-field-id            message                   testrating
first-record-about        n-fields                  testtable/
first-record-id           n-records                 type
first_field_about         n_fields                  unit&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that namespaces are shown with a trailing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/&lt;/span&gt;&lt;/tt&gt;; for users familiar
with the unix &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt;&lt;/tt&gt; command, this is modelled on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ls&lt;/span&gt; &lt;span class="pre"&gt;-F&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;List the tags and subnamespaces in a given namespace:&lt;/p&gt;
&lt;div class="highlight-python"&gt;&lt;pre&gt;$ fdb ls miro/planets
Atmosphere                Mass                      OrbitalRadius
Category                  Moons            
