summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSmári McCarthy <smari@hilbert.(none)>2009-11-25 15:30:42 +0000
committerSmári McCarthy <smari@hilbert.(none)>2009-11-25 15:30:42 +0000
commit5e2997288fe03a1209dd5514ee99d7e176f06039 (patch)
tree60e383199e2631526f74b8731bca77069bfb11ca
parentabf5e252a4647992c794da86355d624f532f579e (diff)
parentb9eec2fa84604f9f697972d413bf89f32c5c015c (diff)
downloadtangiblebit-5e2997288fe03a1209dd5514ee99d7e176f06039.tar.gz
tangiblebit-5e2997288fe03a1209dd5514ee99d7e176f06039.zip
Merge branch 'master' of git@tangiblebit.com:tangiblebit
-rw-r--r--.gitignore2
-rw-r--r--data/types/basetypes.decl33
-rw-r--r--data/types/object.decl141
-rw-r--r--doc/dev.rst3
-rw-r--r--doc/formats.html465
-rw-r--r--doc/formats.rst195
-rw-r--r--doc/objects.html859
-rw-r--r--doc/objects.rst435
-rw-r--r--doc/tb.rst12
-rw-r--r--server/locations/views.py27
-rw-r--r--server/locations/xmlrpc.py9
-rw-r--r--server/objects/models.py8
-rw-r--r--server/objects/views.py19
-rw-r--r--server/urls.py1
14 files changed, 2205 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index 9f4f645..f8db1c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
*.pyc
+*~
+.*.swp
tangiblebit.sqlite3
*.pdf
diff --git a/data/types/basetypes.decl b/data/types/basetypes.decl
new file mode 100644
index 0000000..07cfcdd
--- /dev/null
+++ b/data/types/basetypes.decl
@@ -0,0 +1,33 @@
+# The basic types that can be used for atomic fields. Types not defined
+# here are complex types, made up of several atomic or complex types.
+
+int: "An integer number. External form: as in JSON.";
+
+float: "A floating point number. External form: as in JSON.";
+
+bool: 'A Boolean value, either "true" or "false".';
+
+string:
+ """A string. Use this base type for free-form strings that are not meant
+ to be localized. Strings can contain arbitrary Unicode characters.""";
+
+timestamp:
+ """A point in time. External form: like the `YAML timestamp
+ <http://yaml.org/type/timestamp.html>`_ type.""";
+
+identifier(string):
+ "An identifier, made up of alphanumeric characters and underscores.";
+
+freetext(string):
+ "Text that can be localized (translated in other languages).";
+
+formattedtext(freetext):
+ "A longer block of text that can contain formatting.";
+
+file(string): "A pointer to a file (stored externally).";
+
+# Unit types
+
+length(float): "A length, measured by default in meter (m).";
+
+mass(float): "A mass, measured by default in kilogram (kg).";
diff --git a/data/types/object.decl b/data/types/object.decl
new file mode 100644
index 0000000..e34c874
--- /dev/null
+++ b/data/types/object.decl
@@ -0,0 +1,141 @@
+Object {
+ uri: "http://tangiblebit.com/cat/object";
+ desc: "The root of the object hierarchy";
+
+ # Required properties
+ req {
+ name(freetext): "An informal name of the object.";
+
+ uri(string):
+ """An URI uniquely identifying the object; it's a good idea (but not
+ required) to use a HTTP URI and set up a web page at the specified
+ location, where interested users can find information on the object
+ and download it. Sample: http://example.com/design/coffeemaker if you
+ own the example.com domain.""";
+
+ summary(freetext):
+ """A short (one line) description of what the object is and what it
+ can be used for.""";
+
+ license(string):
+ """The license under which the object is made available (must be
+ compatible with CC-SA-BY or a free software/open source license in
+ order to allow inclusion in the TB object database). On the TBit
+ website there is controlled vocabulary of license names that should
+ be used in this field and in the *softwareLicense* field.""";
+ }
+
+ # Optional properties
+ opt {
+ description(formattedtext):
+ "A longer description of the object.";
+
+ lastModified(timestamp):
+ """Timestamp showing when the object metadata or the files or
+ processes connected with the object where last modified.""";
+
+ weight(mass):
+ "The weight of the object (set to 0 if this is a non-material object).";
+
+ width(length):
+ """The total width of the object, when fitting it into a box (0 if
+ this is a non-material object).""";
+
+ depth(length):
+ """The total depth of the object, when fitting it into a box (0 if
+ this is a non-material object).""";
+
+ height(length):
+ """The total height of the object, when fitting it into a box (0 if
+ this is a non-material object).""";
+
+ softwareLicense(string):
+ """The license under which the software related to the object is made
+ available (must be compatible with CC-SA-BY or a free software/open
+ source license in order to allow inclusion in the TB object
+ database). If omitted, the value given in the *license* field is used
+ instead.""";
+ }
+
+ # Properties occurring once or more
+ reqlist {
+ category(identifier): "List of categories the object belongs to.";
+
+ author(string): "List of the people which created/packaged the object.";
+
+ maintainer(string):
+ "List of people to contact regarding questions about the object.";
+
+ replaces(string):
+ "List of object URIs this object is meant to replace/make obsolete";
+ }
+
+ # Properties occurring any number of times
+ optlist {
+ thumbnail(File):
+ """A list of small visual depictions of the object (pointers to image
+ files).""";
+
+ file(File): "List of files associated with the object.";
+
+ process(Process): "List of processes associated with the object.";
+ }
+
+
+# The complex types used in Object declarations
+
+File {
+
+ req { # Required
+ role(string):
+ """The role of the file in regard to the object, e.g. "depiction"
+ (audio/visual of the object, e.g. a photo, drawing, or movie), "faq",
+ "whitepaper". On the TBit website there is controlled vocabulary of
+ recommended values for this field. Note: files such as "manual"
+ shouldn't be stored here; rather, they should be associated with a
+ *use process* (cf. below).""";
+
+ name(string): "The name of the file.";
+
+ mimetype(string): "The MIME type.";
+ }
+
+ opt { # Optional
+ description(freetext):
+ "A (preferably short) description of the file and its purpose";
+ }
+}
+
+Process {
+ req { # Required
+ role(string):
+ """The role of the process in regard to the object, one of
+
+ * build: how to build/produce the object.
+ * setup: how to setup the object prior to using it (comes between
+ build and usage, and can optionally later be repeated when
+ necessary.) Sample: program channel list on a TV set.
+ * use: how to use the object, in general or for some specific
+ purpose.
+ * dismantle: how to dismantle/disassemble the object.
+ * maintain: how to maintain the object--describes operations that
+ need to be performed regularly or occasionally to keep the object
+ in good order. Sample: change oil in a car.
+ * repair: how to repair the object or some parts of it.
+ * replace: how to replace same part of the object.""";
+
+ process(string): "The URI of the process.";
+
+ software(bool):
+ """If true, this file is licensed under the conditions specified in
+ the *softwareLicense* field, otherwise under the conditions of the
+ *license* field. This field is only used to provide licensing
+ information (it does not matter whether the file really contains
+ software).""";
+
+ description(freetext):
+ """A (preferably short) description of the process in relation to the
+ object.""";
+
+ }
+}
diff --git a/doc/dev.rst b/doc/dev.rst
new file mode 100644
index 0000000..f2551d2
--- /dev/null
+++ b/doc/dev.rst
@@ -0,0 +1,3 @@
+================================
+Coding Style & Development Notes
+================================
diff --git a/doc/formats.html b/doc/formats.html
new file mode 100644
index 0000000..e6d8aa5
--- /dev/null
+++ b/doc/formats.html
@@ -0,0 +1,465 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
+<title>Formats and Languages</title>
+<style type="text/css">
+
+/*
+:Author: David Goodger (goodger@python.org)
+:Id: $Id: html4css1.css 5196 2007-06-03 20:25:28Z wiemann $
+:Copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+*/
+
+/* used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+ border: 0 }
+
+table.borderless td, table.borderless th {
+ /* Override padding for "table.docutils td" with "! important".
+ The right padding separates the table cells. */
+ padding: 0 0.5em 0 0 ! important }
+
+.first {
+ /* Override more specific margin styles with "! important". */
+ margin-top: 0 ! important }
+
+.last, .with-subtitle {
+ margin-bottom: 0 ! important }
+
+.hidden {
+ display: none }
+
+a.toc-backref {
+ text-decoration: none ;
+ color: black }
+
+blockquote.epigraph {
+ margin: 2em 5em ; }
+
+dl.docutils dd {
+ margin-bottom: 0.5em }
+
+/* Uncomment (and remove this text!) to get bold-faced definition list terms
+dl.docutils dt {
+ font-weight: bold }
+*/
+
+div.abstract {
+ margin: 2em 5em }
+
+div.abstract p.topic-title {
+ font-weight: bold ;
+ text-align: center }
+
+div.admonition, div.attention, div.caution, div.danger, div.error,
+div.hint, div.important, div.note, div.tip, div.warning {
+ margin: 2em ;
+ border: medium outset ;
+ padding: 1em }
+
+div.admonition p.admonition-title, div.hint p.admonition-title,
+div.important p.admonition-title, div.note p.admonition-title,
+div.tip p.admonition-title {
+ font-weight: bold ;
+ font-family: sans-serif }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+ color: red ;
+ font-weight: bold ;
+ font-family: sans-serif }
+
+/* Uncomment (and remove this text!) to get reduced vertical space in
+ compound paragraphs.
+div.compound .compound-first, div.compound .compound-middle {
+ margin-bottom: 0.5em }
+
+div.compound .compound-last, div.compound .compound-middle {
+ margin-top: 0.5em }
+*/
+
+div.dedication {
+ margin: 2em 5em ;
+ text-align: center ;
+ font-style: italic }
+
+div.dedication p.topic-title {
+ font-weight: bold ;
+ font-style: normal }
+
+div.figure {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+div.footer, div.header {
+ clear: both;
+ font-size: smaller }
+
+div.line-block {
+ display: block ;
+ margin-top: 1em ;
+ margin-bottom: 1em }
+
+div.line-block div.line-block {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ margin-left: 1.5em }
+
+div.sidebar {
+ margin: 0 0 0.5em 1em ;
+ border: medium outset ;
+ padding: 1em ;
+ background-color: #ffffee ;
+ width: 40% ;
+ float: right ;
+ clear: right }
+
+div.sidebar p.rubric {
+ font-family: sans-serif ;
+ font-size: medium }
+
+div.system-messages {
+ margin: 5em }
+
+div.system-messages h1 {
+ color: red }
+
+div.system-message {
+ border: medium outset ;
+ padding: 1em }
+
+div.system-message p.system-message-title {
+ color: red ;
+ font-weight: bold }
+
+div.topic {
+ margin: 2em }
+
+h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
+h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
+ margin-top: 0.4em }
+
+h1.title {
+ text-align: center }
+
+h2.subtitle {
+ text-align: center }
+
+hr.docutils {
+ width: 75% }
+
+img.align-left {
+ clear: left }
+
+img.align-right {
+ clear: right }
+
+ol.simple, ul.simple {
+ margin-bottom: 1em }
+
+ol.arabic {
+ list-style: decimal }
+
+ol.loweralpha {
+ list-style: lower-alpha }
+
+ol.upperalpha {
+ list-style: upper-alpha }
+
+ol.lowerroman {
+ list-style: lower-roman }
+
+ol.upperroman {
+ list-style: upper-roman }
+
+p.attribution {
+ text-align: right ;
+ margin-left: 50% }
+
+p.caption {
+ font-style: italic }
+
+p.credits {
+ font-style: italic ;
+ font-size: smaller }
+
+p.label {
+ white-space: nowrap }
+
+p.rubric {
+ font-weight: bold ;
+ font-size: larger ;
+ color: maroon ;
+ text-align: center }
+
+p.sidebar-title {
+ font-family: sans-serif ;
+ font-weight: bold ;
+ font-size: larger }
+
+p.sidebar-subtitle {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+p.topic-title {
+ font-weight: bold }
+
+pre.address {
+ margin-bottom: 0 ;
+ margin-top: 0 ;
+ font-family: serif ;
+ font-size: 100% }
+
+pre.literal-block, pre.doctest-block {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+span.classifier {
+ font-family: sans-serif ;
+ font-style: oblique }
+
+span.classifier-delimiter {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+span.interpreted {
+ font-family: sans-serif }
+
+span.option {
+ white-space: nowrap }
+
+span.pre {
+ white-space: pre }
+
+span.problematic {
+ color: red }
+
+span.section-subtitle {
+ /* font-size relative to parent (h1..h6 element) */
+ font-size: 80% }
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px }
+
+table.docinfo {
+ margin: 2em 4em }
+
+table.docutils {
+ margin-top: 0.5em ;
+ margin-bottom: 0.5em }
+
+table.footnote {
+ border-left: solid 1px black;
+ margin-left: 1px }
+
+table.docutils td, table.docutils th,
+table.docinfo td, table.docinfo th {
+ padding-left: 0.5em ;
+ padding-right: 0.5em ;
+ vertical-align: top }
+
+table.docutils th.field-name, table.docinfo th.docinfo-name {
+ font-weight: bold ;
+ text-align: left ;
+ white-space: nowrap ;
+ padding-left: 0 }
+
+h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
+h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
+ font-size: 100% }
+
+ul.auto-toc {
+ list-style-type: none }
+
+</style>
+</head>
+<body>
+<div class="document" id="formats-and-languages">
+<h1 class="title">Formats and Languages</h1>
+
+<p>The formats and languages used by Tangible Bit are explained in English and
+formally defined in EBNF. TODO extract <tt class="docutils literal"><span class="pre">::</span></tt> blocks and use e.g pyparsing
+to autogenerate parsers.</p>
+<div class="section" id="ebnf-grammar">
+<h2>EBNF Grammar</h2>
+<p>We use an EBNF notation that is identical to the <a class="reference external" href="http://www.w3.org/TR/xml/#sec-notation">EBNF notation used in the
+XML specification</a>, except that
+we use <tt class="docutils literal"><span class="pre">symbol:</span> <span class="pre">expression;</span></tt> instead of <tt class="docutils literal"><span class="pre">symbol</span> <span class="pre">::=</span> <span class="pre">expression</span></tt> to
+define symbols.</p>
+</div>
+<div class="section" id="predefined-rules">
+<h2>Predefined Rules</h2>
+<p>The following EBNF rules are assumed to be predefined and not formally
+defined in this document:</p>
+<dl class="docutils">
+<dt>Char</dt>
+<dd>Any Unicode character</dd>
+<dt>UnicodeLetter</dt>
+<dd>A character that has the &quot;letter&quot; property in the Unicode database</dd>
+<dt>CR</dt>
+<dd>a carriage return character (#x0D)</dd>
+<dt>LF</dt>
+<dd>a line feed character (#x0A)</dd>
+</dl>
+</div>
+<div class="section" id="declarations-language-decl">
+<h2>Declarations Language (DecL)</h2>
+<p>A simple, easily writable, readable, and parsable format for declaring
+things, used by Tangible Bit for various purposes.</p>
+<p>There are four kinds of <em>atoms</em>: <em>strings</em>, <em>numbers</em>, <em>identifier
+expressions</em>, and <em>literals</em>:</p>
+<pre class="literal-block">
+Atom: String | Number | IdentifierExpression | Literal;
+</pre>
+<p>There are three types of <em>strings</em>: <em>full-quoted</em> (enclosed in full
+quotation marks), <em>half-quoted</em> (enclosed in half quotation marks), and
+<em>triple-quoted</em> (enclosed in pairs of three matching full or half quotes):</p>
+<pre class="literal-block">
+String: FullQuotedString | HalfQuotedString | TripleQuotedString;
+</pre>
+<p><em>Full-quoted strings</em> are sequences of arbitrary <em>inline characters</em>,
+enclosed between full quotation marks. Full quotation marks within the
+string <em>must</em> be backslash-escaped, literal backslashes and half quotation
+marks <em>may</em> be backslash-escaped (a literal backslash must be escaped if it
+occurs before another backslash or immediately before the end of the
+string); backslashes before any other characters are left in the string:</p>
+<pre class="literal-block">
+FullQuotedString: '&quot;' (InlineChar - [&quot;\] | &quot;\&quot; InlineChar)* '&quot;';
+</pre>
+<p><em>Half-quoted strings</em> are sequences of arbitrary <em>inline characters</em>,
+enclosed between half quotation marks. Half quotation marks within the
+string <em>must</em> be backslash-escaped, literal backslashes and full quotation
+marks <em>may</em> be backslash-escaped (a literal backslash must be escaped if it
+occurs before another backslash or immediately before the end of the
+string); backslashes before any other characters are left in the string:</p>
+<pre class="literal-block">
+HalfQuotedString: &quot;'&quot; (InlineChar - ['\] | &quot;\&quot; InlineChar)* &quot;'&quot;;
+</pre>
+<p><em>Inline characters</em> are any characters except line separators (CR and LF):</p>
+<pre class="literal-block">
+InlineChar: Char - (CR | LF)
+</pre>
+<p><em>Triple-quoted strings</em> are sequences of arbitrary characters enclosed
+between matching triples of full or half quotation marks. They can contain
+unescaped newline and quotation characters (as in Python). The string ends
+at the first triple of quote characters matching the opening triple, hence
+backslash-escaping is still necessary for triples of quote characters of
+the appropriate type and for quote characters of the appropriate type
+immediately preceding the closing triple. Generally, literal backslashes
+and full or half quotation marks may be backslash-escaped, while
+backslashes before any other characters are left in the string (as in the
+other types of strings):</p>
+<pre class="literal-block">
+TripleQuotedString: '&quot;&quot;&quot;' Char* '&quot;&quot;&quot;' | &quot;'''&quot; Char* &quot;'''&quot;;
+</pre>
+<p>TODO define other types of atoms (numbers are int or float, use as external
+form for basetypes) etc.</p>
+<p>literal: &quot;true&quot;, &quot;false&quot;, and &quot;null&quot;.</p>
+<p>identifier : (letter | [_&#64;] ) (letter | digit | [_&#64;] &quot;)*</p>
+<ul class="simple">
+<li>Atoms: strings, numbers, literals (true, false, null).</li>
+</ul>
+<p>TODO From the Python grammar:</p>
+<dl class="docutils">
+<dt>decimalinteger ::=</dt>
+<dd>nonzerodigit digit* | &quot;0&quot;</dd>
+<dt>nonzerodigit ::=</dt>
+<dd>&quot;1&quot;...&quot;9&quot;</dd>
+<dt>floatnumber ::=</dt>
+<dd>pointfloat | exponentfloat</dd>
+<dt>pointfloat ::=</dt>
+<dd>[intpart] fraction | intpart &quot;.&quot;</dd>
+<dt>exponentfloat ::=</dt>
+<dd><dl class="first last docutils">
+<dt>(intpart | pointfloat)</dt>
+<dd>exponent</dd>
+</dl>
+</dd>
+<dt>intpart ::=</dt>
+<dd>digit+</dd>
+<dt>fraction ::=</dt>
+<dd>&quot;.&quot; digit+</dd>
+<dt>exponent ::=</dt>
+<dd>(&quot;e&quot; | &quot;E&quot;) [&quot;+&quot; | &quot;-&quot;] digit+</dd>
+</dl>
+<p>TODO clean-up rest of document; rename BlockList to block, a document is
+probably BlockContent (a block, but without surrounding {}).</p>
+<p>A complete DecL <em>document</em> contains a single <em>list</em>:</p>
+<pre class="literal-block">
+Document: List;
+</pre>
+<p>There are two kinds of <em>lists</em>: <em>inline list</em> and <em>block lists</em>:</p>
+<pre class="literal-block">
+List: InlineList | BlockList;
+</pre>
+<p>Each <em>inline list</em> is a series of zero or more <em>simple values</em>:</p>
+<pre class="literal-block">
+InlineList: (SimpleValue)*;
+</pre>
+<p>TODO? Each <em>block list</em> is a series of zero or more <em>block list items</em>:</p>
+<pre class="literal-block">
+BlockList: ()*;
+</pre>
+<p><em>Simple values</em> are <em>atoms</em>, <em>conditions</em>, <em>calculations</em> or <em>inline
+lists</em>:</p>
+<pre class="literal-block">
+SimpleValue: Atom | Condition | Calculation | InlineList;
+</pre>
+<p>TODO:</p>
+<ul class="simple">
+<li>Identifiers: as in Python, but can also contain the characters &quot;&#64;$.&quot;
+(also compare with XML identifiers, though &quot;:&quot; and &quot;-&quot; can't be
+admitted).</li>
+<li>Identifiers can be interpreted as identifier expressions using the &quot;$&quot;
+and &quot;.&quot;: <em>name$n</em> delivers the n-child of <em>name</em> (list-style access,
+probably counting from 0); <em>dictname.childname</em> returns the child(ren)
+with the specified <em>childname</em> (hash-style access)--automatically returns
+a list if there are several keys with this value. Values are
+auto-converted to lists on demand, i.e. <em>dictname.childname$0</em> will work
+even if there is only one child with that name. However, this behavior is
+application-specific, DecL core doesn't try to interpret identifiers in
+any way.</li>
+<li>Calculations: evaluate to an atom using standard operators arithmetic
+operators (+, -, *, /, %). Can contain Atoms. Grouping is used where
+necessary to resolve ambiguities.</li>
+<li>Conditions: evaluate to a boolean using standard boolean syntax: logical
+connectives (! &amp; | ^), relational operators (== != &lt; &gt; &lt;= &gt;=), set
+operators (in ~). Can contain calculations and atoms and atom lists.
+Grouping is used where necessary to resolve ambiguities.</li>
+</ul>
+<p><em>Numbers</em> must satisfy one of the following regular expressions:</p>
+<pre class="literal-block">
+[-+]?(0|[1-9][0-9_]*) # base 10 int
+ [-+]?([0-9][0-9_]*)?\.[0-9.]*([eE][-+][0-9]+)? # base 10 float
+ [-+]?(inf|Inf) # infinity
+(nan|NaN) # not a number
+</pre>
+<p>Each <em>block list item</em> is a <em>simple item</em> or <em>name/value pair.</em></p>
+<p><em>Name/value pairs</em> are either written as a <em>name</em> followed by &quot;:&quot; and
+whitespace, followed by a <em>simple value</em>.</p>
+<p>TODO <em>Names</em> are <em>simple values</em> or <em>annotated atoms</em>.</p>
+</div>
+<div class="section" id="type-declaration-language">
+<h2>Type Declaration Language</h2>
+<p>TODO describe format used for <tt class="docutils literal"><span class="pre">basetypes.decl</span></tt> (basic types) as well as
+for object declarations and complex types. Possibly define additional
+<em>optlist</em> field for child categories: <tt class="docutils literal"><span class="pre">parent</span></tt> contains the URI of the
+parent category/categories (but in the base types, we just specify the
+parent type in parentheses the name)--probably unify name and URI and allow
+declaring a <tt class="docutils literal"><span class="pre">&#64;uriprefix</span></tt> field for relative URIs (cf. prefixes used in
+N3/RDF). Each file should contain the declaration of an object category as
+well as any complex types used in its definition.</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/doc/formats.rst b/doc/formats.rst
new file mode 100644
index 0000000..a1c1a6c
--- /dev/null
+++ b/doc/formats.rst
@@ -0,0 +1,195 @@
+=====================
+Formats and Languages
+=====================
+
+The formats and languages used by Tangible Bit are explained in English and
+formally defined in EBNF. TODO extract ``::`` blocks and use e.g pyparsing
+to autogenerate parsers.
+
+EBNF Grammar
+~~~~~~~~~~~~
+
+We use an EBNF notation that is identical to the `EBNF notation used in the
+XML specification <http://www.w3.org/TR/xml/#sec-notation>`_, except that
+we use ``symbol: expression;`` instead of ``symbol ::= expression`` to
+define symbols.
+
+Predefined Rules
+~~~~~~~~~~~~~~~~
+
+The following EBNF rules are assumed to be predefined and not formally
+defined in this document:
+
+Char
+ Any Unicode character
+
+UnicodeLetter
+ A character that has the "letter" property in the Unicode database
+
+CR
+ a carriage return character (#x0D)
+
+LF
+ a line feed character (#x0A)
+
+Declarations Language (DecL)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A simple, easily writable, readable, and parsable format for declaring
+things, used by Tangible Bit for various purposes.
+
+There are four kinds of *atoms*: *strings*, *numbers*, *identifier
+expressions*, and *literals*::
+
+ Atom: String | Number | IdentifierExpression | Literal;
+
+There are three types of *strings*: *full-quoted* (enclosed in full
+quotation marks), *half-quoted* (enclosed in half quotation marks), and
+*triple-quoted* (enclosed in pairs of three matching full or half quotes)::
+
+ String: FullQuotedString | HalfQuotedString | TripleQuotedString;
+
+*Full-quoted strings* are sequences of arbitrary *inline characters*,
+enclosed between full quotation marks. Full quotation marks within the
+string *must* be backslash-escaped, literal backslashes and half quotation
+marks *may* be backslash-escaped (a literal backslash must be escaped if it
+occurs before another backslash or immediately before the end of the
+string); backslashes before any other characters are left in the string::
+
+ FullQuotedString: '"' (InlineChar - ["\] | "\" InlineChar)* '"';
+
+*Half-quoted strings* are sequences of arbitrary *inline characters*,
+enclosed between half quotation marks. Half quotation marks within the
+string *must* be backslash-escaped, literal backslashes and full quotation
+marks *may* be backslash-escaped (a literal backslash must be escaped if it
+occurs before another backslash or immediately before the end of the
+string); backslashes before any other characters are left in the string::
+
+ HalfQuotedString: "'" (InlineChar - ['\] | "\" InlineChar)* "'";
+
+*Inline characters* are any characters except line separators (CR and LF)::
+
+ InlineChar: Char - (CR | LF)
+
+*Triple-quoted strings* are sequences of arbitrary characters enclosed
+between matching triples of full or half quotation marks. They can contain
+unescaped newline and quotation characters (as in Python). The string ends
+at the first triple of quote characters matching the opening triple, hence
+backslash-escaping is still necessary for triples of quote characters of
+the appropriate type and for quote characters of the appropriate type
+immediately preceding the closing triple. Generally, literal backslashes
+and full or half quotation marks may be backslash-escaped, while
+backslashes before any other characters are left in the string (as in the
+other types of strings)::
+
+ TripleQuotedString: '"""' Char* '"""' | "'''" Char* "'''";
+
+TODO define other types of atoms (numbers are int or float, use as external
+form for basetypes) etc.
+
+literal: "true", "false", and "null".
+
+identifier : (letter | [_@] ) (letter | digit | [_@] ")*
+
+* Atoms: strings, numbers, literals (true, false, null).
+
+TODO From the Python grammar:
+
+decimalinteger ::=
+ nonzerodigit digit* | "0"
+
+nonzerodigit ::=
+ "1"..."9"
+
+floatnumber ::=
+ pointfloat | exponentfloat
+
+pointfloat ::=
+ [intpart] fraction | intpart "."
+
+exponentfloat ::=
+ (intpart | pointfloat)
+ exponent
+
+intpart ::=
+ digit+
+
+fraction ::=
+ "." digit+
+
+exponent ::=
+ ("e" | "E") ["+" | "-"] digit+
+
+TODO clean-up rest of document; rename BlockList to block, a document is
+probably BlockContent (a block, but without surrounding {}).
+
+A complete DecL *document* contains a single *list*::
+
+ Document: List;
+
+There are two kinds of *lists*: *inline list* and *block lists*::
+
+ List: InlineList | BlockList;
+
+Each *inline list* is a series of zero or more *simple values*::
+
+ InlineList: (SimpleValue)*;
+
+TODO? Each *block list* is a series of zero or more *block list items*::
+
+ BlockList: ()*;
+
+*Simple values* are *atoms*, *conditions*, *calculations* or *inline
+lists*::
+
+ SimpleValue: Atom | Condition | Calculation | InlineList;
+
+
+
+TODO:
+
+* Identifiers: as in Python, but can also contain the characters "@$."
+ (also compare with XML identifiers, though ":" and "-" can't be
+ admitted).
+* Identifiers can be interpreted as identifier expressions using the "$"
+ and ".": *name$n* delivers the n-child of *name* (list-style access,
+ probably counting from 0); *dictname.childname* returns the child(ren)
+ with the specified *childname* (hash-style access)--automatically returns
+ a list if there are several keys with this value. Values are
+ auto-converted to lists on demand, i.e. *dictname.childname$0* will work
+ even if there is only one child with that name. However, this behavior is
+ application-specific, DecL core doesn't try to interpret identifiers in
+ any way.
+* Calculations: evaluate to an atom using standard operators arithmetic
+ operators (+, -, \*, /, %). Can contain Atoms. Grouping is used where
+ necessary to resolve ambiguities.
+* Conditions: evaluate to a boolean using standard boolean syntax: logical
+ connectives (! & | ^), relational operators (== != < > <= >=), set
+ operators (in ~). Can contain calculations and atoms and atom lists.
+ Grouping is used where necessary to resolve ambiguities.
+
+*Numbers* must satisfy one of the following regular expressions::
+
+ [-+]?(0|[1-9][0-9_]*) # base 10 int
+ [-+]?([0-9][0-9_]*)?\.[0-9.]*([eE][-+][0-9]+)? # base 10 float
+ [-+]?(inf|Inf) # infinity
+ (nan|NaN) # not a number
+
+Each *block list item* is a *simple item* or *name/value pair.*
+
+*Name/value pairs* are either written as a *name* followed by ":" and
+whitespace, followed by a *simple value*.
+
+TODO *Names* are *simple values* or *annotated atoms*.
+
+Type Declaration Language
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+TODO describe format used for ``basetypes.decl`` (basic types) as well as
+for object declarations and complex types. Possibly define additional
+*optlist* field for child categories: ``parent`` contains the URI of the
+parent category/categories (but in the base types, we just specify the
+parent type in parentheses the name)--probably unify name and URI and allow
+declaring a ``@uriprefix`` field for relative URIs (cf. prefixes used in
+N3/RDF). Each file should contain the declaration of an object category as
+well as any complex types used in its definition.
diff --git a/doc/objects.html b/doc/objects.html
new file mode 100644
index 0000000..b26796d
--- /dev/null
+++ b/doc/objects.html
@@ -0,0 +1,859 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
+<title>Tangible Bit Object System</title>
+<style type="text/css">
+
+/*
+:Author: David Goodger (goodger@python.org)
+:Id: $Id: html4css1.css 5196 2007-06-03 20:25:28Z wiemann $
+:Copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+*/
+
+/* used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+ border: 0 }
+
+table.borderless td, table.borderless th {
+ /* Override padding for "table.docutils td" with "! important".
+ The right padding separates the table cells. */
+ padding: 0 0.5em 0 0 ! important }
+
+.first {
+ /* Override more specific margin styles with "! important". */
+ margin-top: 0 ! important }
+
+.last, .with-subtitle {
+ margin-bottom: 0 ! important }
+
+.hidden {
+ display: none }
+
+a.toc-backref {
+ text-decoration: none ;
+ color: black }
+
+blockquote.epigraph {
+ margin: 2em 5em ; }
+
+dl.docutils dd {
+ margin-bottom: 0.5em }
+
+/* Uncomment (and remove this text!) to get bold-faced definition list terms
+dl.docutils dt {
+ font-weight: bold }
+*/
+
+div.abstract {
+ margin: 2em 5em }
+
+div.abstract p.topic-title {
+ font-weight: bold ;
+ text-align: center }
+
+div.admonition, div.attention, div.caution, div.danger, div.error,
+div.hint, div.important, div.note, div.tip, div.warning {
+ margin: 2em ;
+ border: medium outset ;
+ padding: 1em }
+
+div.admonition p.admonition-title, div.hint p.admonition-title,
+div.important p.admonition-title, div.note p.admonition-title,
+div.tip p.admonition-title {
+ font-weight: bold ;
+ font-family: sans-serif }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+ color: red ;
+ font-weight: bold ;
+ font-family: sans-serif }
+
+/* Uncomment (and remove this text!) to get reduced vertical space in
+ compound paragraphs.
+div.compound .compound-first, div.compound .compound-middle {
+ margin-bottom: 0.5em }
+
+div.compound .compound-last, div.compound .compound-middle {
+ margin-top: 0.5em }
+*/
+
+div.dedication {
+ margin: 2em 5em ;
+ text-align: center ;
+ font-style: italic }
+
+div.dedication p.topic-title {
+ font-weight: bold ;
+ font-style: normal }
+
+div.figure {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+div.footer, div.header {
+ clear: both;
+ font-size: smaller }
+
+div.line-block {
+ display: block ;
+ margin-top: 1em ;
+ margin-bottom: 1em }
+
+div.line-block div.line-block {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ margin-left: 1.5em }
+
+div.sidebar {
+ margin: 0 0 0.5em 1em ;
+ border: medium outset ;
+ padding: 1em ;
+ background-color: #ffffee ;
+ width: 40% ;
+ float: right ;
+ clear: right }
+
+div.sidebar p.rubric {
+ font-family: sans-serif ;
+ font-size: medium }
+
+div.system-messages {
+ margin: 5em }
+
+div.system-messages h1 {
+ color: red }
+
+div.system-message {
+ border: medium outset ;
+ padding: 1em }
+
+div.system-message p.system-message-title {
+ color: red ;
+ font-weight: bold }
+
+div.topic {
+ margin: 2em }
+
+h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
+h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
+ margin-top: 0.4em }
+
+h1.title {
+ text-align: center }
+
+h2.subtitle {
+ text-align: center }
+
+hr.docutils {
+ width: 75% }
+
+img.align-left {
+ clear: left }
+
+img.align-right {
+ clear: right }
+
+ol.simple, ul.simple {
+ margin-bottom: 1em }
+
+ol.arabic {
+ list-style: decimal }
+
+ol.loweralpha {
+ list-style: lower-alpha }
+
+ol.upperalpha {
+ list-style: upper-alpha }
+
+ol.lowerroman {
+ list-style: lower-roman }
+
+ol.upperroman {
+ list-style: upper-roman }
+
+p.attribution {
+ text-align: right ;
+ margin-left: 50% }
+
+p.caption {
+ font-style: italic }
+
+p.credits {
+ font-style: italic ;
+ font-size: smaller }
+
+p.label {
+ white-space: nowrap }
+
+p.rubric {
+ font-weight: bold ;
+ font-size: larger ;
+ color: maroon ;
+ text-align: center }
+
+p.sidebar-title {
+ font-family: sans-serif ;
+ font-weight: bold ;
+ font-size: larger }
+
+p.sidebar-subtitle {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+p.topic-title {
+ font-weight: bold }
+
+pre.address {
+ margin-bottom: 0 ;
+ margin-top: 0 ;
+ font-family: serif ;
+ font-size: 100% }
+
+pre.literal-block, pre.doctest-block {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+span.classifier {
+ font-family: sans-serif ;
+ font-style: oblique }
+
+span.classifier-delimiter {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+span.interpreted {
+ font-family: sans-serif }
+
+span.option {
+ white-space: nowrap }
+
+span.pre {
+ white-space: pre }
+
+span.problematic {
+ color: red }
+
+span.section-subtitle {
+ /* font-size relative to parent (h1..h6 element) */
+ font-size: 80% }
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px }
+
+table.docinfo {
+ margin: 2em 4em }
+
+table.docutils {
+ margin-top: 0.5em ;
+ margin-bottom: 0.5em }
+
+table.footnote {
+ border-left: solid 1px black;
+ margin-left: 1px }
+
+table.docutils td, table.docutils th,
+table.docinfo td, table.docinfo th {
+ padding-left: 0.5em ;
+ padding-right: 0.5em ;
+ vertical-align: top }
+
+table.docutils th.field-name, table.docinfo th.docinfo-name {
+ font-weight: bold ;
+ text-align: left ;
+ white-space: nowrap ;
+ padding-left: 0 }
+
+h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
+h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
+ font-size: 100% }
+
+ul.auto-toc {
+ list-style-type: none }
+
+</style>
+</head>
+<body>
+<div class="document" id="tangible-bit-object-system">
+<h1 class="title">Tangible Bit Object System</h1>
+
+<p>The Tangible Bit Object System (TBOS) describes physical objects. It
+contains including detailed and automatically processable on how they can
+be build, how they can be used, and what they can be used for. The TBOS
+takes care of the entire life cycle of an object, including information on
+maintenance, part replacement, and repair, and disassembly.</p>
+<p>Each object has <em>properties</em> that describe the object. Each object is
+associated with <em>processes</em> that describe how the object can be build,
+used, maintained, repaired, modified, or dismantled.</p>
+<div class="section" id="object-descriptions">
+<h2>Object Descriptions</h2>
+<p>The most important property of each object are its <em>categories</em> (types).
+This allows placing all objects in a type hierarchy. Each category extends
+another category, the most general object category is <em>Object</em>; each object
+is an instance of one or several category (we allow multiple inheritance
+here). The hierarchy of object categories, as known to Tangible Bit, is
+stored in <tt class="docutils literal"><span class="pre">doc/object_categories.txt</span></tt> (TODO should be formalized and
+moved outside the <tt class="docutils literal"><span class="pre">doc</span></tt> directory; it should be possible to just refer to
+categories by URI to remove the dependency on a single authority). The
+object category also specified which other properties the object has.</p>
+<p>The properties of the <em>Object</em> category, which are shared by all objects,
+are as follows:</p>
+<pre class="literal-block">
+Object {
+ uri: &quot;http://tangiblebit.com/cat/object&quot;;
+ desc: &quot;The root of the object hierarchy&quot;;
+
+ # Required properties
+ req {
+ name(freetext): &quot;An informal name of the object.&quot;;
+
+ uri(string):
+ &quot;&quot;&quot;An URI uniquely identifying the object; it's a good idea (but not
+ required) to use a HTTP URI and set up a web page at the specified
+ location, where interested users can find information on the object
+ and download it. Sample: http://example.com/design/coffeemaker if you
+ own the example.com domain.&quot;&quot;&quot;;
+
+ summary(freetext):
+ &quot;&quot;&quot;A short (one line) description of what the object is and what it
+ can be used for.&quot;&quot;&quot;;
+
+ license(string):
+ &quot;&quot;&quot;The license under which the object is made available (must be
+ compatible with CC-SA-BY or a free software/open source license in
+ order to allow inclusion in the TB object database). On the TBit
+ website there is controlled vocabulary of license names that should
+ be used in this field and in the *softwareLicense* field.&quot;&quot;&quot;;
+ }
+
+ # Optional properties
+ opt {
+ description(formattedtext):
+ &quot;A longer description of the object.&quot;;
+
+ lastModified(timestamp):
+ &quot;&quot;&quot;Timestamp showing when the object metadata or the files or
+ processes connected with the object where last modified.&quot;&quot;&quot;;
+
+ weight(mass):
+ &quot;The weight of the object (set to 0 if this is a non-material object).&quot;;
+
+ width(length):
+ &quot;&quot;&quot;The total width of the object, when fitting it into a box (0 if
+ this is a non-material object).&quot;&quot;&quot;;
+
+ depth(length):
+ &quot;&quot;&quot;The total depth of the object, when fitting it into a box (0 if
+ this is a non-material object).&quot;&quot;&quot;;
+
+ height(length):
+ &quot;&quot;&quot;The total height of the object, when fitting it into a box (0 if
+ this is a non-material object).&quot;&quot;&quot;;
+
+ softwareLicense(string):
+ &quot;&quot;&quot;The license under which the software related to the object is made
+ available (must be compatible with CC-SA-BY or a free software/open
+ source license in order to allow inclusion in the TB object
+ database). If omitted, the value given in the *license* field is used
+ instead.&quot;&quot;&quot;;
+ }
+
+ # Properties occurring once or more
+ reqlist {
+ category(identifier): &quot;List of categories the object belongs to.&quot;;
+
+ author(string): &quot;List of the people which created/packaged the object.&quot;;
+
+ maintainer(string):
+ &quot;List of people to contact regarding questions about the object.&quot;;
+
+ replaces(string):
+ &quot;List of object URIs this object is meant to replace/make obsolete&quot;;
+ }
+
+ # Properties occurring any number of times
+ optlist {
+ thumbnail(File):
+ &quot;&quot;&quot;A list of small visual depictions of the object (pointers to image
+ files).&quot;&quot;&quot;;
+
+ file(File): &quot;List of files associated with the object.&quot;;
+
+ process(Process): &quot;List of processes associated with the object.&quot;;
+ }
+
+
+# The complex types used in Object declarations
+
+File {
+
+ req { # Required
+ role(string):
+ &quot;&quot;&quot;The role of the file in regard to the object, e.g. &quot;depiction&quot;
+ (audio/visual of the object, e.g. a photo, drawing, or movie), &quot;faq&quot;,
+ &quot;whitepaper&quot;. On the TBit website there is controlled vocabulary of
+ recommended values for this field. Note: files such as &quot;manual&quot;
+ shouldn't be stored here; rather, they should be associated with a
+ *use process* (cf. below).&quot;&quot;&quot;;
+
+ name(string): &quot;The name of the file.&quot;;
+
+ mimetype(string): &quot;The MIME type.&quot;;
+ }
+
+ opt { # Optional
+ description(freetext):
+ &quot;A (preferably short) description of the file and its purpose&quot;;
+ }
+}
+
+Process {
+ req { # Required
+ role(string):
+ &quot;&quot;&quot;The role of the process in regard to the object, one of
+
+ * build: how to build/produce the object.
+ * setup: how to setup the object prior to using it (comes between
+ build and usage, and can optionally later be repeated when
+ necessary.) Sample: program channel list on a TV set.
+ * use: how to use the object, in general or for some specific
+ purpose.
+ * dismantle: how to dismantle/disassemble the object.
+ * maintain: how to maintain the object--describes operations that
+ need to be performed regularly or occasionally to keep the object
+ in good order. Sample: change oil in a car.
+ * repair: how to repair the object or some parts of it.
+ * replace: how to replace same part of the object.&quot;&quot;&quot;;
+
+ process(string): &quot;The URI of the process.&quot;;
+
+ software(bool):
+ &quot;&quot;&quot;If true, this file is licensed under the conditions specified in
+ the *softwareLicense* field, otherwise under the conditions of the
+ *license* field. This field is only used to provide licensing
+ information (it does not matter whether the file really contains
+ software).&quot;&quot;&quot;;
+
+ description(freetext):
+ &quot;&quot;&quot;A (preferably short) description of the process in relation to the
+ object.&quot;&quot;&quot;;
+
+ }
+}
+
+</pre>
+<p>TODO include parsed and beautified version of that file instead of its raw
+source.</p>
+<p>Samples of additional properties that could be defined for a VisualDisplay:</p>
+<ul class="simple">
+<li>resolutionX (int)</li>
+<li>resolutionY (int)</li>
+<li>displayWidth (length)</li>
+<li>displayHeight (length)</li>
+</ul>
+<p>New object categories can be declared by defining a name and an URI for the
+category and by specifying the URI of a parent category (<em>Object</em> or a
+category derived from it) and a list of additional properties supported by
+the new category. Category declarations are given in the Type Declaration
+Language, cf. <tt class="docutils literal"><span class="pre">formats</span></tt>.</p>
+<p>The following basic types can be used for additional properties:</p>
+<pre class="literal-block">
+# The basic types that can be used for atomic fields. Types not defined
+# here are complex types, made up of several atomic or complex types.
+
+int: &quot;An integer number. External form: as in JSON.&quot;;
+
+float: &quot;A floating point number. External form: as in JSON.&quot;;
+
+bool: 'A Boolean value, either &quot;true&quot; or &quot;false&quot;.';
+
+string:
+ &quot;&quot;&quot;A string. Use this base type for free-form strings that are not meant
+ to be localized. Strings can contain arbitrary Unicode characters.&quot;&quot;&quot;;
+
+timestamp:
+ &quot;&quot;&quot;A point in time. External form: like the `YAML timestamp
+ &lt;http://yaml.org/type/timestamp.html&gt;`_ type.&quot;&quot;&quot;;
+
+identifier(string):
+ &quot;An identifier, made up of alphanumeric characters and underscores.&quot;;
+
+freetext(string):
+ &quot;Text that can be localized (translated in other languages).&quot;;
+
+formattedtext(freetext):
+ &quot;A longer block of text that can contain formatting.&quot;;
+
+file(string): &quot;A pointer to a file (stored externally).&quot;;
+
+# Unit types
+
+length(float): &quot;A length, measured by default in meter (m).&quot;;
+
+mass(float): &quot;A mass, measured by default in kilogram (kg).&quot;;
+
+</pre>
+<p>TODO include parsed and beautified version of that file instead of its raw
+source.</p>
+<p>All properties that require a unit come with a &quot;natural unit&quot; taken, when
+possible, from the <a class="reference external" href="http://en.wikipedia.org/wiki/International_System_of_Units">International System of Units</a> (meter,
+kilogram, second, ampere, degree Celsius, candela, joule, watt, volt,
+hertz, ohm, lumen etc.). Thus units need never be stored in the DB. The
+obvious exception is money, where a unit (e.g. USD or EUR) must be
+supplied.</p>
+<p>Additional properties can also be <em>complex types</em>, made up of several
+atomic or complex types. Examples of complex types are the <em>file</em> and
+<em>process</em> properties of the <em>Object</em> type. Complex types are declared in
+the same way as object categories (cf. <tt class="docutils literal"><span class="pre">formats</span></tt>).</p>
+</div>
+<div class="section" id="process-descriptions">
+<h2>Process Descriptions</h2>
+<p>Processes describe the life cycle of an object: how it and be built; how it
+can be used and what it can be used for; how it can be maintained,
+repaired, and modified; and how it can be dismantled and discarded or
+recycled when it has reached the end of its life cycle. Without processes,
+any object would be pretty useless.</p>
+<p>Each process description has the following elements:</p>
+<div class="section" id="metadata">
+<h3>Metadata</h3>
+<ul class="simple">
+<li><em>name:</em> an informal name and short summary of the process</li>
+<li><em>id:</em> a DI uniquely identifying the process. Tip: derive from the URI
+of the corresponding object (e.g.
+<tt class="docutils literal"><span class="pre">com.example.coffeemaker.buildit</span></tt> for the coffeemaker example above)</li>
+<li><em>description:</em> a description of the process</li>
+<li><em>authors:</em> list of the people which created/packaged the process
+(typically same as for the corresponding object)</li>
+<li><em>maintainers:</em> list of people to contact regarding questions about the
+process (typically same as for the corresponding object)</li>
+<li><em>last-modified:</em> timestamp showing when the process was last modified</li>
+<li><em>license:</em> the license under which the process is made available
+(typically same as for the corresponding object)</li>
+<li><em>files:</em> list of files associated with the process (same format as above)</li>
+</ul>
+</div>
+<div class="section" id="input">
+<h3>Input</h3>
+<p>Lists materials and components that are required for the process; including
+the amount or the number of instances required. Materials and objects
+listed here are used up or transformed during the process.</p>
+<p>Input requirements are probably listed using the TB query language, which
+might look like this:</p>
+<pre class="literal-block">
+object ? (type ~ SheetMetal &amp; material = Aluminum &amp; width = 1.5 &amp;
+ depth = 0.3 height = 0.003 &amp; copies = 12);
+material ? (type ~ ABS &amp; amount = 0.5);
+</pre>
+<p>(12 sheets made from aluminum or steel, size 150x30 cm, height between 3
+and 4 mm; and 0.5 kg of ABS plastic.)</p>
+<p>A name can be declared before the &quot;?&quot;, e.g. <tt class="docutils literal"><span class="pre">material</span> <span class="pre">&quot;MyMaterial&quot;</span> <span class="pre">?</span></tt>.
+The name used for referring to the object/material later in scripting,
+otherwise the category (e.g. &quot;SheetMetal&quot; or &quot;ABS&quot;) is used.</p>
+<p>The <a class="reference external" href="http://code.gustavonarea.net/booleano/">Booleano</a>-based query
+syntax is straightforward:</p>
+<ul class="simple">
+<li>Logical operators:<ul>
+<li>and: &amp;</li>
+<li>or: |</li>
+<li>not: !</li>
+</ul>
+</li>
+<li>Comparison operators:<ul>
+<li>Equal: = (or maybe ==)</li>
+<li>Not equal: !=</li>
+<li>Less/greater [or equal] than: &lt; &gt; &lt;= &gt;=</li>
+<li>&quot;Similarity&quot;: ~ . <tt class="docutils literal"><span class="pre">A</span> <span class="pre">~</span> <span class="pre">B</span></tt> means:<ul>
+<li>A is a subcategory of B, if A and B are categories</li>
+<li>A contains B as a substring (case-insensitive), if A and B are
+strings (similar to SQL LIKE)</li>
+<li>Maybe: abs(A-B) &lt; 0.01, if A and B are numbers (rough equality
+check)</li>
+<li>Undefined (error) otherwise</li>
+</ul>
+</li>
+</ul>
+</li>
+<li>Items are separated using <tt class="docutils literal"><span class="pre">;</span></tt> or <tt class="docutils literal"><span class="pre">&amp;</span></tt>, indicating that both are
+required; or using <tt class="docutils literal"><span class="pre">|</span></tt> indicating that one of the is required.</li>
+</ul>
+<p>Additional properties, not defined by the object category:</p>
+<ul class="simple">
+<li>copies (int): the number of instances required, for discrete items.
+Default is 1.</li>
+<li>amount (mass): the amount (in kilogram) required, for non-discrete items.
+No default value. Only one of <em>copies</em> or <em>amount</em> may be specified, but
+not both.</li>
+</ul>
+<p>The input requirements are often called &quot;bill of materials (BOM)&quot;, but they
+can contain materials <em>and</em> objects.</p>
+</div>
+<div class="section" id="tools">
+<h3>Tools</h3>
+<p>Lists tools and resources that are used in the process, but that aren't
+used up. Tools are listed in the same way as inputs, e.g.:</p>
+<pre class="literal-block">
+object ? (category ~ WaterHeater &amp; achievableHeat &gt;= 100
+ &amp; heatableVolume &gt;= 2);
+</pre>
+<p>(A water heater than can heat 2 liters of water (or more) to 100 degree
+Celsius (or more), required for ca. 15 minutes.)</p>
+<p>Additional property:</p>
+<ul class="simple">
+<li>time (time?): an estimate of the time for which the tool is
+required--useful e.g. for cost calculations if a tool is shared or rented
+on a temporal basis.</li>
+</ul>
+</div>
+<div class="section" id="constraints">
+<h3>Constraints</h3>
+<p>Lists conditions that must be true for the process to be performed as
+expected. Described in the same way as inputs, e.g.:</p>
+<pre class="literal-block">
+constraint ? (10 &lt;= EnvironmentTemperature &lt;= 35)
+</pre>
+<p>(The environmental temperature must be between 10 and 35 °C.)</p>
+<p>TODO Maybe, instead of constraints, define &quot;location requirements&quot;, making
+this a property of the location (the place where the process will be
+performed)?</p>
+<p>Implementation note: input, tools, and constraints can be stored as &quot;saved
+queries&quot; in the database.</p>
+</div>
+<div class="section" id="output">
+<h3>Output</h3>
+<p>The output describes the objects that will be created as a result of the
+process, if any. Output is specified in a simple declarative language,
+maybe (similar to the Kokompe language, but using &quot;:&quot; instead of &quot;:=&quot;):</p>
+<pre class="literal-block">
+object {
+ category: WaterBoiler;
+ achievableHeat: [60, 80, 90, 100]; # a list
+ heatableVolume: [0..3]; # a range
+ power: 700;
+ weight: 2.8;
+ width: 0.28;
+ depth: 0.2;
+ height: 0.29;
+}
+</pre>
+<p>(A water boiler that can heat up to 3 liters of water to 60, 80, 90, or 100
+°C, needs 700 W, weights 2.8 kg etc.)</p>
+<p>For processes that don't <em>create</em> any objects, but only repair, maintain,
+or use them, no output will be defined. Processes that dismantle objects
+should list the resulting remains or waste as output.</p>
+</div>
+<div class="section" id="operations">
+<h3>Operations</h3>
+<p>This is the core of the process: the list of operations to be performed as
+part of the process. Operations are partially ordered: some must be
+performed sequentially, others can be performed simultaneously or in
+arbitrary order.</p>
+<p>For each operation, there is an <em>agent</em> that should realize the
+operation--either one of the <em>tools</em> required for the process (or, in some
+cases, one of the <em>inputs</em> defined?), or a human.</p>
+<p>Operations will ofter refer to one <em>files</em> attached to the process: CNC
+router should execute the toolpath defined in file X, human should bolt the
+components together as shown in PDF file Y, etc.</p>
+<p>By default, operations are <em>sequential</em>, they must be executed in the
+defined order; alternatively, groups of operations can be marked as
+<em>parallel</em> which allows them to be executed in parallel or in arbitrary
+order. Groups of operations can also be <em>alternative</em> (do this or do that);
+they can also be <em>conditional</em> (if...then...else). Groups of operations can
+be <em>repeated</em> (while... block) for a certain number of times or until a
+certain condition is true.</p>
+<p>Here's an example of how the different kinds of grouping constructs could
+look like, using a simple block-based syntax and placeholders instead of
+actual operations:</p>
+<pre class="literal-block">
+parallel: # execute these operations in any order
+ Bla
+ Bla
+ Bla
+
+sequential: # You can use this inside a parallel block. Otherwise you
+ # won't need it, as all other blocks are sequential by
+ # default.
+ Bla
+ Bla
+ Bla
+
+alternative: # select one of those processes
+ Bla
+ Bla
+ Bla
+
+if *condition*:
+ Bla
+ Bla
+ Bla
+elif *another-condition*:
+else
+ Blub
+
+while *condition*:
+ Bla
+ Bla
+ Bla
+
+for i in [10..1], i + 1: # repeat 10 times (increasing the value of i)
+ Bla
+ Bla
+ Bla
+
+# The argument of a for loop is a list...
+for file in [fileA, fileB, fileC]: # do this for each of the 3 files
+ Bla
+ Bla
+
+# ...or a range...
+for i in [1..10]: # repeat 10 times (increasing the value of i)
+ Bla
+ Bla
+
+# ...with an optional step argument
+for i in [10..1] step -1: # repeat 10 times, counting downwards
+ Bla
+ Bla
+</pre>
+<p>The words &quot;parallel&quot;, &quot;sequential&quot;, &quot;alternative&quot;, &quot;if&quot;, &quot;elif&quot;, &quot;else&quot;,
+&quot;while&quot;, &quot;for&quot;, &quot;in&quot; are reserved keywords. &quot;step&quot; is not reserved as it
+can only be used after a range in a for loop, where variable names are not
+allowed, so there is no risk of confusion.</p>
+<p>TODO Describe how operations targeted at a human or at an object could be
+defined; how to define <em>conditions</em> either for automatic evaluation or as
+queries to a human.</p>
+</div>
+<div class="section" id="parameters">
+<h3>Parameters</h3>
+<p>It should be possible for process to accept <em>parameters</em> that influence the
+process--for example, if you built a chair, you can configure the exact
+length of the legs, specify whether it should have a cushion, select the
+color etc.</p>
+<p>For each parameter, the supported range or enumeration of values should be
+predefined; the user then chooses among the available options.</p>
+<p>The choice of parameter values can influence the other elements of the
+process--exact input requirements and output specification will depend on
+them; some of the operations will change to reflect to them; possibly, the
+tools required will change too.</p>
+<p>When storing options in the DB, the whole range or enum should be stored in
+order to be searchable (e.g. a chair that can be made in any color with
+legs between 35 cm and 80 cm should match a search for a red chair with 50
+cm legs.) That's more difficult for input/tool requirements, however (we
+can calculate and store how much material a 35 cm or a 80 cm chair would
+need, but we can't precalculate and store such information for <em>all</em>
+possible values). A possible, though imperfect solution would be to store
+such information for the <em>minimum</em> and <em>maximum</em> values of numeric
+parameters, and for a <em>default</em> value for enum parameters; and to calculate
+the exact values on demand.</p>
+<p>Example of declaring parameters:</p>
+<pre class="literal-block">
+# leg length is between 35 cm and 80 cm
+leg-length: [0.35..0.80];
+# six different colors are available
+color: [red, green, blue, yellow, black, white];
+</pre>
+<p>Example of selecting parameters--syntax is identical to the syntax used for
+defining inputs:</p>
+<pre class="literal-block">
+# we want a blue chair with 50 cm legs
+leg-length = 0.5 &amp; color = &quot;blue&quot;;
+</pre>
+</div>
+</div>
+<div class="section" id="object-database">
+<h2>Object Database</h2>
+<p>TODO Describe how objects and processes are stored in the DB.</p>
+</div>
+<div class="section" id="tangible-bit-object-description">
+<h2>Tangible Bit Object Description</h2>
+<p>The <em>Tangible Bit Object</em> file format (extension: <em>.tbob</em>) allows
+extracting objects with their relevant processes from the database and
+sharing them computers and users. A TBOB file can contain one or many
+objects with their relevant processes.</p>
+<p>A TBOB package is a ZIP file (like formats such as ODT and EPUB).</p>
+<p>First-level directories: the file contains one directory for objects and
+one for each type of processes it contains:</p>
+<pre class="literal-block">
+objects
+build
+setup
+use
+maintain
+repair
+replace
+</pre>
+<p>(Empty directories can be omitted.)</p>
+<p>Second-level directories: Each object and each process is stored in a
+subdirectory of the corresponding folder, using the object/process ID as
+directory name (e.g. <tt class="docutils literal"><span class="pre">objects/com.example.coffeemaker</span></tt>).</p>
+<p>TODO reverted from IDs to URIs since that's more user-friendly (allowing a
+web page to be shown). Explain how to convert URIs to directory names.</p>
+<p>Each object is represented by 3 simple plaintext (OGDL?) files:</p>
+<ul class="simple">
+<li>properties.og: contains the object properties</li>
+<li>processes.og: index of processes associated with the object</li>
+<li>files.og: index of files associated with the object</li>
+</ul>
+<p>Each process is represented by 5 simple plaintext (OGDL?) files:</p>
+<ul class="simple">
+<li>properties.og: contains the process metadata</li>
+<li>dependencies.og: lists the input, tools, and constraints required</li>
+<li>result.og: defines the output and the allowed parameter settings</li>
+<li>operations.og: defines the list of operations to be performed</li>
+<li>files.og: index of files associated with the process</li>
+</ul>
+<p>If an object or process contains files, they are stored in a third-level
+folder named <tt class="docutils literal"><span class="pre">files</span></tt>.</p>
+<p>TODO mimetype file?; internationalization/translated strings?</p>
+<p>Sample directory structure:</p>
+<pre class="literal-block">
+objects/
+ com.example.coffeemaker/
+ properties.og
+ processes.og
+ files.og
+ files/
+ thumbnail.gif
+ frontview.jpg
+build/
+ com.example.coffeemaker.buildit/
+ properties.og
+ dependencies.og
+ result.og
+ operations.og
+ files.og
+ files/
+ blueprint.iges
+</pre>
+<p>TODO Ensure that it's OK to package GPL'ed software with non-GPL'ed content
+in a single ZIP file (should be).</p>
+</div>
+<div class="section" id="to-do">
+<h2>To Do</h2>
+<ul class="simple">
+<li>Decide on syntax to use in <em>formattedtext</em> (Markdown or WikiCreole?).</li>
+<li>Write sample object package (Drawdio?) and tutorial/overview document on
+documenting and packing objects.</li>
+<li>Get in dialog with people creating and using free designs about what they
+need and whether our approach suits them.</li>
+<li>Document format of declarations (DecL language) and write parser; define
+literal form / parse expression of the <em>basetypes</em>.</li>
+<li>Write database generator that reads the type declarations and creates or
+updates the database scheme accordingly.</li>
+<li>Define and publish controlled vocabulary of recommended license names and
+of the roles of files.</li>
+<li>See TODOs above.</li>
+</ul>
+</div>
+</div>
+</body>
+</html>
diff --git a/doc/objects.rst b/doc/objects.rst
new file mode 100644
index 0000000..36042d2
--- /dev/null
+++ b/doc/objects.rst
@@ -0,0 +1,435 @@
+==========================
+Tangible Bit Object System
+==========================
+
+The Tangible Bit Object System (TBOS) describes physical objects. It
+contains including detailed and automatically processable on how they can
+be build, how they can be used, and what they can be used for. The TBOS
+takes care of the entire life cycle of an object, including information on
+maintenance, part replacement, and repair, and disassembly.
+
+Each object has *properties* that describe the object. Each object is
+associated with *processes* that describe how the object can be build,
+used, maintained, repaired, modified, or dismantled.
+
+Object Descriptions
+~~~~~~~~~~~~~~~~~~~
+
+The most important property of each object are its *categories* (types).
+This allows placing all objects in a type hierarchy. Each category extends
+another category, the most general object category is *Object*; each object
+is an instance of one or several category (we allow multiple inheritance
+here). The hierarchy of object categories, as known to Tangible Bit, is
+stored in ``doc/object_categories.txt`` (TODO should be formalized and
+moved outside the ``doc`` directory; it should be possible to just refer to
+categories by URI to remove the dependency on a single authority). The
+object category also specified which other properties the object has.
+
+The properties of the *Object* category, which are shared by all objects,
+are as follows:
+
+.. include:: ../data/types/object.decl
+ :literal:
+
+TODO include parsed and beautified version of that file instead of its raw
+source.
+
+Samples of additional properties that could be defined for a VisualDisplay:
+
+- resolutionX (int)
+- resolutionY (int)
+- displayWidth (length)
+- displayHeight (length)
+
+New object categories can be declared by defining a name and an URI for the
+category and by specifying the URI of a parent category (*Object* or a
+category derived from it) and a list of additional properties supported by
+the new category. Category declarations are given in the Type Declaration
+Language, cf. ``formats``.
+
+The following basic types can be used for additional properties:
+
+.. include:: ../data/types/basetypes.decl
+ :literal:
+
+TODO include parsed and beautified version of that file instead of its raw
+source.
+
+All properties that require a unit come with a "natural unit" taken, when
+possible, from the `International System of Units
+<http://en.wikipedia.org/wiki/International_System_of_Units>`_ (meter,
+kilogram, second, ampere, degree Celsius, candela, joule, watt, volt,
+hertz, ohm, lumen etc.). Thus units need never be stored in the DB. The
+obvious exception is money, where a unit (e.g. USD or EUR) must be
+supplied.
+
+Additional properties can also be *complex types*, made up of several
+atomic or complex types. Examples of complex types are the *file* and
+*process* properties of the *Object* type. Complex types are declared in
+the same way as object categories (cf. ``formats``).
+
+Process Descriptions
+~~~~~~~~~~~~~~~~~~~~
+
+Processes describe the life cycle of an object: how it and be built; how it
+can be used and what it can be used for; how it can be maintained,
+repaired, and modified; and how it can be dismantled and discarded or
+recycled when it has reached the end of its life cycle. Without processes,
+any object would be pretty useless.
+
+Each process description has the following elements:
+
+Metadata
+++++++++
+
+* *name:* an informal name and short summary of the process
+* *id:* a DI uniquely identifying the process. Tip: derive from the URI
+ of the corresponding object (e.g.
+ ``com.example.coffeemaker.buildit`` for the coffeemaker example above)
+* *description:* a description of the process
+* *authors:* list of the people which created/packaged the process
+ (typically same as for the corresponding object)
+* *maintainers:* list of people to contact regarding questions about the
+ process (typically same as for the corresponding object)
+* *last-modified:* timestamp showing when the process was last modified
+* *license:* the license under which the process is made available
+ (typically same as for the corresponding object)
+* *files:* list of files associated with the process (same format as above)
+
+Input
++++++
+
+Lists materials and components that are required for the process; including
+the amount or the number of instances required. Materials and objects
+listed here are used up or transformed during the process.
+
+Input requirements are probably listed using the TB query language, which
+might look like this::
+
+ object ? (type ~ SheetMetal & material = Aluminum & width = 1.5 &
+ depth = 0.3 height = 0.003 & copies = 12);
+ material ? (type ~ ABS & amount = 0.5);
+
+(12 sheets made from aluminum or steel, size 150x30 cm, height between 3
+and 4 mm; and 0.5 kg of ABS plastic.)
+
+A name can be declared before the "?", e.g. ``material "MyMaterial" ?``.
+The name used for referring to the object/material later in scripting,
+otherwise the category (e.g. "SheetMetal" or "ABS") is used.
+
+The `Booleano <http://code.gustavonarea.net/booleano/>`_\ -based query
+syntax is straightforward:
+
+* Logical operators:
+
+ * and: &
+ * or: |
+ * not: !
+
+* Comparison operators:
+
+ * Equal: = (or maybe ==)
+ * Not equal: !=
+ * Less/greater [or equal] than: < > <= >=
+ * "Similarity": ~ . ``A ~ B`` means:
+
+ * A is a subcategory of B, if A and B are categories
+ * A contains B as a substring (case-insensitive), if A and B are
+ strings (similar to SQL LIKE)
+ * Maybe: abs(A-B) < 0.01, if A and B are numbers (rough equality
+ check)
+ * Undefined (error) otherwise
+
+* Items are separated using ``;`` or ``&``, indicating that both are
+ required; or using ``|`` indicating that one of the is required.
+
+Additional properties, not defined by the object category:
+
+* copies (int): the number of instances required, for discrete items.
+ Default is 1.
+* amount (mass): the amount (in kilogram) required, for non-discrete items.
+ No default value. Only one of *copies* or *amount* may be specified, but
+ not both.
+
+The input requirements are often called "bill of materials (BOM)", but they
+can contain materials *and* objects.
+
+Tools
++++++
+
+Lists tools and resources that are used in the process, but that aren't
+used up. Tools are listed in the same way as inputs, e.g.::
+
+ object ? (category ~ WaterHeater & achievableHeat >= 100
+ & heatableVolume >= 2);
+
+(A water heater than can heat 2 liters of water (or more) to 100 degree
+Celsius (or more), required for ca. 15 minutes.)
+
+Additional property:
+
+* time (time?): an estimate of the time for which the tool is
+ required--useful e.g. for cost calculations if a tool is shared or rented
+ on a temporal basis.
+
+Constraints
++++++++++++
+
+Lists conditions that must be true for the process to be performed as
+expected. Described in the same way as inputs, e.g.::
+
+ constraint ? (10 <= EnvironmentTemperature <= 35)
+
+(The environmental temperature must be between 10 and 35 °C.)
+
+TODO Maybe, instead of constraints, define "location requirements", making
+this a property of the location (the place where the process will be
+performed)?
+
+Implementation note: input, tools, and constraints can be stored as "saved
+queries" in the database.
+
+Output
+++++++
+
+The output describes the objects that will be created as a result of the
+process, if any. Output is specified in a simple declarative language,
+maybe (similar to the Kokompe language, but using ":" instead of ":=")::
+
+ object {
+ category: WaterBoiler;
+ achievableHeat: [60, 80, 90, 100]; # a list
+ heatableVolume: [0..3]; # a range
+ power: 700;
+ weight: 2.8;
+ width: 0.28;
+ depth: 0.2;
+ height: 0.29;
+ }
+
+(A water boiler that can heat up to 3 liters of water to 60, 80, 90, or 100
+°C, needs 700 W, weights 2.8 kg etc.)
+
+For processes that don't *create* any objects, but only repair, maintain,
+or use them, no output will be defined. Processes that dismantle objects
+should list the resulting remains or waste as output.
+
+Operations
+++++++++++
+
+This is the core of the process: the list of operations to be performed as
+part of the process. Operations are partially ordered: some must be
+performed sequentially, others can be performed simultaneously or in
+arbitrary order.
+
+For each operation, there is an *agent* that should realize the
+operation--either one of the *tools* required for the process (or, in some
+cases, one of the *inputs* defined?), or a human.
+
+Operations will ofter refer to one *files* attached to the process: CNC
+router should execute the toolpath defined in file X, human should bolt the
+components together as shown in PDF file Y, etc.
+
+By default, operations are *sequential*, they must be executed in the
+defined order; alternatively, groups of operations can be marked as
+*parallel* which allows them to be executed in parallel or in arbitrary
+order. Groups of operations can also be *alternative* (do this or do that);
+they can also be *conditional* (if...then...else). Groups of operations can
+be *repeated* (while... block) for a certain number of times or until a
+certain condition is true.
+
+Here's an example of how the different kinds of grouping constructs could
+look like, using a simple block-based syntax and placeholders instead of
+actual operations::
+
+ parallel: # execute these operations in any order
+ Bla
+ Bla
+ Bla
+
+ sequential: # You can use this inside a parallel block. Otherwise you
+ # won't need it, as all other blocks are sequential by
+ # default.
+ Bla
+ Bla
+ Bla
+
+ alternative: # select one of those processes
+ Bla
+ Bla
+ Bla
+
+ if *condition*:
+ Bla
+ Bla
+ Bla
+ elif *another-condition*:
+ else
+ Blub
+
+ while *condition*:
+ Bla
+ Bla
+ Bla
+
+ for i in [10..1], i + 1: # repeat 10 times (increasing the value of i)
+ Bla
+ Bla
+ Bla
+
+ # The argument of a for loop is a list...
+ for file in [fileA, fileB, fileC]: # do this for each of the 3 files
+ Bla
+ Bla
+
+ # ...or a range...
+ for i in [1..10]: # repeat 10 times (increasing the value of i)
+ Bla
+ Bla
+
+ # ...with an optional step argument
+ for i in [10..1] step -1: # repeat 10 times, counting downwards
+ Bla
+ Bla
+
+The words "parallel", "sequential", "alternative", "if", "elif", "else",
+"while", "for", "in" are reserved keywords. "step" is not reserved as it
+can only be used after a range in a for loop, where variable names are not
+allowed, so there is no risk of confusion.
+
+TODO Describe how operations targeted at a human or at an object could be
+defined; how to define *conditions* either for automatic evaluation or as
+queries to a human.
+
+Parameters
+++++++++++
+
+It should be possible for process to accept *parameters* that influence the
+process--for example, if you built a chair, you can configure the exact
+length of the legs, specify whether it should have a cushion, select the
+color etc.
+
+For each parameter, the supported range or enumeration of values should be
+predefined; the user then chooses among the available options.
+
+The choice of parameter values can influence the other elements of the
+process--exact input requirements and output specification will depend on
+them; some of the operations will change to reflect to them; possibly, the
+tools required will change too.
+
+When storing options in the DB, the whole range or enum should be stored in
+order to be searchable (e.g. a chair that can be made in any color with
+legs between 35 cm and 80 cm should match a search for a red chair with 50
+cm legs.) That's more difficult for input/tool requirements, however (we
+can calculate and store how much material a 35 cm or a 80 cm chair would
+need, but we can't precalculate and store such information for *all*
+possible values). A possible, though imperfect solution would be to store
+such information for the *minimum* and *maximum* values of numeric
+parameters, and for a *default* value for enum parameters; and to calculate
+the exact values on demand.
+
+Example of declaring parameters::
+
+ # leg length is between 35 cm and 80 cm
+ leg-length: [0.35..0.80];
+ # six different colors are available
+ color: [red, green, blue, yellow, black, white];
+
+Example of selecting parameters--syntax is identical to the syntax used for
+defining inputs::
+
+ # we want a blue chair with 50 cm legs
+ leg-length = 0.5 & color = "blue";
+
+Object Database
+~~~~~~~~~~~~~~~
+
+TODO Describe how objects and processes are stored in the DB.
+
+Tangible Bit Object Description
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The *Tangible Bit Object* file format (extension: *.tbob*) allows
+extracting objects with their relevant processes from the database and
+sharing them computers and users. A TBOB file can contain one or many
+objects with their relevant processes.
+
+A TBOB package is a ZIP file (like formats such as ODT and EPUB).
+
+First-level directories: the file contains one directory for objects and
+one for each type of processes it contains::
+
+ objects
+ build
+ setup
+ use
+ maintain
+ repair
+ replace
+
+(Empty directories can be omitted.)
+
+Second-level directories: Each object and each process is stored in a
+subdirectory of the corresponding folder, using the object/process ID as
+directory name (e.g. ``objects/com.example.coffeemaker``).
+
+TODO reverted from IDs to URIs since that's more user-friendly (allowing a
+web page to be shown). Explain how to convert URIs to directory names.
+
+Each object is represented by 3 simple plaintext (OGDL?) files:
+
+- properties.og: contains the object properties
+- processes.og: index of processes associated with the object
+- files.og: index of files associated with the object
+
+Each process is represented by 5 simple plaintext (OGDL?) files:
+
+- properties.og: contains the process metadata
+- dependencies.og: lists the input, tools, and constraints required
+- result.og: defines the output and the allowed parameter settings
+- operations.og: defines the list of operations to be performed
+- files.og: index of files associated with the process
+
+If an object or process contains files, they are stored in a third-level
+folder named ``files``.
+
+TODO mimetype file?; internationalization/translated strings?
+
+Sample directory structure::
+
+ objects/
+ com.example.coffeemaker/
+ properties.og
+ processes.og
+ files.og
+ files/
+ thumbnail.gif
+ frontview.jpg
+ build/
+ com.example.coffeemaker.buildit/
+ properties.og
+ dependencies.og
+ result.og
+ operations.og
+ files.og
+ files/
+ blueprint.iges
+
+TODO Ensure that it's OK to package GPL'ed software with non-GPL'ed content
+in a single ZIP file (should be).
+
+To Do
+~~~~~
+
+* Decide on syntax to use in *formattedtext* (Markdown or WikiCreole?).
+* Write sample object package (Drawdio?) and tutorial/overview document on
+ documenting and packing objects.
+* Get in dialog with people creating and using free designs about what they
+ need and whether our approach suits them.
+* Document format of declarations (DecL language) and write parser; define
+ literal form / parse expression of the *basetypes*.
+* Write database generator that reads the type declarations and creates or
+ updates the database scheme accordingly.
+* Define and publish controlled vocabulary of recommended license names and
+ of the roles of files.
+* See TODOs above.
diff --git a/doc/tb.rst b/doc/tb.rst
index 7c5f138..706cf3f 100644
--- a/doc/tb.rst
+++ b/doc/tb.rst
@@ -147,6 +147,10 @@ Current database layout:
Here we need input regarding the design, structure, and contents of the materials science database.
+Object System
+~~~~~~~~~~~~~
+
+See ``objects.rst``.
Industrial Capacity Mapping
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -163,4 +167,12 @@ Inventory Manager
Inventory Management tool info.
+Formats and Languages
+~~~~~~~~~~~~~~~~~~~~~
+
+See ``formats.rst``.
+
+Coding Style & Development Notes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+See ``dev.rst``.
diff --git a/server/locations/views.py b/server/locations/views.py
index 7f5e730..f509c7a 100644
--- a/server/locations/views.py
+++ b/server/locations/views.py
@@ -4,6 +4,7 @@ from locations.models import *
from locations.xmlrpc import *
from django.http import HttpResponse
from django.contrib.auth.models import User
+from django.db.models import Q
import simplejson
import time
@@ -22,10 +23,30 @@ def search(request):
query = request.GET['q']
if not query or query == "":
- return HttpResonse(simplejson.encode(GetLocationList()))
+ return HttpResponse(simplejson.encode(GetLocationList()))
else:
- # FIXME: This isn't actually a real search function at the moment.
- return HttpResonse(simplejson.encode(GetLocationList()))
+ q = Q()
+ for qs in query.split(" "):
+ q &= Q(name__contains=qs) | Q(locname__contains=qs)
+
+ try:
+ locations = Location.objects.get(q)
+ except:
+ return HttpResponse("[]")
+
+ results = []
+
+ for location in locations:
+ results.append({
+ 'id': location.id,
+ 'lat': location.lat,
+ 'lon': location.lon,
+ 'name': location.name,
+ 'city': location.locname,
+ 'website': location.website
+ })
+
+ return HttpResponse(simplejson.encode(results))
def setlocation(request):
if not request.has_key('locationid'):
diff --git a/server/locations/xmlrpc.py b/server/locations/xmlrpc.py
index c2ec2f2..5d22bdf 100644
--- a/server/locations/xmlrpc.py
+++ b/server/locations/xmlrpc.py
@@ -12,7 +12,14 @@ def GetLocationList():
results = []
for location in locations:
- results.append({ 'id': location.id, 'lat': location.lat, 'lon': location.lon, 'name': location.name, 'locname': location.locname, 'weblocation': location.website})
+ results.append({
+ 'id': location.id,
+ 'lat': location.lat,
+ 'lon': location.lon,
+ 'name': location.name,
+ 'locname': location.locname,
+ 'website': location.website
+ })
return results
diff --git a/server/objects/models.py b/server/objects/models.py
index fdb0062..a9471a3 100644
--- a/server/objects/models.py
+++ b/server/objects/models.py
@@ -25,6 +25,13 @@ class Object(models.Model):
files = models.ManyToManyField(ObjectFile)
+class Product(models.Model):
+ # To map product codes (EAN, UPC,...) to objects.
+ code = models.CharField(max_length=18, primary_key=True)
+ name = models.CharField(max_length=200)
+ object = models.ForeignKey(Object, blank=True, null=True)
+
+
class Intangible(models.Model):
# TODO: Define me!
# Heat, pressure, electricity, manpower,...
@@ -40,4 +47,5 @@ class ObjectSearchForm(ModelForm):
model = Object
+
admin.site.register(Object)
diff --git a/server/objects/views.py b/server/objects/views.py
index 524ba08..cdf45d3 100644
--- a/server/objects/views.py
+++ b/server/objects/views.py
@@ -1,8 +1,27 @@
+from django.http import HttpResponse
from django.shortcuts import render_to_response
from objects.models import *
+import simplejson
def index(request):
objsearchform = ObjectSearchForm(auto_id="catalogsearch")
return render_to_response("objects/index.html", {"catalogsearch": objsearchform, "user": request.user})
+def ean_lookup(request):
+ query = request.GET["q"].split(",")
+
+ try:
+ results = Product.objects.filter(code__in=query)
+ products = []
+
+ for r in results:
+ products.append({
+ 'code': r.code,
+ 'name': r.name
+ })
+
+ return HttpResponse(simplejson.encode(products))
+ except Exception as e:
+ print e
+ return HttpResponse("[]")
diff --git a/server/urls.py b/server/urls.py
index 375b0fa..ab694ab 100644
--- a/server/urls.py
+++ b/server/urls.py
@@ -32,6 +32,7 @@ urlpatterns = patterns('',
(r'^materials/tradenames$', 'materials.views.manufacturers'),
(r'^objects/$', 'objects.views.index'),
+ (r'^objects/ean_lookup$', 'objects.views.ean_lookup'),
(r'^xml/location', 'locations.views.locationtoxml'),
(r'^yaml/location', 'locations.views.locationtoyaml'),