| .. Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| |
| Platform Tour |
| ================= |
| |
| Introduction |
| --------------- |
| |
| Allura is implemented as a collection of tool applications on top of a |
| robust and open platform. Some of the services provided by the platform include: |
| |
| - Indexing and search |
| - Authentication and Authorization |
| - Email integration (every tool application gets its own email address) |
| - Asynchronous processing with background tasks and events |
| - `Markdown <http://daringfireball.net/projects/markdown/>`_ markup formatting |
| - Simple autolinking between different artifacts in the forge |
| - Attachment handling |
| - Tool administration |
| |
| Tools, on the other hand, provide the actual user interface and logic to |
| manipulate forge artifacts. Some of the tools currently implemented include: |
| |
| admin |
| This tool is installed in all projects, and allows the administration of the |
| project's tools, authentication, and authorization |
| Git, Hg, SVN |
| These tools allow you to host a version control system in Allura. |
| They also provides the ability to "fork" Git and Hg repos in order to |
| provide your own extensions. |
| Wiki |
| This tool provides a basic wiki with support for comments, attachments, and |
| notifications. |
| Tracker |
| This tool provides an extensible ticketing system for tracking feature |
| requests, defects, or support requests. |
| Discussion |
| This tool provides a forum interface with full email integration as well. |
| The forum also handles attachments to posts either via the web interface or via email. |
| |
| The Context Object |
| --------------------------------------------------- |
| |
| The Pylons "context" object `c` has several properties which are automatically |
| set for each request: |
| |
| project |
| The current project |
| app |
| The current tool application object. |
| user |
| The current user |
| |
| Allura platform provides the following functions to manage the context object, |
| if you need to change the context for some situation: |
| |
| .. function:: allura.lib.helpers.push_config(obj, **kw) |
| :noindex: |
| |
| Context manager (used with the `with` statement) used to temporarily set the |
| attributes of a particular object, resetting them to their previous values |
| at the end of the `with` block. Used most frequently with the context object |
| `c`:: |
| |
| c.project = some_project |
| with push_config(c, project=other_project): |
| ... |
| # code in this block will have c.project == other_project |
| # code here will have c.project == some_project |
| |
| .. function:: allura.lib.helpers.set_context(project_id, mount_point=None, app_config_id=None) |
| :noindex: |
| |
| Set the context object `c` according to the given `project_id` and optionally either a |
| `mount_point`, an `app_config_id`. `c.project` is set to the corresponding |
| project object. If the mount_point or app_config_id is |
| specified, then `c.app` will be set to the corresponding tool application |
| object. |
| |
| |
| Artifacts |
| ------------- |
| |
| We've mentioned artifacts a couple of times now without definition. An artifact, |
| as used in Allura, is some object that a tool needs to store in the |
| forge. The platform provides facilities for controlling access to individual |
| artifacts if that's what the tool designer favors. For instance, the Discussion |
| tool allows a user to edit or delete their own posts, but not to edit or delete |
| others (unless the user has the 'moderate' permission on the forum itself). |
| Some examples of artifacts in the current tools: |
| |
| - Discussion: Forum, Thread, Post, Attachment |
| - Wiki: Page, Comment, Attachment |
| - Tracker: Ticket, Comment, Attachment |
| - SCM: Repository, Commit, Patch |
| |
| In order to implement your own artifact, you should override at least a few of |
| the methods of the `allura.model.artifact.Artifact` class:: |
| |
| from ming.orm.property import FieldProperty |
| from allura.model import Artifact |
| |
| class NewArtifact(Artifact): |
| class __mongometa__: |
| name='my_new_artifact' # collection where this artifact is stored |
| type_s = 'My Artifact' # 'type' of the artifact used in search results |
| |
| # Add your own properties here (beyond those provided by Artifact) |
| shortname = FieldProperty(str) |
| |
| def url(self): |
| 'Each artifact should have its own URL ' |
| return self.app.url + self.shortname + '/' |
| |
| def index(self): |
| 'Return the fields you want indexed on this artifact' |
| result = Artifact.index(self) |
| result.update(type_s=self.type_s, |
| name_s=self.shortname, |
| text=self.shortname) |
| return result |
| |
| def shorthand_id(self): |
| 'Used in the generation of short links like [my_artifact]' |
| return self.shortname |
| |
| Platform services provided for artifacts |
| --------------------------------------------------- |
| |
| Whenever you create, modify, or delete an artifact, the platform does a couple of |
| things for you: |
| |
| - The artifact is added to the index and will appear in searches |
| - A shortlink is generated for the artifact (e.g. [MyWikiPage] or [#151]). This allows you |
| to reference the artifact from other artifacts. Whenever the commit message |
| is displayed in the SCM tool, any references to `[#151]` will be |
| automatically linked to that Ticket's page. |
| |
| Shortlinks work only within a project hierarchy (in order to link to some other project's |
| page, you'll have to use the full URL). Sometimes, a shortlink may need to be |
| differentiated based on its location in a subproject or in one of many tools of |
| the same type within a project. In order to do this, shortlinks may be prefixed |
| by either the tool mount point or a project ID and tool mount point. |
| |
| For instance, suppose we have an ticket tracker called 'features' and one called 'bugs'. |
| They both have many tickets in them. To distinguish, use the tracker mount point |
| within the reference. For example [features:#3] or [bugs:#3] |
| |
| Asynchronous Processing |
| ----------------------------------------- |
| |
| Much of the actual functionality of Allura comes from code that runs |
| *outside* the context of a web request, in the `taskd` server (invoked by |
| running `paster taskd development.ini`. Asynchronous processing is performed |
| by two types of functions, *tasks* and *events*, differentiated as follows: |
| |
| Task |
| Tasks are module-level global functions. They are annotated with the `@task` |
| decorator and are invoked with the `.post` method. For instance, to schedule |
| a task `foobar` to execute in the `taskd` context, you would write:: |
| |
| @task |
| def foobar(a,b,c=5): ... |
| |
| foobar.post(9,1,c=15) |
| |
| Event |
| Events are intended for "fan-out" types of events. Events have a string |
| name, and are "listened" for by using the `@event_handler` decorator. The |
| `g.post_event()` helper is provided to run the event handlers for a |
| particular event in the `taskd` context. Multiple event handlers can be |
| registered for each event:: |
| |
| @event_handler('event_name') |
| def handler1(topic, *args, **kwargs): ... |
| |
| @event_handler('event_name') |
| def handler2(topic, *args, **kwargs): ... |
| |
| g.post_event('event_name', 1,2,3, a=5) |
| |
| |
| Email Integration |
| ----------------------------------------- |
| |
| The Allura platform provides easy-to-use email integration. Forge email addresses |
| are of the form |
| <topic>@<mount_point>[.<subproject>]*.<subproject>.projects.sourceforge.net. |
| When a message is received on such an email address, the address is parsed and |
| the sending user is identified (if possible). Based on the parsed address, the |
| pylons context attributes `c.project` and `c.app` are set, and the application is |
| queried to determine whether the identified user has authority to send an email |
| to the given app/topic combination by calling `c.app.has_access(user, topic)`. |
| If the user has access, the message is decomposed into its component parts (if a |
| multipart MIME-encoded message) and `c.app.handle_message(topic, message)` is |
| called for each part with the following components to the `msg` dict: |
| |
| headers |
| The actual headers parsed from the body of the message |
| message_id |
| The `Message-ID` header (which should be universally |
| unique and is |
| generated by the email client), used for determining which messages are replies |
| to which other messages |
| in_reply_to |
| The `In-Reply-To` header, used for determining which messages are replies to |
| which other messages |
| references |
| The `References` header, used for determining which messages refer to |
| which other messages |
| filename |
| Optional, if the part is an attachment with a filename, this will be populated |
| content_type |
| The MIME content_type of the message part |
| payload |
| The actual content of the message part |
| |
| The Allura platform also provides full support for *sending* email without |
| worrying about the specifics of SMTP or sendmail handling. In order to send an |
| email, simply post a task for `allura.tasks.mail_tasks.sendmail` with the |
| following arguments: |
| |
| fromaddr |
| Return address on the message (usually the topic@tool_name that generated |
| it) |
| destinations |
| List of email addresses and/or :class:`bson.ObjectId` s for |
| :class:`allura.model.auth.User` objects |
| text |
| Markdown-formatted body of the message (If the user has requested html or |
| combined text+html messages in their preferences, the Markdown will be so |
| rendered. Otherwise a plain text message will be sent.) |
| reply_to |
| Address to which replies should be sent |
| subject |
| Subject of the message |
| message_id |
| Value to put in the `Message-ID` header (the `_id` field of a |
| :class:`allura.model.artifact.Message` is suitable for this) |
| in_reply_to (optional) |
| Value to put in the `In-Reply-To` header (the `parent_id` field of a |
| :class:`allura.model.artifact.Message` is suitable for this) |