PK1S/B‡Ár«ÑLÑLdoqu-latest/ext_fields.html Document Fields — Docu 0.28.2 documentation

Document Fields¶

New in version 0.23.

Note

This abstraction is by no means a complete replacement for the normal approach of semantic grouping. Please use it with care. Also note that the API can change. The class can even be removed in future versions of Doqu.

class doqu.ext.fields.Field(datatype, essential=False, required=False, default=None, choices=None, label=None, pickled=False)¶

Representation of a document property. Syntax sugar for separate definitions of structure, validators, defaults and labels.

Usage:

class Book(Document):
    title = Field(unicode, required=True, default=u'Hi', label='Title')

this is just another way to type:

class Book(Document):
    structure = {
        'title': unicode
    }
    validators = {
        'title': [validators.Required()]
    }
    defaults = {
        'title': u'Hi'
    }
    labels = {
        'title': u'The Title'
    }

Nice, eh? But be careful: the title definition in the first example barely fits its line. Multiple long definitions will turn your document class into an opaque mess of characters, while the semantically grouped definitions stay short and keep related things aligned together. “Semantic sugar” is sometimes pretty bitter, use it with care.

Complex validators still need to be specified by hand in the relevant dictionary. This can be worked around by creating specialized field classes (e.g. EmailField) as it is done e.g. in Django.

Parameters:
  • essential – if True, validator Exists is added (i.e. the field may be empty but it must be present in the record).
  • pickled – if True, the value is preprocessed with pickle’s dumps/loads functions. This of course breaks lookups by this field but enables storing arbitrary Python objects.
class doqu.ext.fields.FileField(base_path, **kwargs)¶

Handles externally stored files.

Warning

This field saves the file when process_outgoing() is triggered (see outgoing_processors in DocumentMetadata).

Outdated (replaced) files are not automatically removed.

Usage:

class Doc(Document):
    attachment = FileField(base_path=MEDIA_ROOT+'attachments/')

d = Doc()
d.attachment = open('foo.txt')
d.save(db)

dd = Doc.objects(db)[0]
print dd.attachment.file.read()
Parameters:base_path – A string or callable: the directory where the files should be stored.
file_wrapper_class¶

alias of FileWrapper

class doqu.ext.fields.ImageField(base_path, **kwargs)¶

A FileField that provides extended support for images. The ImageField.file is an ImageWrapper instance.

Usage:

class Photo(Document):
    summary = Field(unicode)
    image = ImageField(base_path='photos/')

p = Photo(summary='Fido', image=open('fido.jpg'))
p.save(db)

# playing with image
print "The photo is {0}×{1}px".format(*p.image.size)
p.image.rotate(90)
p.image.save()
file_wrapper_class¶

alias of ImageWrapper

Project Versions

Previous topic

Document API

Next topic

Backend API

This Page

PK1S/B‘ó‰íqíqdoqu-latest/validators.html Validators — Docu 0.28.2 documentation

Validators¶

A validator simply takes an input and verifies it fulfills some criterion, such as a maximum length for a string. If the validation fails, a ValidationError is raised. This simple system allows chaining any number of validators on fields.

The module is heavily inspired by (and partially ripped off from) the WTForms validators. However, ours serve a bit different purpose. First, error messages are not needed here (the errors will not be displayed to end users). Second, these validators include query filtering capabilities.

Usage example:

class Person(Document):
    validators = {
        'first_name': [required(), length(min=2)],
        'age': [number_range(min=18)],
    }

This document will raise ValidationError if you attempt to save it with wrong values. You can call Document.is_valid() to ensure everything is OK.

Now let’s query the database for all objects of Person:

Person.objects(db)

Doqu does not deal with tables or collections, it follows the DRY (Don’t Repeat Yourself) principle and uses the same validators to determine what database records belong to given document class. The schema defined above is alone equivalent to the following query:

...where(first_name__exists=True, age__gte=18).where_not(first_name='')

This is actually the base query available as Person.objects(db).

Note

not all validators affect document-related queries. See detailed documentation on each validator.

exception doqu.validators.StopValidation¶

Causes the validation chain to stop.

If StopValidation is raised, no more validators in the validation chain are called.

exception doqu.validators.ValidationError¶

Raised when a validator fails to validate its input.

class doqu.validators.Email¶

Validates an email address. Note that this uses a very primitive regular expression and should only be used in instances where you later verify by other means, such as email activation or lookups.

Adds conditions to the document-related queries: the field must match the pattern.

doqu.validators.email¶

alias of Email

class doqu.validators.EqualTo(name)¶

Compares the values of two fields.

Parameters:name – The name of the other field to compare to.
doqu.validators.equal_to¶

alias of EqualTo

class doqu.validators.Equals(other_value)¶

Compares the value to another value.

Parameters:other_value – The other value to compare to.

Adds conditions to the document-related queries.

doqu.validators.equals¶

alias of Equals

class doqu.validators.Exists¶

Ensures given field exists in the record. This does not affect validation of a document with pre-defined structure but does affect queries.

Adds conditions to the document-related queries.

doqu.validators.exists¶

alias of Exists

class doqu.validators.IPAddress¶

Validates an IP(v4) address.

Adds conditions to the document-related queries: the field must match the pattern.

doqu.validators.ip_address¶

alias of IPAddress

class doqu.validators.Length(min=None, max=None)¶

Validates the length of a string.

Parameters:
  • min – The minimum required length of the string. If not provided, minimum length will not be checked.
  • max – The maximum length of the string. If not provided, maximum length will not be checked.
doqu.validators.length¶

alias of Length

class doqu.validators.NumberRange(min=None, max=None)¶

Validates that a number is of a minimum and/or maximum value, inclusive. This will work with any comparable number type, such as floats and decimals, not just integers.

Parameters:
  • min – The minimum required value of the number. If not provided, minimum value will not be checked.
  • max – The maximum value of the number. If not provided, maximum value will not be checked.

Adds conditions to the document-related queries.

doqu.validators.number_range¶

alias of NumberRange

class doqu.validators.Optional¶

Allows empty value (i.e. bool(value) == False) and terminates the validation chain for this field (i.e. no more validators are applied to it). Note that errors raised prior to this validator are not suppressed.

doqu.validators.optional¶

alias of Optional

class doqu.validators.Required¶

Requires that the value is not empty, i.e. bool(value) returns True. The bool values can also be False (but not anything else).

Adds conditions to the document-related queries: the field must exist and be not equal to an empty string.

doqu.validators.required¶

alias of Required

class doqu.validators.Regexp(pattern, flags=0)¶

Validates the field against a user provided regexp.

Parameters:
  • regex – The regular expression string to use.
  • flags – The regexp flags to use, for example re.IGNORECASE or re.UNICODE.

Note

the pattern must be provided as string because compiled patterns cannot be used in database lookups.

Adds conditions to the document-related queries: the field must match the pattern.

doqu.validators.regexp¶

alias of Regexp

class doqu.validators.URL(require_tld=True)¶

Simple regexp based url validation. Much like the email validator, you probably want to validate the url later by other means if the url must resolve.

Parameters:require_tld – If true, then the domain-name portion of the URL must contain a .tld suffix. Set this to false if you want to allow domains like localhost.

Adds conditions to the document-related queries: the field must match the pattern.

doqu.validators.url¶

alias of URL

class doqu.validators.AnyOf(choices)¶

Compares the incoming data to a sequence of valid inputs.

Parameters:choices – A sequence of valid inputs.

Adds conditions to the document-related queries.

doqu.validators.any_of¶

alias of AnyOf

class doqu.validators.NoneOf(choices)¶

Compares the incoming data to a sequence of invalid inputs.

Parameters:choices – A sequence of invalid inputs.

Adds conditions to the document-related queries.

doqu.validators.none_of¶

alias of NoneOf

Project Versions

Previous topic

Glossary

Next topic

Utilities

This Page

PK1S/Ba“Lùrùr"doqu-latest/ext_tokyo_cabinet.html Tokyo Cabinet extension — Docu 0.28.2 documentation

Tokyo Cabinet extension¶

A storage/query backend for Tokyo Cabinet.

Allows direct access to the database and is thus extremely fast. However, it locks the database and is therefore not suitable for environments where concurrent access is required. Please use Tokyo Tyrant for such environments.

status:beta
database:Tokyo Cabinet
dependencies:tokyo-python, pyrant
suitable for:general purpose, embedded

Warning

this module is not intended for production despite it may be stable. Bug reports and patches are welcome.

Note

this module should not depend on Pyrant; just needs some refactoring.

Note

support for metasearch is planned.

Usage:

>>> import os
>>> import doqu
>>> DB_SETTINGS = {
...     'backend': 'doqu.ext.tokyo_cabinet',
...     'path': '_tc_test.tct',
... }
>>> assert not os.path.exists(DB_SETTINGS['path']), 'test database must not exist'
>>> db = doqu.get_db(DB_SETTINGS)
>>> class Person(doqu.Document):
...     structure = {'name': unicode}
...     def __unicode__(self):
...         u'%(name)s' % self
...
>>> Person.objects(db)    # the database is expected to be empty
[]
>>> db.connection['john'] = {'name': 'John'}
>>> mary = Person(name='Mary')
>>> mary_pk = mary.save(db)
>>> q = Person.objects(db)
>>> q
[<Person John>, <Person Mary>]
>>> q.where(name__matches='^J')
[<Person John>]
>>> q    # the original query was not modified by the descendant
[<Person John>, <Person Mary>]
>>> db.connection.close()
>>> os.unlink(DB_SETTINGS['path'])
class doqu.ext.tokyo_cabinet.StorageAdapter(**kw)¶
Parameters:path – relative or absolute path to the database file (e.g. test.tct)

Note

Currently only table flavour of Tokyo Cabinet databases is supported. It is uncertain whether it is worth supporting other flavours as they do not provide query mechanisms other than access by primary key.

clear()¶

Clears the whole storage from data, resets autoincrement counters.

connect()¶

Connects to the database. Raises RuntimeError if the connection is not closed yet. Use reconnect() to explicitly close the connection and open it again.

delete(key)¶

Deletes record with given primary key.

disconnect()¶

Closes internal store and removes the reference to it. If the backend works with a file, then all pending changes are saved now.

find(doc_class=<type 'dict'>, **conditions)¶

Returns instances of given class, optionally filtered by given conditions.

Parameters:
  • doc_class – Document class. Default is dict. Normally you will want a more advanced class, such as Document or its more concrete subclasses (with explicit structure and validators).
  • conditions – key/value pairs, same as in where().

Note

By default this returns a tuple of (key, data_dict) per item. However, this can be changed if doc_class provides the method from_storage(). For example, Document has the notion of “saved state” so it can store the key within. Thus, only a single Document object is returned per item.

get(key, doc_class=<type 'dict'>)¶

Returns document instance for given document class and primary key. Raises KeyError if there is no item with given key in the database.

Parameters:
  • key – a numeric or string primary key (as supported by the backend).
  • doc_class – a document class to wrap the data into. Default is dict.
get_many(keys, doc_class=<type 'dict'>)¶

Returns an iterator of documents with primary keys from given list. Basically this is just a simple wrapper around get() but some backends can reimplement the method in a much more efficient way.

get_or_create(doc_class=<type 'dict'>, **conditions)¶

Queries the database for records associated with given document class and conforming to given extra conditions. If such records exist, picks the first one (the order may be random depending on the database). If there are no such records, creates one.

Returns the document instance and a boolean value “created”.

query_adapter¶

alias of QueryAdapter

reconnect()¶

Gracefully closes current connection (if it’s not broken) and connects again to the database (e.g. reopens the file).

save(key, data)¶

Saves given data with given primary key into the storage. Returns the primary key.

Parameters:
  • key – the primary key for given object; if None, will be generated.
  • data – a dict containing all properties to be saved.

Note that you must provide current primary key for a record which is already in the database in order to update it instead of copying it.

sync()¶

Synchronizes the storage to disk immediately if the backend supports this operation. Normally the data is synchronized either on save(), or on timeout, or on disconnect(). This is strictly backend-specific. If a backend does not support the operation, NotImplementedError is raised.

class doqu.ext.tokyo_cabinet.QueryAdapter(*args, **kw)¶

The Query class.

count()¶

Same as __len__ but without fetching the records (i.e. faster).

delete()¶

Deletes all records that match current query.

order_by(names, reverse=False)¶

Returns a query object with same conditions but with results sorted by given field. By default the direction of sorting is ascending.

Parameters:
  • names – list of strings: names of fields by which results should be sorted. Some backends may only support a single field for sorting.
  • reversebool: if True, the direction of sorting is reversed and becomes descending. Default is False.
values(name)¶

Returns an iterator that yields distinct values for given column name.

Note

this is currently highly inefficient because the underlying library does not support columns mode (tctdbiternext3). Moreover, even current implementation can be optimized by removing the overhead of creating full-blown document objects (though preserving data type is necessary).

where(**conditions)¶

Returns Query instance filtered by given conditions. The conditions are specified by backend’s underlying API.

where_not(**conditions)¶

Returns Query instance. Inverted version of where().

Project Versions

Previous topic

Shove extension

Next topic

Tokyo Tyrant extension

This Page

PK1S/B~4á:6:6doqu-latest/index.html Easy data modeling with Doqu — Docu 0.28.2 documentation

Easy data modeling with Doqu¶

Doqu is a lightweight Python framework for document databases. It provides a uniform API for modeling, validation and queries across various kinds of storages.

It is not an ORM as it doesn’t map existing schemata to Python objects. Instead, it lets you define schemata on a higher layer built upon a schema-less storage (key/value or document-oriented). You define models as a valuable subset of the whole database and work with only certain parts of existing entities – the parts you need.

Topics:

Indices and tables¶

Author¶

Originally written by Andrey Mikhaylenko since 2009.

See the file AUTHORS for a complete authors list of this application.

Please feel free to submit patches, report bugs or request features:

Licensing¶

Doqu is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Doqu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with Doqu. If not, see <http://gnu.org/licenses/>.

Project Versions

Table Of Contents

Next topic

Installation

This Page

PK1S/B—”QôYôYdoqu-latest/searchindex.jsSearch.setIndex({objects:{"doqu.ext.forms":{DocumentSelectField:[11,1,1,""],QuerySetSelectField:[11,1,1,""],document_form_factory:[11,5,1,""]},"doqu.document_base":{Many:[13,3,1,""],Document:[13,1,1,""]},"doqu.ext":{tokyo_tyrant:[15,0,1,""],mongodb:[14,0,1,""],shelve_db:[5,0,1,""],forms:[11,0,1,""],fields:[6,0,1,""],shove_db:[2,0,1,""],tokyo_cabinet:[9,0,1,""]},"doqu.ext.mongodb.StorageAdapter":{disconnect:[14,2,1,""],reconnect:[14,2,1,""],get:[14,2,1,""],clear:[14,2,1,""],sync:[14,2,1,""],connect:[14,2,1,""],get_many:[14,2,1,""],get_or_create:[14,2,1,""],save:[14,2,1,""],find:[14,2,1,""],"delete":[14,2,1,""]},"doqu.backend_base.BaseStorageAdapter":{disconnect:[1,2,1,""],reconnect:[1,2,1,""],get:[1,2,1,""],clear:[1,2,1,""],sync:[1,2,1,""],connect:[1,2,1,""],get_many:[1,2,1,""],get_or_create:[1,2,1,""],save:[1,2,1,""],find:[1,2,1,""],"delete":[1,2,1,""]},"doqu.ext.tokyo_tyrant.query":{QueryAdapter:[15,1,1,""]},"doqu.backend_base.BaseQueryAdapter":{count:[1,2,1,""],order_by:[1,2,1,""],values:[1,2,1,""],where_not:[1,2,1,""],where:[1,2,1,""],"delete":[1,2,1,""]},"doqu.ext.shelve_db":{QueryAdapter:[5,1,1,""],StorageAdapter:[5,1,1,""]},"doqu.ext.forms.QuerySetSelectField":{populate_obj:[11,2,1,""],process:[11,2,1,""],validate:[11,2,1,""],process_data:[11,2,1,""],post_validate:[11,2,1,""]},"doqu.backend_base.LookupManager":{exception_class:[1,3,1,""],resolve:[1,2,1,""]},"doqu.document_base.Document":{from_storage:[13,6,1,""],pk:[13,3,1,""],validate:[13,2,1,""],save:[13,2,1,""],contribute_to_query:[13,6,1,""],"delete":[13,2,1,""]},"doqu.ext.fields.FileField":{file_wrapper_class:[6,3,1,""]},"doqu.ext.tokyo_cabinet":{QueryAdapter:[9,1,1,""],StorageAdapter:[9,1,1,""]},"doqu.validators":{any_of:[10,3,1,""],exists:[10,3,1,""],StopValidation:[10,4,1,""],number_range:[10,3,1,""],none_of:[10,3,1,""],Email:[10,1,1,""],equal_to:[10,3,1,""],optional:[10,3,1,""],Equals:[10,1,1,""],Regexp:[10,1,1,""],Optional:[10,1,1,""],email:[10,3,1,""],ValidationError:[10,4,1,""],URL:[10,1,1,""],Required:[10,1,1,""],EqualTo:[10,1,1,""],equals:[10,3,1,""],NumberRange:[10,1,1,""],Length:[10,1,1,""],regexp:[10,3,1,""],ip_address:[10,3,1,""],Exists:[10,1,1,""],url:[10,3,1,""],AnyOf:[10,1,1,""],required:[10,3,1,""],length:[10,3,1,""],NoneOf:[10,1,1,""],IPAddress:[10,1,1,""]},"doqu.ext.forms.DocumentSelectField":{process:[11,2,1,""],populate_obj:[11,2,1,""],validate:[11,2,1,""],process_data:[11,2,1,""],post_validate:[11,2,1,""]},"doqu.ext.mongodb":{QueryAdapter:[14,1,1,""],StorageAdapter:[14,1,1,""]},"doqu.ext.fields":{Field:[6,1,1,""],ImageField:[6,1,1,""],FileField:[6,1,1,""]},"doqu.ext.tokyo_tyrant.storage":{StorageAdapter:[15,1,1,""]},"doqu.backend_base.ConverterManager":{exception_class:[1,3,1,""],to_db:[1,2,1,""],from_db:[1,2,1,""]},doqu:{document_base:[13,0,1,""],utils:[4,0,1,""],backend_base:[1,0,1,""],validators:[10,0,1,""]},"doqu.ext.shelve_db.StorageAdapter":{disconnect:[5,2,1,""],get_many:[5,2,1,""],get:[5,2,1,""],clear:[5,2,1,""],sync:[5,2,1,""],query_adapter:[5,3,1,""],connect:[5,2,1,""],reconnect:[5,2,1,""],get_or_create:[5,2,1,""],save:[5,2,1,""],find:[5,2,1,""],"delete":[5,2,1,""]},"doqu.backend_base":{LookupManager:[1,1,1,""],LookupProcessorDoesNotExist:[1,4,1,""],BaseStorageAdapter:[1,1,1,""],BaseQueryAdapter:[1,1,1,""],ConverterManager:[1,1,1,""],DataProcessorDoesNotExist:[1,4,1,""],ProcessorDoesNotExist:[1,4,1,""]},"doqu.ext.tokyo_cabinet.QueryAdapter":{count:[9,2,1,""],order_by:[9,2,1,""],values:[9,2,1,""],where_not:[9,2,1,""],where:[9,2,1,""],"delete":[9,2,1,""]},"doqu.ext.mongodb.QueryAdapter":{count:[14,2,1,""],order_by:[14,2,1,""],values:[14,2,1,""],where_not:[14,2,1,""],where:[14,2,1,""],"delete":[14,2,1,""]},"doqu.ext.tokyo_cabinet.StorageAdapter":{disconnect:[9,2,1,""],reconnect:[9,2,1,""],get:[9,2,1,""],clear:[9,2,1,""],sync:[9,2,1,""],query_adapter:[9,3,1,""],connect:[9,2,1,""],get_many:[9,2,1,""],get_or_create:[9,2,1,""],save:[9,2,1,""],find:[9,2,1,""],"delete":[9,2,1,""]},"doqu.ext.shove_db":{QueryAdapter:[2,1,1,""],StorageAdapter:[2,1,1,""]},"doqu.ext.shove_db.StorageAdapter":{disconnect:[2,2,1,""],get:[2,2,1,""],query_adapter:[2,3,1,""],sync:[2,2,1,""],find:[2,2,1,""],clear:[2,2,1,""],connect:[2,2,1,""],reconnect:[2,2,1,""],get_or_create:[2,2,1,""],save:[2,2,1,""],get_many:[2,2,1,""],"delete":[2,2,1,""]},"doqu.ext.fields.ImageField":{file_wrapper_class:[6,3,1,""]},"doqu.utils":{get_db:[4,5,1,""],camel_case_to_underscores:[4,5,1,""],dump_doc:[4,5,1,""],load_fixture:[4,5,1,""]},"doqu.ext.shove_db.QueryAdapter":{count:[2,2,1,""],order_by:[2,2,1,""],values:[2,2,1,""],where_not:[2,2,1,""],where:[2,2,1,""],"delete":[2,2,1,""]},"doqu.ext.tokyo_tyrant.storage.StorageAdapter":{disconnect:[15,2,1,""],get:[15,2,1,""],clear:[15,2,1,""],sync:[15,2,1,""],find:[15,2,1,""],connect:[15,2,1,""],reconnect:[15,2,1,""],get_many:[15,2,1,""],save:[15,2,1,""],get_or_create:[15,2,1,""],"delete":[15,2,1,""]},"doqu.ext.shelve_db.QueryAdapter":{count:[5,2,1,""],order_by:[5,2,1,""],values:[5,2,1,""],where_not:[5,2,1,""],where:[5,2,1,""],"delete":[5,2,1,""]},"doqu.ext.tokyo_tyrant.query.QueryAdapter":{count:[15,2,1,""],order_by:[15,2,1,""],values:[15,2,1,""],where_not:[15,2,1,""],where:[15,2,1,""],"delete":[15,2,1,""]}},terms:{represent:[6,13,16],all:[1,2,3,4,5,9,10,14,13,15,16],code:[11,16],partial:10,chain:10,whatev:3,illustr:16,queri:[0,1,2,3,4,5,9,10,11,14,13,15,16],lack:[4,16],signific:16,latter:1,overlap:16,follow:[1,10],disk:[1,2,5,14,15,9],row:[16,2,5],compact:16,privat:1,depend:[1,2,5,11,14,13,15,9],mary_pk:9,decim:10,readabl:4,storageadapt:[14,9,15,2,5],deviat:1,becam:16,under:0,preprocess:6,worth:9,introduc:[1,16],adapt:[3,4,1],merchant:0,woman:16,string:[1,2,3,4,5,6,9,10,14,15,16],fals:[1,2,4,10,6,5,11,14,13,15,9],must_hav:16,account:4,util:[0,4],mechan:[13,9],imagewrapp:6,veri:[3,2,10],affect:10,xxxxxxxxxx:16,ip_address:10,relev:[6,16],bitbucket:[0,12],magic:16,level:[11,1],did:13,gender:16,convertermanag:1,scalabl:16,list:[0,1,2,3,4,5,11,14,15,9],last_nam:16,iter:[1,2,5,14,15,9],factori:4,"try":16,item:[1,2,5,14,13,15,9],allow_blank:11,small:5,settings_kwarg:4,setup:12,pleas:[0,9,6],prevent:16,impli:0,shelve_db:5,slower:2,moreov:[9,1,16,2,5],speci:16,sync:[1,2,5,14,15,9],tokyo_tyrant_databas:16,second:[16,10],design:4,pass:[3,4],port:[14,16],process_data:11,subclass:[1,2,3,9,5,11,14,13,15,16],even:[0,2,6,9,5,13,16],index:[0,2,5],what:[3,0,16,10],number_rang:10,sub:5,compar:[16,10],preserv:[13,9],section:16,abl:16,favour:16,overload:1,uniform:[3,0,16,2,5],current:[1,2,9,5,14,13,15,16],delet:[1,2,5,14,13,15,9],version:[0,1,2,4,6,5,14,15,9],someclass:4,"new":[11,16],symmetr:1,ever:16,method:[1,2,3,4,9,5,11,14,13,15,16],can:[0,1,2,3,4,5,6,9,10,11,12,13,14,15,16],full:[11,9,2,5],deriv:1,absolut:[4,9,16,5],autogener:16,gener:[0,1,2,3,5,11,14,15,9],never:16,len:[14,1],behaviour:[3,1],shouldn:11,explicitli:[1,2,5,14,15,9],let:[0,1,16,10],address:[16,10],equal_to:10,along:[0,2],becom:[14,1,15,16,9],modifi:[0,9,16],sinc:0,interpret:[1,16],wait:16,dry:[13,10],convert:[1,16],unread:16,convers:16,shove:[7,16,2],onetomanyrel:13,svarga:13,margin:4,anymor:16,memcach:2,precis:16,datetim:16,base:[11,4,10],behav:16,pick:[1,2,5,11,14,15,9],extrem:[9,16],implement:[9,1,16,2,5],portabl:16,overrid:[11,4],semant:[6,16],regardless:2,extra:[1,2,9,5,11,14,15,16],primit:10,modul:[0,2,4,10,9,5,14,16],foundat:0,"while":[6,1,2,5],put:16,"boolean":[1,2,5,14,15,9],instal:[0,12],should:[0,1,2,3,5,6,9,10,11,14,13,15,16],select:11,highli:[9,2,5],regex:10,from:[1,2,3,4,5,9,10,11,14,13,15,16],describ:16,would:16,memori:[4,2],distinct:[9,16,2,5],regist:[1,16],two:[11,4,16,10],todai:16,subvers:2,few:[0,16],live:16,concret:[1,2,5,14,13,15,9],call:[3,11,1,10],recommend:1,file_wrapper_class:6,care:[6,16],type:[1,2,3,5,6,9,10,11,14,13,15,16],more:[0,1,2,10,9,5,14,15,16],sort:[1,2,9,5,14,15,16],desir:5,validationerror:[13,10],process_formdata:11,peopl:16,relat:[6,13,16,10],lookup:[6,1,16,2,10],warn:[2,6,16,5,14,9],flag:10,txt:6,stick:1,particular:0,known:4,postgresql:2,given:[1,2,3,4,5,9,10,11,14,13,15,16],easiest:11,dbm:[2,5],must:[1,2,4,5,6,9,10,14,15,16],fly:[16,2],none:[1,2,4,5,6,9,10,11,14,13,15,16],retriev:[13,1,16,2,5],sometim:[3,6],valuabl:0,tokyo:[7,1,15,16,9],alia:[1,2,10,6,5,13,9],prepar:1,work:[0,1,2,3,5,6,9,10,14,15,16],uniqu:[3,14,1,15],spec:16,obvious:16,isinst:1,caveat:11,rais:[1,2,4,10,9,5,11,14,13,15,16],purpos:[0,14,15,9,10],fetch:[14,4,15,16,9],def:[1,9,16],control:16,sqlite:[16,2],malform:16,encapsul:11,process:[11,1],lock:9,share:[16,5],dump_doc:4,indic:0,topic:0,minimum:10,caution:11,want:[1,2,10,9,5,14,15,16],doqu:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,16],serial:[3,1,16,2],lookupmanag:1,coupl:16,alwai:[11,1,16],cours:[6,16],multipl:[1,2,3,6,5,16],variou:[0,4,1,16],first_nam:[16,10],turn:[6,16],rather:11,anoth:[6,13,12,16,10],ordinari:5,write:16,how:[3,1,16],criterion:10,actual:[3,11,14,16,10],pure:2,answer:16,verifi:10,csv:4,config:16,updat:[1,2,9,5,14,15,16],map:[3,0,11],product:[14,9,16],recogn:16,timedelta:16,mess:6,max:10,clone:12,after:11,store_uri:2,befor:[3,13,1,16],wrong:[13,10],scratch:16,mai:[12,2,6,9,5,1,14,15,16],usus:13,unlink:9,associ:[1,2,3,5,14,13,15,9],"short":6,essenti:[6,5],classmethod:13,opaqu:6,counter:[1,2,5,14,15,9],explicit:[1,2,5,14,15,9],correspond:13,django:[11,6,13,16],issu:[0,16],inform:[3,16],"switch":[0,16],combin:[4,1],allow:[1,9,16,10],callabl:6,volum:5,why:[0,16],order:[1,2,9,5,14,15,16],talk:16,our:[16,10],oper:[1,2,5,11,14,15,9],keep_kei:13,rotat:6,document_class:11,data_dict:[1,2,5,14,15,9],find:[1,2,9,5,14,15,16],becaus:[1,2,3,10,9,5,13,16],tupl:[1,2,5,14,15,9],tokyo_cabinet_databas:16,own:1,through:16,reconnect:[1,2,5,14,15,9],still:6,tokyo_cabinet:[4,9,16],paramet:[1,2,4,10,6,5,11,14,13,15,9],style:5,disconnect:[1,2,5,14,15,9],fit:[0,16,6],polici:1,exact:16,complex:[6,1,16,14],better:1,pend:[1,2,5,14,15,9],persist:[16,5],pad:4,hidden:13,therefor:[3,1,9],alter:16,count:[1,2,5,14,15,9],them:[4,13,1],good:[11,1,16],"return":[1,2,4,10,9,5,11,14,13,15,16],thei:[1,3,4,9,5,11,13,16],python:[0,1,2,3,6,9,5,11,16],safe:13,dai:16,initi:11,docu:[3,16,2],"break":6,framework:0,kiss:13,instead:[0,1,2,9,5,11,14,15,16],now:[1,2,10,9,5,14,15,16],discuss:16,nor:16,choic:[11,6,10],term:0,somewher:16,name:[1,2,3,4,5,9,10,11,14,15,16],anyth:[5,16,10],edit:16,simpl:[1,2,10,9,5,14,13,15,16],drop:[11,16],separ:6,easili:16,exampl:[1,2,4,5,6,9,10,14,15,16],mode:[9,2,5],timeout:[1,2,5,14,15,9],autoincr:[1,2,5,14,15,9],found:4,unicod:[4,6,16,10,11,9],complet:[0,13,1,16,6],side:[14,13,2],mean:[3,6,2,10],compil:10,harm:4,replac:6,hard:16,idea:[11,1],each:[3,11,13,1,10],wrap:[1,2,5,14,15,9],redistribut:0,meta:16,expect:[11,4,1,9,16],backend_bas:[1,5],orient:[0,16],special:[3,6,1,11],out:16,ftp:2,shown:16,overridden:11,open:[1,2,6,5,14,15,9],publish:0,content:[11,16],rewrit:14,suitabl:[1,2,3,5,14,15,9],rel:[4,9,5],print:[6,16],metaclass:16,correct:[3,1,16],integr:[11,0,7],model:[11,0,16],insid:11,advanc:[1,2,5,11,14,15,9],another_db:4,runtimeerror:[1,2,5,14,15,9],differ:[3,5,1,16,10],free:[0,16],standard:5,lookupprocessordoesnotexist:1,orm:[11,0,16],dictionari:[3,4,6,5,13,16],nice:[6,4,16],ask:16,org:[0,12],ppl_named_guido:16,unpredict:16,basi:[2,5],prescrib:3,synchron:[1,2,5,14,15,9],keep:[11,6,13],filter:[1,2,10,9,5,11,14,13,15,16],thing:[3,6,16],length:[11,1,10],get_db:[4,9,16],place:3,isn:16,subtl:3,confus:3,imposs:[11,2],first:[1,2,10,6,9,5,14,15,16],origin:[0,9],softwar:0,reimplement:[1,2,5,14,15,9],directli:[4,1,16],blown:[9,2,5],feel:[0,16],media_root:6,bson:3,"__getitem__":[4,16],number:[14,1,15,16,10],yourself:[13,10],restrict:[3,16],reopen:[1,2,5,14,15,9],alreadi:[1,2,9,5,11,14,15,16],done:[6,16,2,5],least:1,blank:11,stabl:[4,15,9,5],ignorecas:10,primari:[1,2,3,9,5,14,13,15,16],size:[11,6],avail:[14,4,13,10],sourc:2,"long":6,process_outgo:6,convent:[1,16],data:[0,1,2,3,5,9,10,11,14,13,15,16],top:[11,16],system:10,wrapper:[1,2,5,14,15,9],mercuri:12,attach:6,necessarili:16,order_bi:[1,2,5,14,15,9],too:16,accept:16,termin:10,conveni:[0,7],bitter:6,store:[1,2,3,6,9,5,11,14,13,15,16],schema:[3,0,13,10],pkg_resourc:4,gnu:0,option:[0,1,2,3,4,5,9,10,14,15,16],namespac:3,shelf:5,tool:5,copi:[0,1,2,5,14,13,15,9],specifi:[1,2,6,5,11,14,13,9],direct:[1,2,9,5,14,13,15,16],mongodb:[3,14,7,1,5],part:[0,1,16,2,5],mostli:[14,2],date__month:[2,5],shelv:[4,7,5],textfield:11,exactli:[14,1],than:[16,2,9],serv:10,kind:[0,16],john:9,provid:[0,1,2,3,4,5,6,9,10,11,14,15,16],remov:[1,2,6,9,5,14,15,16],structur:[1,2,3,5,6,9,10,11,14,13,15,16],charact:6,project:[14,13],reus:16,label_attr:11,queryadapt:[14,9,15,2,5],bind:16,imagefield:6,thu:[1,2,5,14,15,9],pre:[1,16,10],sai:16,queryset:11,ani:[0,2,3,10,5,11,13,16],raw:4,netherland:16,from_db:1,have:[3,0,1,16],tabl:[0,9,16,10],need:[0,1,6,9,10,11,12,13,16],take:[11,10],notimplementederror:[1,2,5,14,15,9],exclud:4,distributionnotfound:4,caus:[16,10],date:[16,2,5],built:[0,16],equival:[14,1,10],unhash:[2,5],destroi:16,self:[11,4,9,16],note:[1,2,4,5,6,9,10,11,14,13,15,16],also:[12,3,4,6,10,16],without:[0,2,3,16,5,9],rewritten:16,which:[1,2,4,9,5,11,14,13,15,16],textareafield:11,environ:[9,16,5],noth:[3,16],singl:[1,2,3,5,14,15,9],compat:11,sure:16,unless:11,distribut:0,integerfield:11,principl:10,unsur:16,licens:0,oracl:2,multitud:16,most:[11,1,16,2,5],plai:6,regular:10,propertymanag:1,plan:9,pair:[1,2,5,14,15,9],subset:[0,13,1,16],querysetselectfield:11,"class":[1,2,3,4,5,6,9,10,11,14,13,15,16],warranti:0,appear:[11,16],exception_class:1,don:[16,10],ship:[7,16],url:10,doc:6,clear:[1,2,5,14,15,9],adopt:16,request:[0,1],wtform:[11,7,13,10],destruct:11,doe:[0,1,2,3,5,9,10,11,14,13,15,16],inde:16,ext:[2,4,6,9,5,11,14,15,16],declar:[11,13],birth_plac:16,declat:13,determin:[3,13,1,10],databas:[0,1,2,3,4,5,7,9,10,14,13,15,16],effect:13,usual:[3,11,1,16],microsoft:2,dot:[4,16],class_nam:4,show:4,"__str__":11,alphanumer:16,mongokit:[13,16],syntax:[6,16],concurr:9,hack:14,anywai:[3,1],filefield:6,involv:[14,13,2,5],despit:[9,16],onli:[0,1,2,3,5,9,10,11,14,13,15,16],coerc:4,locat:[11,4],just:[0,1,2,3,5,6,9,10,14,15,16],pretti:[6,4],personform:11,first_name__exist:[16,10],solut:1,state:[1,2,9,5,14,13,15,16],sugar:[6,16],"public":[0,13,1],parametr:2,dict:[1,2,5,14,13,15,9],analyz:2,over:[2,5],hope:[0,16],overwritten:13,rdbqcstreq:1,contribut:3,document_form_factori:11,get:[1,2,9,5,14,13,15,16],familiar:16,express:10,stop:[16,10],repr:4,repo:12,nativ:[1,16],amazon:2,cannot:[3,16,10],person_2:16,person_0:16,"0x3ba85e0":11,report:[0,9],none_of:10,neither:[0,12,16],requir:[2,3,4,5,6,9,10,11,13,16],bar:16,enabl:6,baz:16,yield:[3,1,9,2,5],patch:[0,9,14],rfc:16,"default":[1,2,4,6,9,5,11,14,13,15,16],stupid:13,common:[16,2],contain:[0,1,2,3,5,9,10,11,14,13,15,16],metadata:3,where:[1,2,3,5,6,9,10,14,15,16],valid:[0,1,2,3,5,6,9,10,11,14,13,15,16],silent:[2,5],summari:6,conform:[1,2,4,9,5,14,15,16],set:[1,2,3,4,5,10,11,14,13,16],tyrant:[7,15,16,9],dump:[6,16,2],fido:6,"float":[1,10],get_mani:[1,2,5,14,15,9],heavili:10,maximum:[11,10],datatyp:[6,1],see:[0,12,2,3,4,5,6,10,16],bare:6,result:[1,2,5,11,14,15,9],arg:[14,9,2,5],fail:[4,10],close:[1,2,5,14,15,9],dataprocessordoesnotexist:1,best:16,statu:[2,5,11,14,15,9],said:2,kei:[0,1,2,3,4,9,5,14,13,15,16],correctli:1,stopvalid:[11,10],pattern:10,someth:[13,16],berkelei:2,label:[11,6],"_foo":1,written:0,won:[11,16],blank_text:11,dynam:14,simplest:3,"import":[11,4,13,9,16],day_16_years_back:16,entiti:[0,16],approach:[6,16,14],across:0,attribut:[1,16],signatur:1,triplet:1,bound:13,syntact:16,extend:[6,1],numer:[1,2,5,14,15,9],attempt:[16,10],javascript:11,extens:[0,12,2,3,4,7,5,11,14,15,9],job:16,steroid:16,here:[16,2,10],solv:16,group:[6,16,2,5],come:[3,13],problem:16,from_storag:[1,2,5,14,13,15,9],popul:11,bodi:3,last:11,easi:[0,12,16],howev:[1,2,10,9,5,14,13,15,16],alon:10,equal:[3,4,1,10],against:[13,1,16,10],etc:3,tutori:[0,16],present:[3,6],basestr:1,mani:[11,13],age__gt:10,whole:[0,1,2,5,14,15,9],load:[6,4,16],tctdbiternext3:[9,2,5],simpli:10,outgoing_processor:6,technic:3,point:16,wall:16,inspir:[11,13,10],equalto:10,rdbqcnumeq:1,db_set:9,featur:[0,16],path:[4,9,16,5],batteri:7,respect:16,assum:[4,1,16],backend:[0,1,2,3,4,7,8,9,5,14,13,15,16],get_or_cr:[1,2,5,14,15,9],basestorageadapt:[4,1,5],decent:[2,5],invert:[1,2,5,14,15,9],somedocu:4,fro:16,mari:9,empti:[3,6,16,10,13,9],mark:16,belong:[11,16,10],json:[3,2],much:[1,2,10,9,5,14,15,16],valu:[0,1,2,3,4,5,6,9,10,11,14,13,15,16],interest:16,basic:[1,2,9,5,14,15,16],shove_db:2,futur:[6,4],immedi:[1,2,5,14,15,9],valueerror:1,"__len__":[1,9,2,5],quickli:16,box:16,both:[11,16],validation_stop:11,presenc:16,imag:6,xxx:16,search:[0,16],argument:11,assert:9,andrei:0,understand:16,togeth:6,child:16,"catch":1,cache_uri:2,jpg:6,query_adapt:[9,2,5],those:16,"case":[11,1,16,5],multi:4,uncertain:9,look:[3,16],packag:4,servic:2,properti:[1,2,3,6,9,5,11,14,15,16],easier:16,lesser:0,defin:[0,1,2,10,5,11,13,16],calcul:[16,2],unifi:[1,16,5],match:[1,2,10,5,11,14,15,9],abov:[16,10],error:[11,10],glossari:[3,0],birth_date__gt:16,fixtur:4,observ:16,layer:[0,1],readi:1,filewrapp:6,non:16,rip:10,some_class:4,kwarg:[11,6],clutter:16,zodb:2,lightweight:0,incom:[11,10],dedic:16,sever:13,parent:16,guido:16,develop:16,welcom:[14,9],author:0,perform:[16,2],make:[13,16,2,5],couchdb:3,document_bas:13,same:[1,2,3,10,9,5,11,14,15,16],handl:[6,13,5],instanc:[1,2,4,5,6,9,10,11,14,13,15,16],decod:1,descend:[1,2,5,14,15,9],zope:2,mydoc:16,document:[0,1,2,3,4,5,6,7,8,9,10,11,14,13,15,16],emailfield:[6,16],agnost:1,ascend:[1,2,5,14,15,9],higher:0,http:[0,12],optim:[9,16,2,5],cach:2,nest:3,tld:10,upon:0,someon:16,hand:6,capabl:10,post_valid:11,temporari:2,user:[4,10],countri:16,extern:[6,1,5],suffix:10,ipaddress:10,chang:[1,2,4,6,9,5,14,15,16],expand:4,task:11,off:[16,10],choos:16,nevertheless:13,colour:16,min:10,well:[4,16],inherit:[0,16],pickl:[6,5],person:[11,9,16,10],client:[14,2],thi:[0,1,2,3,4,5,6,9,10,11,14,13,15,16],filesystem:2,everyth:[11,10],documentselectfield:11,processordoesnotexist:1,left:[2,5],construct:[11,4],identifi:3,to_db:1,execut:1,less:0,photo:6,tct:[4,9,16],obtain:4,activ:10,align:[6,4],birth_dat:16,invalid:[3,13,10],mysql:2,touch:16,yep:16,speed:[2,5],yet:[1,2,5,14,13,15,9],previous:16,web:2,extra_valid:11,expos:16,danger:13,had:16,except:[11,4,1,16,10],littl:16,populate_obj:11,add:[3,16,10],is_valid:10,schemata:[0,16],appli:[11,10],els:[11,10],distinguish:16,save:[1,2,3,5,6,9,10,14,13,15,16],smart:[2,5],build:14,real:14,applic:[0,16,2,5],settings_dict:4,use_dot_not:16,around:[1,2,6,5,14,15,9],format:[6,4,1,16,2],read:[6,4,16],prefer:16,subfield:11,piec:3,know:[13,16],birth:16,thoroughli:16,bit:[5,16,2,10],recurs:5,prarm:4,ineffici:[9,2,5],daemon:16,like:[2,3,4,10,5,11,13,16],specif:[1,2,4,9,5,14,15,16],arbitrari:[3,6,5],rossum:16,manual:11,resolv:[1,10],integ:10,server:[14,2],collect:[3,14,10],pyrant:[15,9],api:[0,1,2,3,4,6,8,9,5,11,14,13,16],necessari:9,either:[0,1,2,4,5,11,14,15,9],fill:[13,16],ttserver:16,per:[1,2,9,5,14,15,16],prior:10,manag:[1,16],underli:[1,2,4,5,14,9],rdbcnumeq:1,revers:[1,2,5,14,15,9],old:16,who:16,deal:[16,10],mikhaylenko:0,some:[12,2,3,4,5,7,9,10,1,13,14,15,16],back:[13,16],contribute_to_queri:13,born:16,intern:[1,2,5,14,15,9],repeat:[13,10],"export":16,random:[1,2,5,14,15,9],proper:[4,16,2],guess:[11,1,16],as_repr:4,librari:[0,1,2,4,7,9,5,12,16],numberrang:10,other_valu:10,friend:16,birth_date__exist:16,avoid:3,though:9,definit:[6,16],"__getattr__":16,when:[1,3,6,10,11,13,16],"__unicode__":[11,9,16],outgo:13,basequeryadapt:1,noneof:10,condit:[1,2,3,10,9,5,14,15,16],foo:[6,4,1,16],localhost:[16,10],refer:[0,1,2,4,8,9,5,11,14,13,15,16],object:[0,1,2,3,4,5,6,9,10,11,14,13,15,16],run:[11,13,16],pre_valid:11,word:[0,16],view:[11,16],usag:[6,4,1,9,10],broken:[1,2,5,14,15,9],host:[14,16],great:16,regexp:10,between:[3,1],plug:16,comparison:[2,5],about:[3,16],obj:11,firebird:2,constraint:16,column:[4,9,15,2,5],processor:1,beta:[11,14,9,2],page:0,unsav:4,messag:[4,10],constructor:11,book:[6,16],any_of:10,fulfil:10,aha:16,effici:[1,2,5,14,15,9],proto:1,guidlin:16,elementari:1,within:[1,2,3,5,14,15,9],encod:1,domain:10,automat:[11,6,16],due:[2,5],down:11,right:[2,5],lookup_manag:1,ensur:[1,16,10],nameless:16,camel_case_to_underscor:4,storag:[0,1,2,3,4,9,5,11,14,13,15,16],your:[0,16,6],merg:16,inclus:10,fast:9,van:16,wai:[12,2,4,6,9,5,11,1,13,14,15,16],support:[1,2,6,9,5,14,15,16],question:[0,16],submit:[11,0],custom:[1,16],verbos:16,width:4,compliant:11,trigger:6,interfac:[16,2,5],includ:[4,5,7,13,10],lot:5,overhead:[9,2,5],strictli:[1,2,5,14,15,9],my_doc:16,"function":[11,6,4],larri:16,form:[11,1,2],offer:[3,11,2],conclud:16,bundl:[3,4,2,5],regard:1,keyerror:[1,2,5,14,15,9],load_fixtur:4,cabinet:[7,1,15,16,9],sqlalchemi:2,translat:[4,1],where_not:[1,2,10,5,14,15,9],metasearch:9,line:[11,6,4,16],anyof:[16,10],"true":[1,2,4,5,6,9,10,11,14,13,15,16],bug:[0,9],faster:[9,2,5],reset:[1,2,5,14,15,9],notat:16,rememb:16,flavour:9,input:[11,10],possibl:[1,2,4,5,13,16],whether:[3,13,9],wish:16,access:[16,2,9],displai:[11,10],"abstract":[0,7,13,1,6],record:[1,2,3,5,6,9,10,14,13,15,16],below:16,limit:[2,5],embed:9,unrel:13,email:[16,10],connect:[1,2,9,5,11,14,15,16],later:[0,10],creat:[1,2,4,6,9,5,11,14,15,16],"int":[11,1],certain:[3,0,4,1,16],dure:11,exact_match:1,doesn:[0,14],repres:[3,13,16],exist:[0,1,2,4,5,6,9,10,11,14,13,15,16],rule:1,file:[0,1,2,4,6,9,5,14,15,16],tokyo_tyr:[4,15,16],pip:12,duru:2,improv:[14,2],check:[13,1,10],probabl:[16,10],again:[1,2,5,14,15,9],surpris:16,documentmetadata:6,require_tld:10,titl:6,uri:2,excel:5,detail:[3,0,1,10],refactor:[14,9],end:10,field:[0,1,3,6,7,8,9,10,11,14,13,15,16],other:[0,1,3,7,9,10,11,12,13,16],bool:[14,1,15,9,10],rdbm:2,normal:[1,2,4,6,5,11,14,15,9],suppress:10,test:[1,3,4,16,5,9],you:[0,1,2,3,5,9,10,11,12,13,14,15,16],pymongo:14,shrink:11,runtim:16,deifin:16,intend:[14,9],sequenc:[16,10],formdata:11,get_storag:16,docstr:1,base_path:6,"_tc_test":9,livingb:16,slice:1,consid:[4,13,16,2],sql:2,anybodi:16,stai:6,outdat:[6,16],femal:16,receiv:0,longer:16,directori:6,came:16,doc_class:[1,2,5,14,15,9],notion:[1,2,5,14,13,15,9],portion:10,name__match:9,ignor:[2,5],gracefulli:[1,2,5,14,15,9],potenti:13,time:16,push:16,appl:16,daili:16,prototyp:16},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:exception","5":"py:function","6":"py:classmethod"},titles:["Easy data modeling with Doqu","Backend API","Shove extension","Glossary","Utilities","Shelve extension","Document Fields","Extensions","API reference","Tokyo Cabinet extension","Validators","WTForms extension","Installation","Document API","MongoDB extension","Tokyo Tyrant extension","Tutorial"],objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","exception","Python exception"],"5":["py","function","Python function"],"6":["py","classmethod","Python class method"]},filenames:["index","backend_base","ext_shove","glossary","utils","ext_shelve","ext_fields","ext","api","ext_tokyo_cabinet","validators","ext_forms","installation","document","ext_mongodb","ext_tokyo_tyrant","tutorial"]})PK1S/BÍÊûûdoqu-latest/genindex.html Index — Docu 0.28.2 documentation

Index

A | B | C | D | E | F | G | I | L | M | N | O | P | Q | R | S | T | U | V | W

A

any_of (in module doqu.validators)
AnyOf (class in doqu.validators)

B

BaseQueryAdapter (class in doqu.backend_base)
BaseStorageAdapter (class in doqu.backend_base)

C

camel_case_to_underscores() (in module doqu.utils)
clear() (doqu.backend_base.BaseStorageAdapter method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)
connect() (doqu.backend_base.BaseStorageAdapter method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)
contribute_to_query() (doqu.document_base.Document class method)
ConverterManager (class in doqu.backend_base)
count() (doqu.backend_base.BaseQueryAdapter method)
(doqu.ext.mongodb.QueryAdapter method)
(doqu.ext.shelve_db.QueryAdapter method)
(doqu.ext.shove_db.QueryAdapter method)
(doqu.ext.tokyo_cabinet.QueryAdapter method)
(doqu.ext.tokyo_tyrant.query.QueryAdapter method)

D

DataProcessorDoesNotExist
delete() (doqu.backend_base.BaseQueryAdapter method)
(doqu.backend_base.BaseStorageAdapter method)
(doqu.document_base.Document method)
(doqu.ext.mongodb.QueryAdapter method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.QueryAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.QueryAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.QueryAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.query.QueryAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)
disconnect() (doqu.backend_base.BaseStorageAdapter method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)
document
Document (class in doqu.document_base)
document query
document_form_factory() (in module doqu.ext.forms)
DocumentSelectField (class in doqu.ext.forms)
doqu.backend_base (module)
doqu.document_base (module)
doqu.ext.fields (module)
doqu.ext.forms (module)
doqu.ext.mongodb (module)
doqu.ext.shelve_db (module)
doqu.ext.shove_db (module)
doqu.ext.tokyo_cabinet (module)
doqu.ext.tokyo_tyrant (module)
doqu.utils (module)
doqu.validators (module)
dump_doc() (in module doqu.utils)

E

Email (class in doqu.validators)
email (in module doqu.validators)
equal_to (in module doqu.validators)
Equals (class in doqu.validators)
equals (in module doqu.validators)
EqualTo (class in doqu.validators)
exception_class (doqu.backend_base.ConverterManager attribute)
(doqu.backend_base.LookupManager attribute)
Exists (class in doqu.validators)
exists (in module doqu.validators)

F

field
Field (class in doqu.ext.fields)
file_wrapper_class (doqu.ext.fields.FileField attribute)
(doqu.ext.fields.ImageField attribute)
FileField (class in doqu.ext.fields)
find() (doqu.backend_base.BaseStorageAdapter method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)
from_db() (doqu.backend_base.ConverterManager method)
from_storage() (doqu.document_base.Document class method)

G

get() (doqu.backend_base.BaseStorageAdapter method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)
get_db() (in module doqu.utils)
get_many() (doqu.backend_base.BaseStorageAdapter method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)
get_or_create() (doqu.backend_base.BaseStorageAdapter method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)

I

ImageField (class in doqu.ext.fields)
ip_address (in module doqu.validators)
IPAddress (class in doqu.validators)

L

Length (class in doqu.validators)
length (in module doqu.validators)
load_fixture() (in module doqu.utils)
LookupManager (class in doqu.backend_base)
LookupProcessorDoesNotExist

M

Many (in module doqu.document_base)

N

none_of (in module doqu.validators)
NoneOf (class in doqu.validators)
number_range (in module doqu.validators)
NumberRange (class in doqu.validators)

O

Optional (class in doqu.validators)
optional (in module doqu.validators)
order_by() (doqu.backend_base.BaseQueryAdapter method)
(doqu.ext.mongodb.QueryAdapter method)
(doqu.ext.shelve_db.QueryAdapter method)
(doqu.ext.shove_db.QueryAdapter method)
(doqu.ext.tokyo_cabinet.QueryAdapter method)
(doqu.ext.tokyo_tyrant.query.QueryAdapter method)

P

pk (doqu.document_base.Document attribute)
populate_obj() (doqu.ext.forms.DocumentSelectField method)
(doqu.ext.forms.QuerySetSelectField method)
post_validate() (doqu.ext.forms.DocumentSelectField method)
(doqu.ext.forms.QuerySetSelectField method)
process() (doqu.ext.forms.DocumentSelectField method)
(doqu.ext.forms.QuerySetSelectField method)
process_data() (doqu.ext.forms.DocumentSelectField method)
(doqu.ext.forms.QuerySetSelectField method)
ProcessorDoesNotExist

Q

query_adapter (doqu.ext.shelve_db.StorageAdapter attribute)
(doqu.ext.shove_db.StorageAdapter attribute)
(doqu.ext.tokyo_cabinet.StorageAdapter attribute)
QueryAdapter (class in doqu.ext.mongodb)
(class in doqu.ext.shelve_db)
(class in doqu.ext.shove_db)
(class in doqu.ext.tokyo_cabinet)
(class in doqu.ext.tokyo_tyrant.query)
QuerySetSelectField (class in doqu.ext.forms)

R

reconnect() (doqu.backend_base.BaseStorageAdapter method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)
record
Regexp (class in doqu.validators)
regexp (in module doqu.validators)
Required (class in doqu.validators)
required (in module doqu.validators)
resolve() (doqu.backend_base.LookupManager method)

S

save() (doqu.backend_base.BaseStorageAdapter method)
(doqu.document_base.Document method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)
schema
StopValidation
storage
StorageAdapter (class in doqu.ext.mongodb)
(class in doqu.ext.shelve_db)
(class in doqu.ext.shove_db)
(class in doqu.ext.tokyo_cabinet)
(class in doqu.ext.tokyo_tyrant.storage)
sync() (doqu.backend_base.BaseStorageAdapter method)
(doqu.ext.mongodb.StorageAdapter method)
(doqu.ext.shelve_db.StorageAdapter method)
(doqu.ext.shove_db.StorageAdapter method)
(doqu.ext.tokyo_cabinet.StorageAdapter method)
(doqu.ext.tokyo_tyrant.storage.StorageAdapter method)

T

to_db() (doqu.backend_base.ConverterManager method)

U

URL (class in doqu.validators)
url (in module doqu.validators)

V

validate() (doqu.document_base.Document method)
(doqu.ext.forms.DocumentSelectField method)
(doqu.ext.forms.QuerySetSelectField method)
ValidationError
validator
values() (doqu.backend_base.BaseQueryAdapter method)
(doqu.ext.mongodb.QueryAdapter method)
(doqu.ext.shelve_db.QueryAdapter method)
(doqu.ext.shove_db.QueryAdapter method)
(doqu.ext.tokyo_cabinet.QueryAdapter method)
(doqu.ext.tokyo_tyrant.query.QueryAdapter method)

W

where() (doqu.backend_base.BaseQueryAdapter method)
(doqu.ext.mongodb.QueryAdapter method)
(doqu.ext.shelve_db.QueryAdapter method)
(doqu.ext.shove_db.QueryAdapter method)
(doqu.ext.tokyo_cabinet.QueryAdapter method)
(doqu.ext.tokyo_tyrant.query.QueryAdapter method)
where_not() (doqu.backend_base.BaseQueryAdapter method)
(doqu.ext.mongodb.QueryAdapter method)
(doqu.ext.shelve_db.QueryAdapter method)
(doqu.ext.shove_db.QueryAdapter method)
(doqu.ext.tokyo_cabinet.QueryAdapter method)
(doqu.ext.tokyo_tyrant.query.QueryAdapter method)

Project Versions

PK1S/B‡Ø½7J*J*doqu-latest/ext.html Extensions — Docu 0.28.2 documentation

Extensions¶

Doqu ships with some batteries included.

Convenience abstractions¶

Integration with other libraries¶

Project Versions

Table Of Contents

Previous topic

Utilities

Next topic

Shelve extension

This Page

PK1S/B;oJgJgdoqu-latest/ext_shove.html Shove extension — Docu 0.28.2 documentation

Shove extension¶

A storage/query backend for shove which is bundled with Python.

status:beta
database:any supported by shove: storage — Amazon S3 Web Service, Berkeley Source Database, Filesystem, Firebird, FTP, DBM, Durus, Memory, Microsoft SQL Server, MySQL, Oracle, PostgreSQL, SQLite, Subversion, Zope Object Database (ZODB); caching — Filesystem, Firebird, memcached, Memory, Microsoft SQL Server, MySQL, Oracle, PostgreSQL, SQLite
dependencies:shove
suitable for:“smart” interface to a key/value store; temporary memory storage

This extension wraps the shove library and provides the uniform query API along with support for Document API.

Note

Regardless of the underlying storage, Shove serializes the records and only offers access by primary key. This means that efficient queries are impossible even with RDBMS; moreover, such databases are more likely to perform slower than simple key/value stores. The Docu queries with Shove involve iterating over the full set of records on client side and making per-row comparison without proper indexing.

That said, the backend is considered not suitable for applications that depend on queries and require decent speed of lookups by value. However, it can be very useful as a memory storage (e.g. to analyze a JSON dump or calculate some data on the fly) or as an improved interface to an existing pure key/value storage which is mostly used without advanced queries.

class doqu.ext.shove_db.StorageAdapter(**kw)¶

All parametres are optional. Here are the most common:

Parameters:
  • store_uri – URI for the data store
  • cache_uri – URI for the caching instance

The URI format for a backend is documented in its module (see the shove documentation). The URI form is the same as SQLAlchemy’s.

clear()¶

Clears the whole storage from data, resets autoincrement counters.

connect()¶

Connects to the database. Raises RuntimeError if the connection is not closed yet. Use reconnect() to explicitly close the connection and open it again.

delete(key)¶

Deletes record with given primary key.

disconnect()¶

Closes internal store and removes the reference to it. If the backend works with a file, then all pending changes are saved now.

find(doc_class=<type 'dict'>, **conditions)¶

Returns instances of given class, optionally filtered by given conditions.

Parameters:
  • doc_class – Document class. Default is dict. Normally you will want a more advanced class, such as Document or its more concrete subclasses (with explicit structure and validators).
  • conditions – key/value pairs, same as in where().

Note

By default this returns a tuple of (key, data_dict) per item. However, this can be changed if doc_class provides the method from_storage(). For example, Document has the notion of “saved state” so it can store the key within. Thus, only a single Document object is returned per item.

get(key, doc_class=<type 'dict'>)¶

Returns document instance for given document class and primary key. Raises KeyError if there is no item with given key in the database.

Parameters:
  • key – a numeric or string primary key (as supported by the backend).
  • doc_class – a document class to wrap the data into. Default is dict.
get_many(keys, doc_class=<type 'dict'>)¶

Returns an iterator of documents with primary keys from given list. Basically this is just a simple wrapper around get() but some backends can reimplement the method in a much more efficient way.

get_or_create(doc_class=<type 'dict'>, **conditions)¶

Queries the database for records associated with given document class and conforming to given extra conditions. If such records exist, picks the first one (the order may be random depending on the database). If there are no such records, creates one.

Returns the document instance and a boolean value “created”.

query_adapter¶

alias of QueryAdapter

reconnect()¶

Gracefully closes current connection (if it’s not broken) and connects again to the database (e.g. reopens the file).

save(key, data)¶

Saves given data with given primary key into the storage. Returns the primary key.

Parameters:
  • key – the primary key for given object; if None, will be generated.
  • data – a dict containing all properties to be saved.

Note that you must provide current primary key for a record which is already in the database in order to update it instead of copying it.

sync()¶

Synchronizes the storage to disk immediately if the backend supports this operation. Normally the data is synchronized either on save(), or on timeout, or on disconnect(). This is strictly backend-specific. If a backend does not support the operation, NotImplementedError is raised.

class doqu.ext.shove_db.QueryAdapter(*args, **kw)¶

The Query class.

count()¶

Same as __len__ but a bit faster.

delete()¶

Deletes all records that match current query.

order_by(names, reverse=False)¶

Defines order in which results should be retrieved.

Parameters:
  • names – the names of columns by which the ordering should be done. Can be an iterable with strings or a single string.
  • reverse – If True, direction changes from ascending (default) to descending.

Examples:

q.order_by('name')                  # ascending
q.order_by('name', reverse=True)    # descending

If multiple names are provided, grouping is done from left to right.

Note

while you can specify the direction of sorting, it is not possible to do it on per-name basis due to backend limitations.

Warning

ordering implementation for this database is currently inefficient.

values(name)¶

Returns an iterator that yields distinct values for given column name.

Supports date parts (i.e. date__month=7).

Note

this is currently highly inefficient because the underlying library does not support columns mode (tctdbiternext3). Moreover, even current implementation can be optimized by removing the overhead of creating full-blown document objects.

Note

unhashable values (like lists) are silently ignored.

where(**conditions)¶

Returns Query instance filtered by given conditions. The conditions are specified by backend’s underlying API.

where_not(**conditions)¶

Returns Query instance. Inverted version of where().

Project Versions

Previous topic

Shelve extension

Next topic

Tokyo Cabinet extension

This Page

PK1S/Bv .$.$doqu-latest/installation.html Installation — Docu 0.28.2 documentation

Installation¶

As easy as it can be:

$ pip install doqu

Another way is to use the Mercurial repo:

$ hg clone http://bitbucket.org/neithere/doqu
$ cd doqu
$ ./setup.py install

You may also need to install some other libraries (see Extensions).

Project Versions

Previous topic

Easy data modeling with Doqu

Next topic

Tutorial

This Page

PK1S/B ñRCîZîZdoqu-latest/ext_mongodb.html MongoDB extension — Docu 0.28.2 documentation

MongoDB extension¶

A storage/query backend for MongoDB.

status:beta
database:MongoDB
dependencies:pymongo
suitable for:general purpose (mostly server-side)

Warning

this module is not intended for production. It contains some hacks and should be refactored. However, it is actually used in a real project involving complex queries. Patches, improvements, rewrites are welcome.

class doqu.ext.mongodb.StorageAdapter(**kw)¶
Parameters:
  • host
  • port
  • database
  • collection
clear()¶

Clears the whole storage from data, resets autoincrement counters.

connect()¶

Connects to the database. Raises RuntimeError if the connection is not closed yet. Use reconnect() to explicitly close the connection and open it again.

delete(key)¶

Deletes record with given primary key.

disconnect()¶

Closes internal store and removes the reference to it. If the backend works with a file, then all pending changes are saved now.

find(doc_class=<type 'dict'>, **conditions)¶

Returns instances of given class, optionally filtered by given conditions.

Parameters:
  • doc_class – Document class. Default is dict. Normally you will want a more advanced class, such as Document or its more concrete subclasses (with explicit structure and validators).
  • conditions – key/value pairs, same as in where().

Note

By default this returns a tuple of (key, data_dict) per item. However, this can be changed if doc_class provides the method from_storage(). For example, Document has the notion of “saved state” so it can store the key within. Thus, only a single Document object is returned per item.

get(key, doc_class=<type 'dict'>)¶

Returns document instance for given document class and primary key. Raises KeyError if there is no item with given key in the database.

Parameters:
  • key – a numeric or string primary key (as supported by the backend).
  • doc_class – a document class to wrap the data into. Default is dict.
get_many(keys, doc_class=<type 'dict'>)¶

Returns an iterator of documents with primary keys from given list. Basically this is just a simple wrapper around get() but some backends can reimplement the method in a much more efficient way.

get_or_create(doc_class=<type 'dict'>, **conditions)¶

Queries the database for records associated with given document class and conforming to given extra conditions. If such records exist, picks the first one (the order may be random depending on the database). If there are no such records, creates one.

Returns the document instance and a boolean value “created”.

reconnect()¶

Gracefully closes current connection (if it’s not broken) and connects again to the database (e.g. reopens the file).

save(key, data)¶

Saves given data with given primary key into the storage. Returns the primary key.

Parameters:
  • key – the primary key for given object; if None, will be generated.
  • data – a dict containing all properties to be saved.

Note that you must provide current primary key for a record which is already in the database in order to update it instead of copying it.

sync()¶

Synchronizes the storage to disk immediately if the backend supports this operation. Normally the data is synchronized either on save(), or on timeout, or on disconnect(). This is strictly backend-specific. If a backend does not support the operation, NotImplementedError is raised.

class doqu.ext.mongodb.QueryAdapter(*args, **kw)¶
count()¶

Returns the number of records that match given query. The result of q.count() is exactly equivalent to the result of len(q) but does not involve fetching of the records.

delete()¶

Deletes all records that match current query.

order_by(names, reverse=False)¶

Returns a query object with same conditions but with results sorted by given field. By default the direction of sorting is ascending.

Parameters:
  • names – list of strings: names of fields by which results should be sorted. Some backends may only support a single field for sorting.
  • reversebool: if True, the direction of sorting is reversed and becomes descending. Default is False.
values(name)¶

Returns a list of unique values for given field name.

Parameters:name – the field name.

Note

A set is dynamically build on client side if the query contains conditions. If it doesn’t, a much more efficient approach is used. It is only available within current connection, not query.

where(**conditions)¶

Returns Query instance filtered by given conditions. The conditions are specified by backend’s underlying API.

where_not(**conditions)¶

Returns Query instance. Inverted version of where().

Project Versions

Previous topic

Tokyo Tyrant extension

Next topic

Document Fields

This Page

PK1S/B´iÏlBBdoqu-latest/search.html Search — Docu 0.28.2 documentation

Search

Please activate JavaScript to enable the search functionality.

From here you can search these documents. Enter your search words into the box below and click "search". Note that the search function will automatically search for all of the words. Pages containing fewer words won't appear in the result list.

Project Versions

PK1S/B!Ø…³ê#ê#doqu-latest/api.html API reference — Docu 0.28.2 documentation

Project Versions

Previous topic

WTForms extension

Next topic

Document API

This Page

PK1S/BŽ·¥ÙA6A6doqu-latest/glossary.html Glossary — Docu 0.28.2 documentation

Glossary¶

storage

A place where data is stored. Provides a single namespace. Key/value stores can be represented with a single storage object, some other databases will require multiple storage objects (e.g. each “database” of CouchDB or each “collection” of MongoDB). Docu does not use nested namespaces because in document databases they mean nothing anyway.

Doqu offers a uniform API for different databases by providing “storage adapters”. See Backend API for technical details and Extensions for a list of adapters bundled with Docu.

record
A piece of data identified by an arbitrary unique primary key in a storage. In key/value stores the body of the record will be called “value” (usually serialized to a string); in other databases it is called “document” (also serialized as JSON, BSON, etc.). To avoid confusion we call all these things “records”. In Python the record is represented as a dictionary of fields.
field
A named property of a record or document. Records are actually containers for fields. There can be only one field with given name in the same record/document.
document

An dictionary with metadata. Can be associated with a record in a storage. The structure can be restricted by schema. Optional validators determine how should the document look before it can be saved into the storage, or what records can be associated with documents of given class. Special behaviour can abe added with methods of the Document subclass (see Document API).

The simplest document is just a dictionary with some metadata. The metadata can be empty or contain information about where the document comes from, what does its record look like, etc.

A document without schema or validators is equal to its record. A document with schema is only equal to the record if they have the same sets of fields and these fields are valid (i.e. have correct data types and pass certain tests).

As you see, there is a difference between documents and records but sometimes it’s very subtle.

schema
A mapping of field names to Python data types. Prescribes the structure of a document.
validator
Contains a certain test. When associated with a field of a document, determines whether given value is suitable for the field and, therefore, whether the document is valid in general. An invalid document cannot be saved to the storage. A validator can also contribute to the document query. See Validators for details on how this works.
document query
A query that yields all records within given storage that can be associated with certain document. A document without validators does not add any conditions to the query, i.e. yields all records whatever structure they have. Validators can require that some fields are present or pass certain tests.

Project Versions

Previous topic

Tutorial

Next topic

Validators

This Page

PK1S/B³Fd„ÞiÞidoqu-latest/ext_forms.html WTForms extension — Docu 0.28.2 documentation

WTForms extension¶

Offers integration with WTForms.

status:beta
dependencies:wtforms

The extension provides two new field classes: QuerySetSelectField and DocumentSelectField (inspired by wtforms.ext.django.*). They connect the forms with the Doqu API for queries. You can manually create forms with these fields.

The easiest way to create a Document-compliant form is using the function document_form_factory(). It returns a form class based on the document structure:

from doqu import Document
from doqu import validators
from doqu.ext.forms import document_form_factory

class Location(Document):
    structure = {'name': unicode}

class Person(Document):
    structure = {'name': unicode, 'age': int, 'location': Location}
    labels = {'name': 'Full name', 'age': 'Age', 'location': 'Location'}
    validators = {'name': [required()]}

PersonForm = document_form_factory(Person)

The last line does the same as this code:

from wtforms import TextField, IntegerField, validators
from doqu.ext.forms import DocumentSelectField

class PersonForm(wtforms.Form):
    name = TextField('Full name', [validators.Required()])
    age = IntegerField('Age')
    location = DocumentSelectField('Location', [], Location)
doqu.ext.forms.document_form_factory(document_class, storage=None)¶

Expects a Document instance, creates and returns a wtforms.Form class for this model.

The form fields are selected depending on the Python type declared by each property.

Parameters:
  • document_class – the Doqu document class for which the form should be created
  • storage – a Doqu-compatible storage; we need it to generate lists of choices for references to other models. If not defined, references will not appear in the form.

Caveat: the unicode type can be mapped to TextField and TextAreaField. It is impossible to guess which one should be used unless maximum length is defined for the property. TextAreaField is picked by default. It is a good idea to automatically shrink it with JavaScript so that its size always matches the contents.

class doqu.ext.forms.QuerySetSelectField(label=u'', validators=None, queryset=None, label_attr='', allow_blank=False, blank_text=u'', **kw)¶

Given a QuerySet either at initialization or inside a view, will display a select drop-down field of choices. The data property actually will store/keep an ORM model instance, not the ID. Submitting a choice which is not in the queryset will result in a validation error.

Specifying label_attr in the constructor will use that property of the model instance for display in the list, else the model object’s __str__ or __unicode__ will be used.

If allow_blank is set to True, then a blank choice will be added to the top of the list. Selecting this choice will result in the data property being None. The label for the blank choice can be set by specifying the blank_text parameter.

populate_obj(obj, name)¶

Populates obj.<name> with the field’s data.

Note :This is a destructive operation. If obj.<name> already exists, it will be overridden. Use with caution.
post_validate(form, validation_stopped)¶

Override if you need to run any field-level validation tasks after normal validation. This shouldn’t be needed in most cases.

Parameters:
  • form – The form the field belongs to.
  • validation_stoppedTrue if any validator raised StopValidation.
process(formdata, data=<object object at 0x3ba85e0>)¶

Process incoming data, calling process_data, process_formdata as needed, and run filters.

If data is not provided, process_data will be called on the field’s default.

Field subclasses usually won’t override this, instead overriding the process_formdata and process_data methods. Only override this for special advanced processing, such as when a field encapsulates many inputs.

process_data(value)¶

Process the Python data applied to this field and store the result.

This will be called during form construction by the form’s kwargs or obj argument.

Parameters:value – The python object containing the value to process.
validate(form, extra_validators=())¶

Validates the field and returns True or False. self.errors will contain any errors raised during validation. This is usually only called by Form.validate.

Subfields shouldn’t override this, but rather override either pre_validate, post_validate or both, depending on needs.

Parameters:
  • form – The form the field belongs to.
  • extra_validators – A list of extra validators to run.
class doqu.ext.forms.DocumentSelectField(label=u'', validators=None, document_class=None, storage=None, **kw)¶

Like a QuerySetSelectField, except takes a document class instead of a queryset and lists everything in it.

populate_obj(obj, name)¶

Populates obj.<name> with the field’s data.

Note :This is a destructive operation. If obj.<name> already exists, it will be overridden. Use with caution.
post_validate(form, validation_stopped)¶

Override if you need to run any field-level validation tasks after normal validation. This shouldn’t be needed in most cases.

Parameters:
  • form – The form the field belongs to.
  • validation_stoppedTrue if any validator raised StopValidation.
process(formdata, data=<object object at 0x3ba85e0>)¶

Process incoming data, calling process_data, process_formdata as needed, and run filters.

If data is not provided, process_data will be called on the field’s default.

Field subclasses usually won’t override this, instead overriding the process_formdata and process_data methods. Only override this for special advanced processing, such as when a field encapsulates many inputs.

process_data(value)¶

Process the Python data applied to this field and store the result.

This will be called during form construction by the form’s kwargs or obj argument.

Parameters:value – The python object containing the value to process.
validate(form, extra_validators=())¶

Validates the field and returns True or False. self.errors will contain any errors raised during validation. This is usually only called by Form.validate.

Subfields shouldn’t override this, but rather override either pre_validate, post_validate or both, depending on needs.

Parameters:
  • form – The form the field belongs to.
  • extra_validators – A list of extra validators to run.

Project Versions

Previous topic

Document Fields

Next topic

API reference

This Page

PK1S/Bêæædoqu-latest/.buildinfo# Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. config: 51a1569af874c120f3d94235bf50bc70 tags: fbb0d17656682115ca4d033fb2f83ba1 PK1S/BãË< F>F>doqu-latest/document.html Document API — Docu 0.28.2 documentation

Document API¶

Documents represent database records. Each document is a (in)complete subset of fields contained in a record. Available data types and query mechanisms are determined by the storage in use.

The API was inspired by Django, MongoKit, WTForms, Svarga and several other projects. It was important to KISS (keep it simple, stupid), DRY (do not repeat yourself) and to make the API as abstract as possible so that it did not depend on backends and yet did not get in the way.

class doqu.document_base.Document(**kw)¶

A document/query object. Dict-like representation of a document stored in a database. Includes schema declaration, bi-directional validation (outgoing and query), handles relations and has the notion of the saved state, i.e. knows the storage and primary key of the corresponding record.

classmethod contribute_to_query(query)¶

Returns given query filtered by schema and validators defined for this document.

delete()¶

Deletes the object from the associated storage.

classmethod from_storage(storage, key, data)¶

Returns a document instance filled with given data and bound to given storage and key. The instance can be safely saved back using save(). If the concrete subclass defines the structure, then usused fields coming from the storage are hidden from the public API but nevertheless they will be saved back to the database as is.

pk¶

Returns current primary key (if any) or None.

save(storage=None, keep_key=False)¶

Saves instance to given storage.

Parameters:
  • storage – the storage to which the document should be saved. If not specified, default storage is used (the one from which the document was retrieved of to which it this instance was saved before).
  • keep_key – if True, the primary key is preserved even when saving to another storage. This is potentially dangerous because existing unrelated records can be overwritten. You will only need this when copying a set of records that reference each other by primary key. Default is False.
validate()¶

Checks if instance data is valid. This involves a) checking whether all values correspond to the declated structure, and b) running all Validators against the data dictionary.

Raises ValidationError if something is wrong.

Note

if the data dictionary does not contain some items determined by structure or validators, these items are not checked.

Note

The document is checked as is. There are no side effects. That is, if some required values are empty, they will be considered invalid even if default values are defined for them. The save() method, however, fills in the default values before validating.

doqu.document_base.Many¶

alias of OneToManyRelation

Project Versions

Previous topic

API reference

Next topic

Document Fields

This Page

PK1S/Bð†c’’doqu-latest/objects.inv# Sphinx inventory version 2 # Project: Docu # Version: 0.28 # The remainder of this file is compressed using zlib. xÚ­[Ksã6 ¾ï¯ðL{¦¹î-mvg2“dÓ¤íUCK´­D*”äÿ}©—­‚’/™‰>|¤Œ´‰7E-¥É67·›}ª‹B˜Sp(³ô·úêÍï››/G‘&±(µá<\D™ Γ±ŽªLªróQIsr½Ñ?}Ó>m?d {éõ%Ƴ»D¦,¯d:NT,?›gS±•iýp~ºéo´Ïožt\¥róP_ú²— x©¿Ú½Ñ>ZHa¢ÃøÁöZ÷Ø[ûÀ‹u‚áGÈÏ2Øi“ÖŠ¯YûÙ?6öjØ\m_k¯wn±/mEô.UnE!Gï oÀ¯Ve’Ž¿Õ\î×`þ¡þü^=©R¿Ÿt‰m¢d9›Üè.>HqéQ†ñv6@{~óûã‰^.»¬.OF(Ìèö&>D¦Õ^w×ñ›(â ¹LùHc.Ònß>*ÑFD”Š¢ØÜÎü~-xkSù.¹M¯ 8©¨±@–ÛQ&°bã‹ üm–ÔˆƒÙþÈËD+‘ú;ãïßz,BKnO,wŒ2öOûg2Ÿ}ç ~œy†Ã 36É΢’`Ð%‰X«l­ 3¡NËVšeµV#< îû 1X®1.á^Yòë •f{zwêôcǘ&nÝÙJ2sÄ/hl#¾:¸ñðrÇF¼dÜgˆei’mUÊ¥0Q6ad¤(%+ŠŸy•{ù™ûZßÜ?šõ'±LåÄjg:¢n`§PËCÞdùfmˆÊïuMr]”a7—¹3ü-qAGȦöË3•²BÒsX!ŸW&e‡ ‘q8I¶(µŒ™mk€ã äïSw!@6ŒëL$üR5Z·†Ž®Øv,·Ã7ä€ÎRüí3)ÊÂsv% C6eZ÷¢/FG:µ¹×²xÖec`=¤üŒdÃÜIZ Ö€UTˆÆZÞÐxÀÀEÓ3®\‡qg!ÈÆI-=†µdОġI .M¯8ú¯.1QßÁ¶q {6+IèòD¬, °Q½8¢µ~¯ò'¡¬­u0:=.ã £–t³XqØ3U&hf[éJ­ÍÀa!१1‚z¼¢g¬[c&5›×1K§#ãk¤¡o˜Œˆ×®âNF)ét HÌÓN$ÿ¯ý·. “jº¢âƒ]ïG‹îá^tQ¦¡¨ÕI@ß“TÂnHD¨Òw;TúÆO‘Èdj]SHkJX)aMÛžï*uKÀU²×ç5âO¢ú­ב\ͪ²­Í(ûÐ^²“i l™ë^®¦•ÑûÅ?›†ô Žæ±%´¡µF°zGº7ž£<§´œ'º¾­…°_6.º³y@¥3W*ÀåЄW©õS¨·?¯°ŒsªÁ'Žk¦ŠËB Ó€áA°©¤œçMvÁ_FtgÍÛ2™ï©@g ÀäQª}yð•Æžµ’ëÕK‚/lih@_Û²|‘žÝ»ÌŸºˆ!ï@ÅÞ^Heøˈ<·U$ž(‰§ÚyÅåÜniíú`»“Œ‚–Uñ/­ŽÒX¿øÓÆó‚s™ Hæ0±Ö™bž9ëöËú•¼-G…*‰ldºè¢ýj¨wž»+HÑED÷./„´×V!bŠß ¡=¦†nƒbƒ nÆ·G@_Ó âèBÉî.JѼlX÷ <÷Z8îvé 8stzF;£3Ï9!‹éYh’!ADÊÓœ(r®=·v^ÚM°ë"ª)K¬]´³„¹m žàF1ìrê´ƒ¸R%ríÚ8úD‚Ý\u—ÚÅ^±ù³`ë‡aå4`‘¤˜ILDB ÙêT`ð"Vi´Ä_‚ØÆÇÙ¦úßp'";èi¢ bф̧äþ<(WÒjõÇ:EZ(gK“øö=±…é$¶²ß‚g37ç†-ABý(æ8¥¡9kÓˆûäï¼ÇôÈ]ý¼ÔDšH\e(É-©=ŸÅZÏû]ǪäÆNÈx«9N™™åøé‘3»Þ^î¡$eO•”"Ùûw4³Ñ¿_ðÐ.ÁÓ|h­;[‚ â< -þÇU–‡¶x0‹Bñ‰¼d™„À{#ƒÒ†½uáËîê7c´ñÚbŹ |Ö›¶DW/,—>ò£³XÎR‘@·éÁ|‡6Gæ‹ëh%nx÷½‡ÌŽ¶ZF›v¸½¥Xƒö#šþmÒ)óJ­ÒJúêkxØÁŒ_3àÇKO yþ}}ôø)N-®#'ûºñž?Þ1:§¶ bÓûL8˜ux+â\ey>*{.Äy¸ŽŠv‚Ÿ"¿"©­Ö©±Å®Ï²j룜ÏÒc;EsZ}\|îgÙyE Tutorial — Docu 0.28.2 documentation

Tutorial¶

Warning

this document must be rewritten from scratch

What does Doqu do?¶

Why document-oriented?¶

Why not just use the library X for database Y?¶

Native Python bindings exist for most databases. It is preferable to use a dedicated library if you are absolutely sure that your code will never be used with another database. But there are two common use cases when Doqu is much more preferable:

  1. prototyping: if you are unsure about which database fits your requirements best and wish to test various databases against your code, just write your code with Doqu and then try switching backends to see which performs best. Then optimize the code for it.
  2. reusing the code: if you expect the module to be plugged into an application with unpredictable settings, use Doqu.

Of course we are talking about document databases. For relational databases you would use an ORM.

What are “backends”?¶

Warning

this section is out of date

Docu can be used with a multitude of databases providing a uniform API for retrieving, storing, removing and searching of records. To couple Docu with a database, a storage/query backend is needed.

A “backend” is a module that provides two classes: Storage and Query. Both must conform to the basic specifications (see basic specs below). Backends may not be able to implement all default methods; they may also provide some extra methods.

The Storage class is an interface for the database. It allows to add, read, create and update records by primary keys. You will not use this class directly in your code.

The Query class is what you will talk to when filtering objects of a model. There are no constraints on how the search conditions should be represented. This is likely to cause some problems when you switch from one backend to another. Some guidlines will be probably defined to address the issue of portability. For now we try to ensure that all default backends share the conventions defined by the Tokyo Tyrant backend.

Switching backends¶

Warning

this section is out of date

Let’s assume we have a Tokyo Cabinet database. You can choose the TC backend to use the DB file directly or access the same file through the manager. The first option is great for development and some other cases where you would use SQLite; the second option is important for most production environments where multiple connections are expected. The good news is that there’s no more import and export, dump/load sequences, create/alter/drop and friends. Having tested the application against the database storage.tct with Cabinet backend, just run ttserver storage.tct and switch the backend config.

Let’s create our application:

import docu
import settings
from models import Country, Person

storage = docu.get_storage(settings.DATABASE)

print Person.objects(storage)   # prints all Person objects from DB

Now define settings for both backends (settings.py):

# direct access to the database (simple, not scalable)
TOKYO_CABINET_DATABASE = {
    'backend': 'docu.ext.tokyo_cabinet',
    'kind': 'TABLE',
    'path': 'storage.tct',
}

# access through the Tyrant manager (needs daemon, scalable)
TOKYO_TYRANT_DATABASE = {
    'backend': 'docu.ext.tokyo_tyrant',
    'host': 'localhost',
    'port': 1978,
}

# this is the *only* line you need to change in order to change the backend
DATABASE = TOKYO_CABINET_DATABASE

A few words on what a model is¶

Warning

this section is out of date

First off, what is a model? Well, it’s something that represents an object. The object can be stored in a database. We can fetch it from there, modify and push back.

How is a model different from a Python dictionary then? Easy. Dictionaries know nothing about where the data came from, what parts of it are important for us, how the values should be converted to and fro, and how should the data be validated before it is stored somewhere. A model of an apple does know what properties should an object have to be a Proper Apple; what can be done the apple so that it does not stop being a Proper Apple; and where does the apple belong so it won’t be in the way when it isn’t needed anymore.

In other words, the model is an answer to questions what, where and how about a document. And a dictionary is a document (or, more precisely, a simple representation of the document in given environment).

Working with documents¶

Warning

this section is out of date

A document is basically a “dictionary on steroids”. Let’s create a document:

>>> from docu import *
>>> document = Document(foo=123, bar='baz')
>>> document['foo']
123
>>> document['foo'] = 456

Well, any dictionary can do that. But wait:

>>> db = get_db(backend='docu.ext.shove')
>>> document.save(db)
'new-primary-key'
>>> Document.objects(db)
[<Document: instance>]
>>> fetched = Document.objects(db)[0]
>>> document == fetched
True
>>> fetched['bar']
'baz'

Aha, so Document supports persistence! Nice. By the way, how about some syntactic sugar? Here:

class MyDoc(Document):
    use_dot_notation = True

That’s the same good old Document but with “dot notation” switched on. It allows access to keys with __getattr__ as well as with __getitem__:

>>> my_doc = MyDoc(foo=123)
>>> my_doc.foo
123

Of course this will only work with alphanumeric keys.

Now let’s say we are going to make a little address book. We don’t want any “foo” or “bar, just the relevant information. And the “foo” key should not be allowed in such documents. Can we restrict the structure to certain keys and data types? Let’s see:

class Person(Document):
    structure = {'name': unicode, 'email': unicode}

Great, now the names and values are controlled. The document will raise an exception when someone, say, attempts to put a number instead of the email.

Note

Any built-in type will do; some classes are also accepted (like datetime.date et al). Even Document instances are accepted: they are interpreted as references. The exact set of supported types and classes is defined per storage backend because the data must be (de)serialized. It is possible to register custom converters in runtime.

(Note that the values can be None.) But what if we need to mark some fields as required? Or what if the email is indeed a unicode string but its content has nothing to do with RFC 5322? We need to prevent malformed data from being saved into the database. That’s the daily job for validators:

from docu.validators import *

class Person(Document):
    structure = {
        'name': unicode,
        'email': unicode,
    }
    validators = {
        'name': [required()],
        'email': [optional(), email()],
    }

This will only allow correct data into the storage.

Note

At this point you may ask why are the definitions so verbose. Why not Field classes à la Django? Well, they can be added on top of what’s described here. Actually Docu ships with Document Fields so you can easily write:

class Person(Document):
    name = Field(unicode, required=True)
    email = EmailField()    # this class is not implemented but can be

Why isn’t this approach used by default? Well, it turned out that such classes introduce more problems than they solve. Too much magic, you know. Also, they quickly become a name + clutter thing. Compact but unreadable. So we adopted the MongoKit approach, i.e. semantic grouping of attributes. And — guess what? — the document classes became much easier to understand. Despite the definitions are a bit longer. And remember, it is always possible to add syntax sugar, but it’s usually extremely hard to remove it.

And now, surprise: validators do an extra favour for us! Look:

XXX an example of query; previously defined documents are not shown because
records are filtered by validators

More questions?¶

If you can’t find the answer to your questions on Docu in the documentation, feel free to ask in the discussion group.

———— XXXXXXXXXX The part below is outdated —————-

The Document behaves Let’s observe the object thoroughly and conclude that colour is an important distinctive feature of this... um, sort of thing:

class Thing(Document):
    structure = {
        'colour': unicode
    }

Great, now that’s a model. It recognizes a property as significant. Now we can compare, search and distinguish objects by colour (and its presence or lack). Obviously, if colour is an applicable property for an object, then it belongs to this model.

A more complete example which will look familiar to those who had ever used an ORM (e.g. the Django one):

import datetime
from docu import *

class Country(Document):
    structure = {
        'name': unicode    # any Python type; default is unicode
    }
    validators = {
        'type': [AnyOf(['country'])]
    }

    def __unicode__(self):
        return self['name']

class Person(Document):
    structure = {
        'first_name': unicode,
        'last_name': unicode,
        'gender': unicode,
        'birth_date': datetime.date,
        'birth_place': Country,    # reference to another model
    }
    validators = {
        'first_name': [required()],
        'last_name': [required()],
    }
    use_dot_notation = True

    def __unicode__(self):
        return u'{first_name} {last_name}'.format(**self)

    @property
    def age(self):
        return (datetime.datetime.now().date() - self.birth_date).days / 365

The interesting part is the Meta subclass. It contains a must_have attribute which actually binds the model to a subset of data in the storage. {'first_name__exists': True} states that a data row/document/... must have the field first_name defined (not necessarily non-empty). You can easily define any other query conditions (currently with respect to the backend’s syntax but we hope to unify things). When you create an empty model instance, it will have all the “must haves” pre-filled if they are not complex lookups (e.g. Country will have its type set to True, but we cannot do that with Person‘s constraints).

Inheritance¶

Warning

this section is out of date

Let’s define another model:

class Woman(Person):
    class Meta:
        must_have = {'gender': 'female'}

Or even that one:

today = datetime.datetime.now()
day_16_years_back = now - datetime.timedelta(days=16*365)

class Child(Person):
    parent = Reference(Person)

    class Meta:
        must_have = {'birth_date__gte': day_16_years_back}

Note that our Woman or Child models are subclasses of Person model. They inherit all attributes of Person. Moreover, Person‘s metaclass is inherited too. The must_have dictionaries of Child and Woman models are merged into the parent model’s dictionary, so when we query the database for records described by the Woman model, we get all records that have first_name and last_name defined and gender set to “female”. When we edit a Person instance, we do not care about the parent attribute; we actually don’t even have access to it.

Model is a query, not a container¶

Warning

this section is out of date

We can even deal with data described above without model inheritance. Consider this valid model – LivingBeing:

class LivingBeing(Model):
    species = Property()
    birth_date = Property()

    class Meta:
        must_have = {'birth_date__exists': True}

The data described by LivingBeing overlaps the data described by Person. Some people have their birth dates not deifined and Person allows that. However, LivingBeing requires this attribute, so not all people will appear in a query by this model. At the same time LivingBeing does not require names, so anybody and anything, named or nameless, but ever born, is a “living being”. Updating a record through any of these models will not touch data that the model does not know. For instance, saving an entity as a LivingBeing will not remove its name or parent, and working with it as a Child will neither expose nor destroy the information about species.

These examples illustrate how models are more “views” than “schemata”.

Now let’s try these models with a Tokyo Cabinet database:

>>> db = docu.get_db(
...     backend = 'docu.ext.tokyo_cabinet',
...     path = 'test.tct'
... )
>>> guido = Person(first_name='Guido', last_name='van Rossum')
>>> guido
<Person Guido van Rossum>
>>> guido.first_name
Guido
>>> guido.birth_date = datetime.date(1960, 1, 31)
>>> guido.save(db)    # returns the autogenerated primary key
'person_0'
>>> ppl_named_guido = Person.objects(db).where(first_name='Guido')
>>> ppl_named_guido
[<Person Guido van Rossum>]
>>> guido = ppl_named_guido[0]
>>> guido.age    # calculated on the fly -- datetime conversion works
49
>>> guido.birth_place = Country(name='Netherlands')
>>> guido.save()    # model instance already knows the storage it belongs to
'person_0'
>>> guido.birth_place
<Country Netherlands>
>>> Country.objects(db)    # yep, it was saved automatically with Guido
[<Country Netherlands>]
>>> larry = Person(first_name='Larry', last_name='Wall')
>>> larry.save(db)
'person_2'
>>> Person.objects(db)
[<Person Guido van Rossum>, <Person Larry Wall>]

...and so on.

Note that relations are supported out of the box.

PK1S/BS'rþUþU!doqu-latest/ext_tokyo_tyrant.html Tokyo Tyrant extension — Docu 0.28.2 documentation

Tokyo Tyrant extension¶

A storage/query backend for Tokyo Tyrant.

status:stable
database:Tokyo Cabinet, Tokyo Tyrant
dependencies:Pyrant
suitable for:general purpose
class doqu.ext.tokyo_tyrant.storage.StorageAdapter(**kw)¶
clear()¶

Clears the whole storage from data, resets autoincrement counters.

connect()¶

Connects to the database. Raises RuntimeError if the connection is not closed yet. Use reconnect() to explicitly close the connection and open it again.

delete(key)¶

Deletes record with given primary key.

disconnect()¶

Closes internal store and removes the reference to it. If the backend works with a file, then all pending changes are saved now.

find(doc_class=<type 'dict'>, **conditions)¶

Returns instances of given class, optionally filtered by given conditions.

Parameters:
  • doc_class – Document class. Default is dict. Normally you will want a more advanced class, such as Document or its more concrete subclasses (with explicit structure and validators).
  • conditions – key/value pairs, same as in where().

Note

By default this returns a tuple of (key, data_dict) per item. However, this can be changed if doc_class provides the method from_storage(). For example, Document has the notion of “saved state” so it can store the key within. Thus, only a single Document object is returned per item.

get(key, doc_class=<type 'dict'>)¶

Returns document instance for given document class and primary key. Raises KeyError if there is no item with given key in the database.

Parameters:
  • key – a numeric or string primary key (as supported by the backend).
  • doc_class – a document class to wrap the data into. Default is dict.
get_many(keys, doc_class=<type 'dict'>)¶

Returns an iterator of documents with primary keys from given list. Basically this is just a simple wrapper around get() but some backends can reimplement the method in a much more efficient way.

get_or_create(doc_class=<type 'dict'>, **conditions)¶

Queries the database for records associated with given document class and conforming to given extra conditions. If such records exist, picks the first one (the order may be random depending on the database). If there are no such records, creates one.

Returns the document instance and a boolean value “created”.

reconnect()¶

Gracefully closes current connection (if it’s not broken) and connects again to the database (e.g. reopens the file).

save(key, data)¶

Saves given data with given primary key into the storage. Returns the primary key.

Parameters:
  • key – the primary key for given object; if None, will be generated.
  • data – a dict containing all properties to be saved.

Note that you must provide current primary key for a record which is already in the database in order to update it instead of copying it.

sync()¶

Synchronizes the storage to disk immediately if the backend supports this operation. Normally the data is synchronized either on save(), or on timeout, or on disconnect(). This is strictly backend-specific. If a backend does not support the operation, NotImplementedError is raised.

class doqu.ext.tokyo_tyrant.query.QueryAdapter(storage, doc_class)¶
count()¶

Returns the number of records that match current query. Does not fetch the records.

delete()¶

Deletes all records that match current query.

order_by(names, reverse=False)¶

Returns a query object with same conditions but with results sorted by given field. By default the direction of sorting is ascending.

Parameters:
  • names – list of strings: names of fields by which results should be sorted. Some backends may only support a single field for sorting.
  • reversebool: if True, the direction of sorting is reversed and becomes descending. Default is False.
values(name)¶

Returns a list of unique values for given column name.

where(**conditions)¶

Returns Query instance filtered by given conditions.

where_not(**conditions)¶

Returns Query instance. Inverted version of where().

Project Versions

Previous topic

Tokyo Cabinet extension

Next topic

MongoDB extension

This Page

PK1S/Bbf¼¼doqu-latest/backend_base.html Backend API — Docu 0.28.2 documentation

Backend API¶

Abstract classes for unified storage/query API with various backends.

Derivative classes are expected to be either complete implementations or wrappers for external libraries. The latter is assumed to be a better solution as Doqu is only one of the possible layers. It is always a good idea to provide different levels of abstraction and let others combine them as needed.

The backends do not have to subclass BaseStorageAdapter and BaseQueryAdapter. However, they must closely follow their API.

class doqu.backend_base.BaseStorageAdapter(**kw)¶

Abstract adapter class for storage backends.

Note

Backends policy

If a public method foo() internally uses a private method _foo(), then subclasses should only overload only the private attribute. This ensures that docstring and signature are always correct. However, if the backend introduces some deviations in behaviour or extends the signature, the public method can (and should) be overloaded at least to provide documentation.

clear()¶

Clears the whole storage from data, resets autoincrement counters.

connect()¶

Connects to the database. Raises RuntimeError if the connection is not closed yet. Use reconnect() to explicitly close the connection and open it again.

delete(key)¶

Deletes record with given primary key.

disconnect()¶

Closes internal store and removes the reference to it. If the backend works with a file, then all pending changes are saved now.

find(doc_class=<type 'dict'>, **conditions)¶

Returns instances of given class, optionally filtered by given conditions.

Parameters:
  • doc_class – Document class. Default is dict. Normally you will want a more advanced class, such as Document or its more concrete subclasses (with explicit structure and validators).
  • conditions – key/value pairs, same as in where().

Note

By default this returns a tuple of (key, data_dict) per item. However, this can be changed if doc_class provides the method from_storage(). For example, Document has the notion of “saved state” so it can store the key within. Thus, only a single Document object is returned per item.

get(key, doc_class=<type 'dict'>)¶

Returns document instance for given document class and primary key. Raises KeyError if there is no item with given key in the database.

Parameters:
  • key – a numeric or string primary key (as supported by the backend).
  • doc_class – a document class to wrap the data into. Default is dict.
get_many(keys, doc_class=<type 'dict'>)¶

Returns an iterator of documents with primary keys from given list. Basically this is just a simple wrapper around get() but some backends can reimplement the method in a much more efficient way.

get_or_create(doc_class=<type 'dict'>, **conditions)¶

Queries the database for records associated with given document class and conforming to given extra conditions. If such records exist, picks the first one (the order may be random depending on the database). If there are no such records, creates one.

Returns the document instance and a boolean value “created”.

reconnect()¶

Gracefully closes current connection (if it’s not broken) and connects again to the database (e.g. reopens the file).

save(key, data)¶

Saves given data with given primary key into the storage. Returns the primary key.

Parameters:
  • key – the primary key for given object; if None, will be generated.
  • data – a dict containing all properties to be saved.

Note that you must provide current primary key for a record which is already in the database in order to update it instead of copying it.

sync()¶

Synchronizes the storage to disk immediately if the backend supports this operation. Normally the data is synchronized either on save(), or on timeout, or on disconnect(). This is strictly backend-specific. If a backend does not support the operation, NotImplementedError is raised.

class doqu.backend_base.BaseQueryAdapter(storage, doc_class)¶

Query adapter for given backend.

count()¶

Returns the number of records that match given query. The result of q.count() is exactly equivalent to the result of len(q). The implementation details do not differ by default, but it is recommended that the backends stick to the following convention:

  • __len__ executes the query, retrieves all matching records and tests the length of the resulting list;
  • count executes a special query that only returns a single value: the number of matching records.

Thus, __len__ is more suitable when you are going to iterate the records anyway (and do no extra queries), while count is better when you just want to check if the records exist, or to only use a part of matching records (i.e. a slice).

delete()¶

Deletes all records that match current query.

order_by(names, reverse=False)¶

Returns a query object with same conditions but with results sorted by given field. By default the direction of sorting is ascending.

Parameters:
  • names – list of strings: names of fields by which results should be sorted. Some backends may only support a single field for sorting.
  • reversebool: if True, the direction of sorting is reversed and becomes descending. Default is False.
values(name)¶

Returns a list of unique values for given field name.

Parameters:name – the field name.
where(**conditions)¶

Returns Query instance filtered by given conditions. The conditions are specified by backend’s underlying API.

where_not(**conditions)¶

Returns Query instance. Inverted version of where().

exception doqu.backend_base.ProcessorDoesNotExist¶

This exception is raised when given backend does not have a processor suitable for given value. Usually you will need to catch a subclass of this exception.

class doqu.backend_base.LookupManager¶

Usage:

lookup_manager = LookupManager()

@lookup_manager.register('equals', default=True)  # only one lookup can be default
def exact_match(name, value):
    '''
    Returns native Tokyo Cabinet lookup triplets for given
    backend-agnostic lookup triplet.
    '''
    if isinstance(value, basestring):
        return (
            (name, proto.RDBQCSTREQ, value),
        )
    if isinstance(value, (int, float)):
        return (
            (name, proto.RDBQCNUMEQ, value),
        )
    raise ValueError

Now if you call lookup_manager.resolve('age', 'equals', 99), the returned value will be (('age', proto.RDBCNUMEQ, 99),).

A single generic lookup may yield multiple native lookups because some backends do not support certain lookups directly and therefore must translate them to a combination of elementary conditions. In most cases resolve() will yield a single condition. Its format is determined by the query adapter.

exception_class¶

alias of LookupProcessorDoesNotExist

resolve(name, operation, value)¶

Returns a set of backend-specific conditions for given backend-agnostic triplet, e.g.:

('age', 'gt', 90)

will be translated by the Tokyo Cabinet backend to:

('age', 9, '90')

or by the MongoDB backend to:

{'age': {'$gt': 90}}
exception doqu.backend_base.LookupProcessorDoesNotExist¶

This exception is raised when given backend does not support the requested lookup.

class doqu.backend_base.ConverterManager¶

An instance of this class can manage property processors for given backend. Processor classes must be registered against Python types or classes. The processor manager allows encoding and decoding data between a document class instance and a database record. Each backend supports only a certain subset of Python datatypes and has its own rules in regard to how None values are interpreted, how complex data structures are serialized and so on. Moreover, there’s no way to guess how a custom class should be processed. Therefore, each combination of data type + backend has to be explicitly defined as a set of processing methods (to and from).

exception_class¶

alias of DataProcessorDoesNotExist

from_db(datatype, value)¶

Converts given value to given Python datatype. The value must be correctly pre-encoded by the symmetrical PropertyManager.to_db() method before saving it to the database.

Raises DataProcessorDoesNotExist if no suitable processor is defined by the backend.

to_db(value, storage)¶

Prepares given value and returns it in a form ready for storing in the database.

Raises DataProcessorDoesNotExist if no suitable processor is defined by the backend.

exception doqu.backend_base.DataProcessorDoesNotExist¶

This exception is raised when given backend does not have a datatype processor suitable for given value.

Project Versions

Previous topic

Document Fields

This Page

PK1S/BU}4ŸyAyAdoqu-latest/utils.html Utilities — Docu 0.28.2 documentation

Utilities¶

Various useful functions. Some can be imported from doqu.utils, some are available directly at doqu.

These utilities are either stable and well-tested or possible changes in their API are not considered harmful (i.e. they are marginal). Important functions which design is likely to change or which lack proper tests are located in doqu.future.

doqu.utils.dump_doc(self, raw=False, as_repr=False, align=True, keys=None, exclude=None)¶

Returns a multi-line string with document keys and values nicely formatted and aligned.

Parameters:
  • raw – If True, uses “raw” values, as fetched from the database (note that this will fail for unsaved documents). If not, the values are obtained in the normal way, i.e. by __getitem__(). Default is False.
  • align – If True, the keys and values are aligned into two columns of equal width. If False, no padding is used. Default is True.
  • keys – a list of document keys to show. By default all existing keys are included.
  • exclude – a list of keys to exclude. By default no keys are excluded.
Prarm as_repr:

If True, uses repr() for values; if not, coerces them to Unicode. Default if False.

doqu.utils.get_db(settings_dict=None, **settings_kwargs)¶

Storage adapter factory. Expects path to storage backend module and optional backend-specific settings. Returns storage adapter instance. If required underlying library is not found, exception pkg_resources.DistributionNotFound is raised with package name and version as the message.

Parameters:backend – string, dotted path to a Doqu storage backend (e.g. doqu.ext.tokyo_tyrant). See Extensions for a list of bundled backends or Backend API for backend API reference.

Usage:

import doqu

db = doqu.get_db(backend='doqu.ext.shelve', path='test.db')

query = SomeDocument.objects(db)

Settings can be also passed as a dictionary:

SETTINGS = {
    'backend': 'doqu.ext.tokyo_cabinet',
    'path': 'test.tct',
}

db = doqu.get_db(SETTINGS)

The two methods can be combined to override certain settings:

db = doqu.get_db(SETTINGS, path='another_db.tct')
doqu.utils.camel_case_to_underscores(class_name)¶

Returns a pretty readable name based on the class name. For example, “SomeClass” is translated to “some_class”.

doqu.utils.load_fixture(path, db=None)¶

Reads given file (assuming it is in a known format), loads it into given storage adapter instance and returns that instance.

Parameters:
  • path – absolute or relative path to the fixture file; user constructions (“~/foo”) will be expanded.
  • db – a storage adapter instance (its class must conform to the BaseStorageAdapter API). If not provided, a memory storage will be created.

Usage:

import doqu

db = doqu.load_fixture('account.csv')

query = SomeDocument.objects(db)

Project Versions

Previous topic

Validators

Next topic

Extensions

This Page

PK1S/Bž+Ôº¾(¾(doqu-latest/py-modindex.html Python Module Index — Docu 0.28.2 documentation

Project Versions

PK1S/Bý! äÑdÑddoqu-latest/ext_shelve.html Shelve extension — Docu 0.28.2 documentation

Shelve extension¶

A storage/query backend for shelve which is bundled with Python.

status:stable
database:any dbm-style database supported by shelve
dependencies:the Python standard library
suitable for:“smart” interface to a key/value store, small volume

A “shelf” is a persistent, dictionary-like object. The difference with “dbm†databases is that the values (not the keys!) in a shelf can be essentially arbitrary Python objects — anything that the pickle module can handle. This includes most class instances, recursive data types, and objects containing lots of shared sub-objects. The keys are ordinary strings.

This extension wraps the standard Python library and provides Document support and uniform query API.

Note

The query methods are inefficient as they involve iterating over the full set of records and making per-row comparison without indexing. This backend is not suitable for applications that depend on queries and require decent speed. However, it is an excellent tool for existing DBM databases or for environments and cases where external dependencies are not desired.

class doqu.ext.shelve_db.StorageAdapter(**kw)¶

Provides unified Doqu API for MongoDB (see doqu.backend_base.BaseStorageAdapter).

Parameters:path – relative or absolute path to the database file (e.g. test.db)
clear()¶

Clears the whole storage from data, resets autoincrement counters.

connect()¶

Connects to the database. Raises RuntimeError if the connection is not closed yet. Use reconnect() to explicitly close the connection and open it again.

delete(key)¶

Deletes record with given primary key.

disconnect()¶

Closes internal store and removes the reference to it. If the backend works with a file, then all pending changes are saved now.

find(doc_class=<type 'dict'>, **conditions)¶

Returns instances of given class, optionally filtered by given conditions.

Parameters:
  • doc_class – Document class. Default is dict. Normally you will want a more advanced class, such as Document or its more concrete subclasses (with explicit structure and validators).
  • conditions – key/value pairs, same as in where().

Note

By default this returns a tuple of (key, data_dict) per item. However, this can be changed if doc_class provides the method from_storage(). For example, Document has the notion of “saved state” so it can store the key within. Thus, only a single Document object is returned per item.

get(key, doc_class=<type 'dict'>)¶

Returns document instance for given document class and primary key. Raises KeyError if there is no item with given key in the database.

Parameters:
  • key – a numeric or string primary key (as supported by the backend).
  • doc_class – a document class to wrap the data into. Default is dict.
get_many(keys, doc_class=<type 'dict'>)¶

Returns an iterator of documents with primary keys from given list. Basically this is just a simple wrapper around get() but some backends can reimplement the method in a much more efficient way.

get_or_create(doc_class=<type 'dict'>, **conditions)¶

Queries the database for records associated with given document class and conforming to given extra conditions. If such records exist, picks the first one (the order may be random depending on the database). If there are no such records, creates one.

Returns the document instance and a boolean value “created”.

query_adapter¶

alias of QueryAdapter

reconnect()¶

Gracefully closes current connection (if it’s not broken) and connects again to the database (e.g. reopens the file).

save(key, data)¶

Saves given data with given primary key into the storage. Returns the primary key.

Parameters:
  • key – the primary key for given object; if None, will be generated.
  • data – a dict containing all properties to be saved.

Note that you must provide current primary key for a record which is already in the database in order to update it instead of copying it.

sync()¶

Synchronizes the storage to disk immediately if the backend supports this operation. Normally the data is synchronized either on save(), or on timeout, or on disconnect(). This is strictly backend-specific. If a backend does not support the operation, NotImplementedError is raised.

class doqu.ext.shelve_db.QueryAdapter(*args, **kw)¶

The Query class.

count()¶

Same as __len__ but a bit faster.

delete()¶

Deletes all records that match current query.

order_by(names, reverse=False)¶

Defines order in which results should be retrieved.

Parameters:
  • names – the names of columns by which the ordering should be done. Can be an iterable with strings or a single string.
  • reverse – If True, direction changes from ascending (default) to descending.

Examples:

q.order_by('name')                  # ascending
q.order_by('name', reverse=True)    # descending

If multiple names are provided, grouping is done from left to right.

Note

while you can specify the direction of sorting, it is not possible to do it on per-name basis due to backend limitations.

Warning

ordering implementation for this database is currently inefficient.

values(name)¶

Returns an iterator that yields distinct values for given column name.

Supports date parts (i.e. date__month=7).

Note

this is currently highly inefficient because the underlying library does not support columns mode (tctdbiternext3). Moreover, even current implementation can be optimized by removing the overhead of creating full-blown document objects.

Note

unhashable values (like lists) are silently ignored.

where(**conditions)¶

Returns Query instance filtered by given conditions. The conditions are specified by backend’s underlying API.

where_not(**conditions)¶

Returns Query instance. Inverted version of where().

Project Versions

Previous topic

Extensions

Next topic

Shove extension

This Page

PK,S/BkuFòpp$doqu-latest/_static/down-pressed.png‰PNG  IHDRóÿasRGB®ÎébKGDùC» pHYs × ×B(›xtIMEÚ -vF#ðIDAT8ËÍÒ!OAàïÚJ, ++@ I v¢bÿ@Wñ7F’ HNâ±ú# ‚4¡8Ì6¹4×6Tñ’MvvÞ¼7³»êœûöDs¿‡aóxâ1†U îq‚;<¦ˆÏ E¸Â-f)âºj%ßpˆo4xFà78G…>æ)â-ƒ ž ¡ÂEYm4%7YTk-¾–Q¶a–"NWAo-y†eqÒá¾,)â ÓÒYÓÑú´ptŽÐå½\hóq´Îím˜sÔz¦ìG]ÄNñ‡Òa…‡röç߶¨s^lã vh\î2Ù%ðâßãŽ0EeRvØIEND®B`‚PK,S/B4µîîdoqu-latest/_static/jquery.js/*! * jQuery JavaScript Library v1.4.2 * http://jquery.com/ * * Copyright 2010, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * Includes Sizzle.js * http://sizzlejs.com/ * Copyright 2010, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * * Date: Sat Feb 13 22:33:48 2010 -0500 */ (function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& (d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== "find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a"; var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, "_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== "="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); (function(){var g=s.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= {},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== "string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== 1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, ""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", ""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, "border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== "string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? "&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== 1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== "json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== "number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
"; a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": "pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); PK,S/BšhßÛkkdoqu-latest/_static/down.png‰PNG  IHDRóÿasRGB®ÎébKGDùC» pHYs × ×B(›xtIMEÚ"ÅíU{ëIDAT8ËÍÒ¡NCAÐóÚJ, ++@ ™4>‡¨â/ÐUü’¤^,†~T&Ô3M^^^ÛPÅM6ÙÙ¹sïÌî*¥ôí‰RJ¿‡a)e¼GñÃ*ƒœàñ¹¡èW¸Å<"®«Fò ‡øFgÜã78G…>q ƒ†ÁOI¨p‘«‰:s“õAÕjñ5GÙ†yDœ®ƒ^+y†U:ép_%G§@D|ašÕ­O“£s„Æ(ïy¡M,"â¨Íím˜sÔx:÷£.b§@D|`–V˜åÙŸÛ²”²ÜÆìиÜe²KàÅ¿Ç/êG!‚ ™IEND®B`‚PK,S/B' 5wú ú %doqu-latest/_static/comment-close.png‰PNG  IHDRóÿa OiCCPPhotoshop ICC profilexÚSgTSé=÷ÞôBKˆ€”KoR RB‹€‘&*! Jˆ!¡ÙQÁEEÈ ˆŽŽ€ŒQ, Š Øä!¢Žƒ£ˆŠÊûá{£kÖ¼÷æÍþµ×>ç¬ó³ÏÀ –H3Q5€ ©BàƒÇÄÆáä.@ $p³d!sý#ø~<<+"À¾xÓ ÀM›À0‡ÿêB™\€„Àt‘8K€@zŽB¦@F€˜&S `ËcbãP-`'æÓ€ø™{[”! ‘ eˆDh;¬ÏVŠEX0fKÄ9Ø-0IWfH°·ÀÎ ² 0Qˆ…){`È##x„™FòW<ñ+®ç*x™²<¹$9E[-qWW.(ÎI+6aaš@.Ây™24àóÌ ‘àƒóýxήÎÎ6Ž¶_-ê¿ÿ"bbãþåÏ«p@át~Ñþ,/³€;€mþ¢%îh^  u÷‹f²@µ éÚWópø~<ß5°j>{‘-¨]cöK'XtÀâ÷ò»oÁÔ(€hƒáÏwÿï?ýG %€fI’q^D$.Tʳ?ÇD *°AôÁ,ÀÁÜÁ ü`6„B$ÄÂBB d€r`)¬‚B(†Í°*`/Ô@4ÀQh†“p.ÂU¸=púažÁ(¼ AÈa!ÚˆbŠX#Ž™…ø!ÁH‹$ ɈQ"K‘5H1RŠT UHò=r9‡\Fº‘;È2‚ü†¼G1”²Q=Ô µC¹¨7„F¢ Ðdt1š ›Ðr´=Œ6¡çЫhÚ>CÇ0Àè3Äl0.ÆÃB±8, “c˱"¬ «Æ°V¬»‰õcϱwEÀ 6wB aAHXLXNØH¨ $4Ú 7 „QÂ'"“¨K´&ºùÄb21‡XH,#Ö/{ˆCÄ7$‰C2'¹I±¤TÒÒFÒnR#é,©›4H#“ÉÚdk²9”, +È…ääÃä3ää!ò[ b@q¤øSâ(RÊjJåå4åe˜2AU£šRݨ¡T5ZB­¡¶R¯Q‡¨4uš9̓IK¥­¢•Óhh÷i¯ètºÝ•N—ÐWÒËéGè—èôw †ƒÇˆg(›gw¯˜L¦Ó‹ÇT071ë˜ç™™oUX*¶*|‘Ê •J•&•*/T©ª¦ªÞª UóUËT©^S}®FU3Sã© Ô–«UªPëSSg©;¨‡ªg¨oT?¤~Yý‰YÃLÃOC¤Q ±_ã¼Æ c³x,!k «†u5Ä&±ÍÙ|v*»˜ý»‹=ª©¡9C3J3W³Ró”f?ã˜qøœtN ç(§—ó~ŠÞï)â)¦4L¹1e\kª–—–X«H«Q«Gë½6®í§¦½E»YûAÇJ'\'GgÎçSÙSݧ §M=:õ®.ªk¥¡»Dw¿n§î˜ž¾^€žLo§Þy½çú}/ýTýmú§õG X³ $Û Î<Å5qo</ÇÛñQC]Ã@C¥a•a—á„‘¹Ñ<£ÕFFŒiÆ\ã$ãmÆmÆ£&&!&KMêMîšRM¹¦)¦;L;LÇÍÌÍ¢ÍÖ™5›=1×2ç›ç›×›ß·`ZxZ,¶¨¶¸eI²äZ¦Yn…Z9Y¥XUZ]³F­­%Ö»­»§§¹N“N«žÖgðñ¶É¶©·°åØÛ®¶m¶}agbg·Å®Ã“}º}ý= ‡Ù«Z~s´r:V:ޚΜî?}Åô–é/gXÏÏØ3ã¶Ë)ÄiS›ÓGgg¹sƒóˆ‹‰K‚Ë.—>.›ÆÝȽäJtõq]ázÒõ›³›Âí¨Û¯î6îiî‡ÜŸÌ4Ÿ)žY3sÐÃÈCàQåÑ? Ÿ•0k߬~OCOgµç#/c/‘W­×°·¥wª÷aï>ö>rŸã>ã<7Þ2ÞY_Ì7À·È·ËOÃož_…ßC#ÿdÿzÿѧ€%g‰A[ûøz|!¿Ž?:Ûeö²ÙíAŒ ¹AA‚­‚åÁ­!hÈì­!÷ç˜Î‘Îi…P~èÖÐaæa‹Ã~ '…‡…W†?ŽpˆXÑ1—5wÑÜCsßDúD–DÞ›g1O9¯-J5*>ª.j<Ú7º4º?Æ.fYÌÕXXIlK9.*®6nl¾ßüíó‡ââ ã{˜/È]py¡ÎÂô…§©.,:–@LˆN8”ðA*¨Œ%òw%Ž yÂÂg"/Ñ6шØC\*NòH*Mz’쑼5y$Å3¥,幄'©¼L LÝ›:žšv m2=:½1ƒ’‘qBª!M“¶gêgæfvˬe…²þÅn‹·/•Ék³¬Y- ¶B¦èTZ(×*²geWf¿Í‰Ê9–«ž+Íí̳ÊÛ7œïŸÿíÂá’¶¥†KW-X潬j9²‰Š®Û—Ø(Üxå‡oÊ¿™Ü”´©«Ä¹dÏfÒféæÞ-ž[–ª—æ—n ÙÚ´ ßV´íõöEÛ/—Í(Û»ƒ¶C¹£¿<¸¼e§ÉÎÍ;?T¤TôTúT6îÒݵa×ønÑî{¼ö4ìÕÛ[¼÷ý>ɾÛUUMÕfÕeûIû³÷?®‰ªéø–ûm]­NmqíÇÒý#¶×¹ÔÕÒ=TRÖ+ëGǾþïw- 6 UœÆâ#pDyäé÷ ß÷ :ÚvŒ{¬áÓvg/jBšòšF›Sšû[b[ºOÌ>ÑÖêÞzüGÛœ499â?rýéü§CÏdÏ&žþ¢þË®/~øÕë×Îјѡ—ò—“¿m|¥ýêÀë¯ÛÆÂƾÉx31^ôVûíÁwÜwï£ßOä| (ÿhù±õSЧû“““ÿ˜óüc3-ÛbKGDÿÿÿ ½§“ pHYs  šœtIMEÚ!â›ÈÝ,IDAT8Ëe’_HuÇ?Ïï}ßsŽž3ÍyòË•¶¦‹U2MvQÉÖŠFÔE¬.ŠÑÍÃÅ‚­ÄŠbÑE$DD­‹ËZF5b@QÌ"š:2§›š¦¾ïû{Ÿn.êsõåçû<_ø yî?ô½m÷²ýè·wV™ê@t£R`}Z íÄÐ_£# _=œá_@ÝËý ßw^óRë®·•%6gC-έ(K>ä| $„Éï{¯}