source: telemeta/urls.py @ c676291

cremcrem2crem3devdev2diademsdj1.6feature/breadcrumbsfeature/ts-0.5feature/ts-0.5.4feature/writecachegenericinstru_searchlamlam2mapsv3mergenlivemultiprobproductionrelease/1.4.4sabiodsearchsecurityserversocialstoragetelecastertest
Last change on this file since c676291 was c676291, checked in by yomguy <yomguy@…>, 3 years ago

fix accounts

  • Property mode set to 100644
File size: 21.0 KB
Line 
1# -*- coding: utf-8 -*-
2# Copyright (C) 2007 Samalyse SARL
3# Copyright (c) 2007-2011 Parisson SARL
4
5# This software is a computer program whose purpose is to backup, analyse,
6# transcode and stream any audio content with its metadata over a web frontend.
7
8# This software is governed by the CeCILL  license under French law and
9# abiding by the rules of distribution of free software.  You can  use,
10# modify and/ or redistribute the software under the terms of the CeCILL
11# license as circulated by CEA, CNRS and INRIA at the following URL
12# "http://www.cecill.info".
13
14# As a counterpart to the access to the source code and  rights to copy,
15# modify and redistribute granted by the license, users are provided only
16# with a limited warranty  and the software's author,  the holder of the
17# economic rights,  and the successive licensors  have only  limited
18# liability.
19
20# In this respect, the user's attention is drawn to the risks associated
21# with loading,  using,  modifying and/or developing or reproducing the
22# software by the user in light of its specific status of free software,
23# that may mean  that it is complicated to manipulate,  and  that  also
24# therefore means  that it is reserved for developers  and  experienced
25# professionals having in-depth computer knowledge. Users are therefore
26# encouraged to load and test the software's suitability as regards their
27# requirements in conditions enabling the security of their systems and/or
28# data to be ensured and,  more generally, to use and operate it in the
29# same conditions as regards security.
30
31# The fact that you are presently reading this means that you have had
32# knowledge of the CeCILL license and that you accept its terms.
33#
34# Authors: Olivier Guilyardi <olivier@samalyse.com>
35#          Guillaume Pellerin <yomguy@parisson.com>
36
37from django.conf.urls.defaults import *
38from django.conf import settings
39from django.views.generic.simple import redirect_to
40from telemeta.models import MediaItem, MediaCollection, MediaItemMarker, MediaCorpus, MediaFonds
41from telemeta.views.base import GeneralView, AdminView, CollectionView, ItemView, \
42                                InstrumentView, PlaylistView, ProfileView, GeoView, \
43                                LastestRevisionsFeed, ResourceView, UserRevisionsFeed
44from jsonrpc import jsonrpc_site
45import os.path
46import telemeta.config
47
48telemeta.config.check()
49
50# initialization
51general_view = GeneralView()
52admin_view = AdminView()
53collection_view = CollectionView()
54item_view = ItemView()
55instrument_view = InstrumentView()
56playlist_view = PlaylistView()
57profile_view = ProfileView()
58geo_view = GeoView()
59resource_view = ResourceView()
60
61# query sets for Django generic views
62all_items = { 'queryset': MediaItem.objects.enriched().order_by('code', 'old_code') }
63all_items_sound = { 'queryset': MediaItem.objects.sound().order_by('code', 'old_code') }
64all_collections = { 'queryset': MediaCollection.objects.enriched(), }
65all_collections_unpublished = { 'queryset': MediaCollection.objects.filter(code__contains='_I_'), }
66all_collections_published = { 'queryset': MediaCollection.objects.filter(code__contains='_E_'), }
67all_collections_sound = { 'queryset': MediaCollection.objects.sound().order_by('code', 'old_code') }
68all_corpus = { 'queryset': MediaCorpus.objects.all().order_by('title') }
69all_fonds = { 'queryset': MediaFonds.objects.all().order_by('title') }
70
71# ID's regular expressions
72export_extensions = "|".join(item_view.list_export_extensions())
73
74htdocs = os.path.dirname(__file__) + '/htdocs'
75
76urlpatterns = patterns('',
77    url(r'^$', general_view.home, name="telemeta-home"),
78
79    # items
80    url(r'^archives/items/$', 'django.views.generic.list_detail.object_list',
81        dict(all_items, paginate_by=20, template_name="telemeta/mediaitem_list.html"),
82        name="telemeta-items"),
83    url(r'^archives/items_sound/$', 'django.views.generic.list_detail.object_list',
84        dict(all_items_sound, paginate_by=20, template_name="telemeta/mediaitem_list.html"), name="telemeta-items-sound"),
85    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/$', item_view.item_detail,
86        name="telemeta-item-detail"),
87    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/dc/$', item_view.item_detail,
88        {'template': 'telemeta/mediaitem_detail_dc.html'},
89        name="telemeta-item-dublincore"),
90    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/dc/xml/$', item_view.item_detail,
91        {'format': 'dublin_core_xml'},
92        name="telemeta-item-dublincore-xml"),
93    url(r'^archives/items/download/(?P<public_id>[A-Za-z0-9._-]+)\.(?P<extension>'
94            + export_extensions + ')$',
95        item_view.item_export,
96        name="telemeta-item-export"),
97    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/visualize/(?P<visualizer_id>[0-9a-z_]+)/(?P<width>[0-9A-Z]+)x(?P<height>[0-9A-Z]+)/$',
98        item_view.item_visualize,
99        name="telemeta-item-visualize"),
100    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/analyze/xml/$',
101        item_view.item_analyze_xml,
102        name="telemeta-item-analyze-xml"),
103    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/item_xspf.xml$',
104        item_view.item_playlist,
105        dict(template="telemeta/mediaitem_xspf.xml", mimetype="application/xspf+xml"),
106        name="telemeta-item-xspf"),
107    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/edit/$', item_view.item_edit,
108        dict(template='telemeta/mediaitem_edit.html'), name="telemeta-item-edit"),
109    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/copy/$', item_view.item_copy,
110        dict(template='telemeta/mediaitem_copy.html'), name="telemeta-item-copy"),
111    url(r'^archives/item_new/add/$', item_view.item_add,
112        dict(template='telemeta/mediaitem_add.html'), name="telemeta-item-add"),
113    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/player/(?P<width>[0-9]+)x(?P<height>[0-9]+)/$', item_view.item_detail,
114        dict(template='telemeta/mediaitem_player.html'), name="telemeta-item-player"),
115    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/player/(?P<width>[0-9]+)x(?P<height>[0-9]+)/simple/$', item_view.item_detail,
116        dict(template='telemeta/mediaitem_player_simple.html'), name="telemeta-item-player-simple"),
117    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/performances/$', item_view.item_performances_edit,
118        dict(template='telemeta/mediaitem_performances_edit.html'), name="telemeta-item-performances_edit"),
119    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/keywords/$', item_view.item_keywords_edit,
120        dict(template='telemeta/mediaitem_keywords_edit.html'), name="telemeta-item-keywords_edit"),
121    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/delete/$', item_view.item_delete, name="telemeta-item-delete"),
122    url(r'^archives/items/(?P<item_public_id>[A-Za-z0-9._-]+)/related/(?P<media_id>[A-Za-z0-9._-]+)$', item_view.related_media_item_stream, name="telemeta-item-related"),
123    url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/related_edit/$', item_view.related_media_edit,  dict(template='telemeta/mediaitem_related_edit.html'), name="telemeta-item-related_edit"),
124    # Markers
125    url(r'^markers/(?P<marker_id>[A-Za-z0-9]+)/$', item_view.item_detail, name="telemeta-item-detail-marker"),
126    # FIXME: need all paths
127    url(r'^items/(?P<path>[A-Za-z0-9._-s/]+)/$', redirect_to, {'url': '/archives/items/%(path)s/', 'permanent': False}, name="telemeta-item-redir"),
128
129    # collections
130    url(r'^archives/collections/$', 'django.views.generic.list_detail.object_list',
131        dict(all_collections, paginate_by=20, template_name="telemeta/collection_list.html"), name="telemeta-collections"),
132    url(r'^archives/collections_unpublished/$', 'django.views.generic.list_detail.object_list',
133        dict(all_collections_unpublished, paginate_by=20, template_name="telemeta/collection_list.html"), name="telemeta-collections-unpublished"),
134    url(r'^archives/collections_published/$', 'django.views.generic.list_detail.object_list',
135        dict(all_collections_published, paginate_by=20, template_name="telemeta/collection_list.html"), name="telemeta-collections-published"),
136    url(r'^archives/collections/?page=(?P<page>[0-9]+)$',
137        'django.views.generic.list_detail.object_list',
138        dict(all_collections, paginate_by=20)),
139    url(r'^archives/collections/(?P<public_id>[A-Za-z0-9._-]+)/$', collection_view.collection_detail,
140        dict(template="telemeta/collection_detail.html"), name="telemeta-collection-detail"),
141    url(r'^archives/collections/(?P<public_id>[A-Za-z0-9._-]+)/dc/$', collection_view.collection_detail,
142        dict(template="telemeta/collection_detail_dc.html"), name="telemeta-collection-dublincore"),
143    url(r'^archives/collections/(?P<public_id>[A-Za-z0-9._-]+)/collection_xspf.xml$',
144        collection_view.collection_playlist,
145        dict(template="telemeta/collection_xspf.xml", mimetype="application/xspf+xml"),
146        name="telemeta-collection-xspf"),
147    url(r'^archives/collections/(?P<public_id>[A-Za-z0-9._-]+)/collection.m3u$',
148        collection_view.collection_playlist,
149        dict(template="telemeta/collection.m3u", mimetype="audio/mpegurl"),
150        name="telemeta-collection-m3u"),
151    url(r'^archives/collections/(?P<public_id>[A-Za-z0-9._-]+)/edit/$', collection_view.collection_edit,
152        dict(template='telemeta/collection_edit.html'), name="telemeta-collection-edit"),
153    url(r'^archives/collections/(?P<public_id>[A-Za-z0-9._-]+)/copy/$', collection_view.collection_copy,
154        dict(template='telemeta/collection_edit.html'), name="telemeta-collection-copy"),
155    url(r'^archives/collection_new/add/$', collection_view.collection_add,
156        dict(template='telemeta/collection_add.html'), name="telemeta-collection-add"),
157    url(r'^archives/collections/(?P<public_id>[A-Za-z0-9._-]+)/add_item/$', item_view.item_add,
158        dict(template='telemeta/mediaitem_add.html'), name="telemeta-collection-additem"),
159    url(r'^archives/collections/(?P<public_id>[A-Za-z0-9._-]+)/delete/$', collection_view.collection_delete, name="telemeta-collection-delete"),
160    url(r'^archives/collections/(?P<collection_public_id>[A-Za-z0-9._-]+)/related/(?P<media_id>[A-Za-z0-9._-]+)$', collection_view.related_media_collection_stream, name="telemeta-collection-related"),
161    url(r'^archives/collections/(?P<public_id>[A-Za-z0-9._-]+)/related_edit/$', collection_view.related_media_edit,  dict(template='telemeta/collection_related_edit.html'), name="telemeta-collection-related_edit"),
162    url(r'^archives/collections_sound/$', 'django.views.generic.list_detail.object_list',
163        dict(all_collections_sound, paginate_by=20, template_name="telemeta/collection_list.html"), name="telemeta-collections-sound"),
164    # FIXME: need all paths
165    url(r'^collections/(?P<path>[A-Za-z0-9._-s/]+)/$', redirect_to, {'url': '/archives/collections/%(path)s/', 'permanent': False}, name="telemeta-collection-redir"),
166
167    # RESOURCES
168    # Corpus list
169    url(r'^archives/corpus/$', 'django.views.generic.list_detail.object_list',
170        dict(all_corpus, paginate_by=20, template_name="telemeta/resource_list.html", extra_context={'type':'corpus'}), name="telemeta-corpus"),
171    # Fonds list
172    url(r'^archives/fonds/$', 'django.views.generic.list_detail.object_list',
173        dict(all_fonds, paginate_by=20, template_name="telemeta/resource_list.html", extra_context={'type':'fonds'}), name="telemeta-fonds"),
174
175    # Generic resource
176    url(r'^archives/(?P<type>[A-Za-z0-9._-]+)/(?P<public_id>[A-Za-z0-9._-]+)/$', resource_view.detail,
177        dict(template="telemeta/resource_detail.html"), name="telemeta-resource-detail"),
178    url(r'^archives/(?P<type>[A-Za-z0-9._-]+)/(?P<public_id>[A-Za-z0-9._-]+)/dc/$', resource_view.detail,
179        dict(template="telemeta/resource_detail_dc.html"), name="telemeta-resource-dublincore"),
180    url(r'^archives/(?P<type>[A-Za-z0-9._-]+)/(?P<public_id>[A-Za-z0-9._-]+)/edit/$', resource_view.edit,
181        dict(template='telemeta/resource_edit.html'), name="telemeta-resource-edit"),
182    url(r'^archives/(?P<type>[A-Za-z0-9._-]+)/(?P<public_id>[A-Za-z0-9._-]+)/copy/$', resource_view.copy,
183        dict(template='telemeta/resource_edit.html'), name="telemeta-resource-copy"),
184    url(r'^archives/(?P<type>[A-Za-z0-9._-]+)_add$', resource_view.add,
185        dict(template='telemeta/resource_add.html'), name="telemeta-resource-add"),
186    url(r'^archives/(?P<type>[A-Za-z0-9._-]+)/(?P<public_id>[A-Za-z0-9._-]+)/delete/$', resource_view.delete, name="telemeta-resource-delete"),
187    url(r'^archives/(?P<type>[A-Za-z0-9._-]+)/(?P<public_id>[A-Za-z0-9._-]+)/related/(?P<media_id>[A-Za-z0-9._-]+)$', resource_view.related_stream, name="telemeta-resource-related"),
188    url(r'^archives/(?P<type>[A-Za-z0-9._-]+)/(?P<public_id>[A-Za-z0-9._-]+)/related_edit/$', resource_view.related_edit,  dict(template='telemeta/resource_related_edit.html'), name="telemeta-resource-related_edit"),
189    url(r'^archives/(?P<type>[A-Za-z0-9._-]+)/(?P<public_id>[A-Za-z0-9._-]+)/dc/$', resource_view.detail,
190        {'template': 'telemeta/resource_detail_dc.html'},
191        name="telemeta-resource-dublincore"),
192    url(r'^archives/(?P<type>[A-Za-z0-9._-]+)/(?P<public_id>[A-Za-z0-9._-]+)/dc/xml/$', resource_view.detail,
193        {'format': 'dublin_core_xml'},
194        name="telemeta-resource-dublincore-xml"),
195    url(r'^archives/$', general_view.search, name="telemeta-archives"),
196
197    # search
198    url(r'^search/$', general_view.search, name="telemeta-search"),
199    url(r'^search/collections/$', general_view.search, {'type': 'collections'},
200        name="telemeta-search-collections"),
201    url(r'^search/items/$', general_view.search, {'type': 'items'},
202        name="telemeta-search-items"),
203    url(r'^search/corpus/$', general_view.search, {'type': 'corpus'},
204        name="telemeta-search-corpus"),
205    url(r'^search/fonds/$', general_view.search, {'type': 'fonds'},
206        name="telemeta-search-fonds"),
207
208    url(r'^search/criteria/$', general_view.edit_search, name="telemeta-search-criteria"),
209    url(r'^complete_location/$', general_view.complete_location, name="telemeta-complete-location"),
210
211    # administration
212    url(r'^admin/$', admin_view.admin_index, name="telemeta-admin"),
213    url(r'^admin/general/$', admin_view.admin_general, name="telemeta-admin-general"),
214    url(r'^admin/enumerations/$', admin_view.admin_enumerations, name="telemeta-admin-enumerations"),
215    url(r'^admin/users/$', admin_view.admin_users, name="telemeta-admin-users"),
216
217    # instruments administration
218    url(r'^admin/instruments/$',
219        instrument_view.edit_instrument ,
220        name="telemeta-instrument-edit"),
221    url(r'^admin/instruments/add/$',
222        instrument_view.add_to_instrument,
223        name="telemeta-instrument-add"),
224    url(r'^admin/instruments/update/$',
225        instrument_view.update_instrument,
226        name="telemeta-instrument-update"),
227    url(r'^admin/instruments/'
228        + r'(?P<value_id>[0-9]+)/$',
229        instrument_view.edit_instrument_value,
230        name="telemeta-instrument-record-edit"),
231    url(r'^admin/instruments/'
232        + r'(?P<value_id>[0-9]+)/update/$',
233        instrument_view.update_instrument_value,
234        name="telemeta-instrument-record-update"),
235
236    # enumerations administration
237    url(r'^admin/enumerations/(?P<enumeration_id>[0-9a-z]+)/$',
238        admin_view.edit_enumeration ,
239        name="telemeta-enumeration-edit"),
240    url(r'^admin/enumerations/(?P<enumeration_id>[0-9a-z]+)/add/$',
241        admin_view.add_to_enumeration,
242        name="telemeta-enumeration-add"),
243    url(r'^admin/enumerations/(?P<enumeration_id>[0-9a-z]+)/update/$',
244        admin_view.update_enumeration,
245        name="telemeta-enumeration-update"),
246    url(r'^admin/enumerations/(?P<enumeration_id>[0-9a-z]+)/'
247        + r'(?P<value_id>[0-9]+)/$',
248        admin_view.edit_enumeration_value,
249        name="telemeta-enumeration-record-edit"),
250    url(r'^admin/enumerations/(?P<enumeration_id>[0-9a-z]+)/'
251        + r'(?P<value_id>[0-9]+)/update/$',
252        admin_view.update_enumeration_value,
253        name="telemeta-enumeration-record-update"),
254
255    # Geographic browsing
256    url(r'^geo/$', geo_view.list_continents, name="telemeta-geo-continents"),
257    url(r'^geo/(?P<continent>[a-z_]+)/$', geo_view.list_countries,
258        name="telemeta-geo-countries"),
259    url(r'^geo/collections/(?P<continent>[a-z_]+)/(?P<country>[a-z_]+)/$',
260        geo_view.list_country_collections,
261        name="telemeta-geo-country-collections"),
262    url(r'^geo/items/(?P<continent>[a-z_]+)/(?P<country>[a-z_]+)/$',
263        geo_view.list_country_items,
264        name="telemeta-geo-country-items"),
265    url(r'^geo/country_info/(?P<id>[0-9a-z]+)/$',
266        geo_view.country_info, name="telemeta-country-info"),
267
268    # CSS+Images (FIXME: for developement only)
269    url(r'^css/(?P<path>.*)$', 'django.views.static.serve',
270        {'document_root': htdocs+'/css'},
271        name="telemeta-css"),
272    url(r'images/(?P<path>.*)$', 'django.views.static.serve',
273        {'document_root': htdocs+'/images'},
274        name="telemeta-images"),
275    url(r'images/(?P<path>.*).png$', 'django.views.static.serve',
276        {'document_root': htdocs+'/images'},
277        name="telemeta-type-images"),
278    url(r'^js/(?P<path>.*)$', 'django.views.static.serve',
279        {'document_root': htdocs+'/js'},
280        name="telemeta-js"),
281    url(r'^swf/(?P<path>.*)$', 'django.views.static.serve',
282        {'document_root': htdocs+'/swf'},
283        name="telemeta-swf"),
284    url(r'^timeside/(?P<path>.*)$', 'django.views.static.serve',
285        {'document_root': htdocs+'/timeside'},
286        name="telemeta-timeside"),
287    url(r'^video-js/(?P<path>.*)$','django.views.static.serve',
288        {'document_root': htdocs+'/video-js'},
289        name="telemeta-video-js"),
290
291    # Flat pages
292    url(r'^pages/(?P<path>.*)$', general_view.render_flatpage, name="telemeta-flatpage"),
293
294    # OAI-PMH Data Provider
295    url(r'^oai/.*$', general_view.handle_oai_request, name="telemeta-oai"),
296
297    # Authentication
298    url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'telemeta/login.html'},
299        name="telemeta-login"),
300    url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'telemeta/login.html'},
301        name="telemeta-login"),
302    #url(r'^login/$', 'ipauth.views.login', {'template_name': 'telemeta/login.html'},
303    #    name="telemeta-login"),
304    url(r'^logout/$', general_view.logout, name="telemeta-logout"),
305
306    # Users
307    url(r'^accounts/$', general_view.users, name="telemeta-users"),
308
309    # Desk
310    url(r'^desk/lists/$', general_view.lists, name="telemeta-desk-lists"),
311    url(r'^desk/profile/(?P<username>[A-Za-z0-9._-]+)/$', profile_view.profile_detail, name="telemeta-desk-profile"),
312    url(r'^desk/home/$', general_view.home, name="telemeta-desk-home"),
313
314    # Profiles
315    url(r'^accounts/(?P<username>[A-Za-z0-9._-]+)/profile/$', profile_view.profile_detail, name="telemeta-profile-detail"),
316    url(r'^accounts/(?P<username>[A-Za-z0-9._-]+)/profile/edit/$', profile_view.profile_edit, name="telemeta-profile-edit"),
317    url(r'^accounts/(?P<username>[A-Za-z0-9._-]+)/rss/$', UserRevisionsFeed(),  name="telemeta-user-rss"),
318
319    # Registration
320    url(r'^accounts/password_change/$', 'django.contrib.auth.views.password_change', {'template_name': 'telemeta/registration/password_change_form.html'}, name="telemeta-password-change"),
321    url(r'^accounts/password_change_done/$', 'django.contrib.auth.views.password_change_done', {'template_name': 'telemeta/registration/password_change_done.html'}, name="telemeta-password-change-done"),
322
323    url(r'^accounts/password_reset/$', 'django.contrib.auth.views.password_reset', {'template_name': 'telemeta/registration/password_reset_form.html', 'email_template_name': 'telemeta/registration/password_reset_email.html'}, name="telemeta-password-reset"),
324    url(r'^accounts/password_reset_done/$', 'django.contrib.auth.views.password_reset_done', {'template_name': 'telemeta/registration/password_reset_done.html'}, name="telemeta-password-reset-done"),
325    url(r'^accounts/password_reset_confirm/(?P<uidb36>[A-Za-z0-9._-]+)/(?P<token>[A-Za-z0-9._-]+)/$', 'django.contrib.auth.views.password_reset_confirm', {'template_name': 'telemeta/registration/password_reset_confirm.html'}, name="telemeta-password-reset-confirm"),
326    url(r'^accounts/password_reset_complete/$', 'django.contrib.auth.views.password_reset_complete', {'template_name': 'telemeta/registration/password_reset_complete.html'}, name="telemeta-password-reset-complete"),
327    url(r'^accounts/password_reset_complete/$', 'django.contrib.auth.views.password_reset_complete', {'template_name': 'telemeta/registration/password_reset_complete.html'}, name="telemeta-password-reset-complete"),
328
329    # JSON RPC
330    url(r'json/$', jsonrpc_site.dispatch, name='jsonrpc_mountpoint'),
331    # for the graphical browser/web console only, omissible
332    # url(r'json/browse/', 'jsonrpc.views.browse', name="jsonrpc_browser"),
333
334    # Playlists
335    url(r'^playlists/(?P<public_id>[a-zA-Z0-9]+)/(?P<resource_type>[a-zA-Z0-9]+)/csv/$', playlist_view.playlist_csv_export, name="telemeta-playlist-csv-export"),
336
337    # RSS feeds
338    url(r'^rss/$', LastestRevisionsFeed(), name="telemeta-rss"),
339
340    # Static media
341    # FIXME:need to move export dir from the cache
342    url(r'^media/cache/(?P<path>.*)$', 'django.views.static.serve', {
343            'document_root': settings.TELEMETA_CACHE_DIR,}),
344)
345
346
Note: See TracBrowser for help on using the repository browser.