app/soc/models/role.py
changeset 474 0bf5af57cef9
parent 385 6d410bf49a82
child 481 94834a1e6c01
equal deleted inserted replaced
473:d01d5e3b0b5c 474:0bf5af57cef9
     3 # Copyright 2008 the Melange authors.
     3 # Copyright 2008 the Melange authors.
     4 #
     4 #
     5 # Licensed under the Apache License, Version 2.0 (the "License");
     5 # Licensed under the Apache License, Version 2.0 (the "License");
     6 # you may not use this file except in compliance with the License.
     6 # you may not use this file except in compliance with the License.
     7 # You may obtain a copy of the License at
     7 # You may obtain a copy of the License at
     8 # 
     8 #
     9 #   http://www.apache.org/licenses/LICENSE-2.0
     9 #   http://www.apache.org/licenses/LICENSE-2.0
    10 # 
    10 #
    11 # Unless required by applicable law or agreed to in writing, software
    11 # Unless required by applicable law or agreed to in writing, software
    12 # distributed under the License is distributed on an "AS IS" BASIS,
    12 # distributed under the License is distributed on an "AS IS" BASIS,
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14 # See the License for the specific language governing permissions and
    14 # See the License for the specific language governing permissions and
    15 # limitations under the License.
    15 # limitations under the License.
    16 
    16 
    17 """This module contains the Administrator Model."""
    17 """This module contains the Role Model."""
    18 
    18 
    19 __authors__ = [
    19 __authors__ = [
    20   '"Todd Larsen" <tlarsen@google.com>',
    20   '"Todd Larsen" <tlarsen@google.com>',
       
    21   '"Sverre Rabbelier" <sverre@rabbelier.nl>',
       
    22   '"Pawel Solyga" <pawel.solyga@gmail.com>',
    21 ]
    23 ]
    22 
    24 
    23 
    25 
    24 import soc.models.person
    26 import polymodel
    25 
    27 
    26 
    28 from google.appengine.ext import db
    27 class Role(soc.models.person.Person):
    29 
       
    30 from django.utils.translation import ugettext_lazy
       
    31 
       
    32 from soc.models import countries
       
    33 
       
    34 import soc.models.user
       
    35 
       
    36 
       
    37 class Role(polymodel.PolyModel):
    28   """Information common to Program participation for all Roles.
    38   """Information common to Program participation for all Roles.
    29 
    39 
    30   Role is the entity that is created when a Person actually participates
    40   Some details of a Role are considered "public" information, and nearly
    31   in some fashion in a Program.  Person details could *possibly* be collected
    41   all of these are optional (except for given_name, surname, and email).
       
    42   Other details of a Role are kept "private" and are only provided to
       
    43   other Users in roles that "need to know" this information.  How these
       
    44   fields are revealed is usually covered by Program terms of service.
       
    45 
       
    46   Role is the entity that is created when a User actually participates
       
    47   in some fashion in a Program. Role details could *possibly* be collected
    32   without actual participation (voluntary, opt-in, of course).
    48   without actual participation (voluntary, opt-in, of course).
    33 
    49 
    34   A Role is a Person's participation in a single Program.  To avoid
    50   A Role is a User's participation in a single Program.  To avoid
    35   duplication of data entry, facilities will be available for selecting
    51   duplication of data entry, facilities will be available for selecting
    36   an existing Role associated with a particular User to be duplicated for
    52   an existing Role associated with a particular User to be duplicated for
    37   participation in a new Program.
    53   participation in a new Program.
    38 
    54 
    39   A Person has to have at least one Role in order to be able to create
    55   A User has to have at least one Role in order to be able to create
    40   any Work (such as a Document) on the site.  The easiest-to-obtain Role is
    56   any Work (such as a Document) on the site.  The easiest-to-obtain Role is
    41   probably Club Member (though Clubs can set their own membership criteria).
    57   probably Club Member (though Clubs can set their own membership criteria).
    42 
    58 
    43   A Role entity participates in the following relationships implemented
    59   A Role entity participates in the following relationships implemented
    44   as a db.ReferenceProperty elsewhere in another db.Model:
    60   as a db.ReferenceProperty elsewhere in another db.Model:
    50 
    66 
    51    works) a many:many relationship with Works, stored in a separate
    67    works) a many:many relationship with Works, stored in a separate
    52      WorksRoles model, representing the Work authored by this Role.
    68      WorksRoles model, representing the Work authored by this Role.
    53      See the WorksRoles model class for details.
    69      See the WorksRoles model class for details.
    54   """
    70   """
    55   pass
    71 
    56 
    72   #: A required many:1 relationship that ties (possibly multiple
       
    73   #: entities of) Role details to a unique User. A Role cannot
       
    74   #: exist unassociated from a login identity and credentials. The
       
    75   #: back-reference in the User model is a Query named 'roles'.
       
    76   user = db.ReferenceProperty(reference_class=soc.models.user.User,
       
    77                               required=True, collection_name='roles')
       
    78 
       
    79   #====================================================================
       
    80   #  (public) name information
       
    81   #====================================================================
       
    82 
       
    83   #: Required field storing the parts of the Role's name
       
    84   #: corresponding to the field names; displayed publicly.
       
    85   #: given_name can only be lower ASCII, not UTF-8 text, because it is
       
    86   #: used, for example, as part of the shipping (mailing) address.
       
    87   given_name = db.StringProperty(required=True,
       
    88       verbose_name=ugettext_lazy('First (given) name'))
       
    89   given_name.help_text = ugettext_lazy('lower ASCII characters only')
       
    90 
       
    91   #: Required field storing the parts of the Role's name
       
    92   #: corresponding to the field names; displayed publicly.
       
    93   #: Surname can only be lower ASCII, not UTF-8 text, because it is
       
    94   #: used, for example, as part of the shipping (mailing) address.
       
    95   surname = db.StringProperty(
       
    96       required=True,
       
    97       verbose_name=ugettext_lazy('Last (family) name'))
       
    98   surname.help_text = ugettext_lazy('lower ASCII characters only')
       
    99 
       
   100   #: Optional field used as a display name, such as for awards
       
   101   #: certificates. Should be the entire display name in the format
       
   102   #: the Role would like it displayed (could be surname followed by
       
   103   #: given name in some cultures, for example). Display names can be
       
   104   #: any valid UTF-8 text.
       
   105   display_name = db.StringProperty(
       
   106       verbose_name=ugettext_lazy('Display Name'))
       
   107   display_name.help_text = ugettext_lazy(
       
   108       'Optional field used as a display name, such as for awards '
       
   109       'certificates. Should be the entire display name in the format '
       
   110       'the person would like it displayed (could be family name followed '
       
   111       'by given name in some cultures, for example). Display names can be '
       
   112       'any valid UTF-8 text.')
       
   113 
       
   114   #====================================================================
       
   115   #  (public) contact information
       
   116   #====================================================================
       
   117 
       
   118   #: Required field used as the 'public' contact mechanism for the
       
   119   #: Role (as opposed to the user.id email address which is
       
   120   #: kept secret).
       
   121   email = db.EmailProperty(
       
   122       required=True,
       
   123       verbose_name=ugettext_lazy('Email Address'))
       
   124 
       
   125   #: Optional field storing Instant Messaging network; displayed publicly.
       
   126   im_network = db.StringProperty(
       
   127       verbose_name=ugettext_lazy('IM Network'))
       
   128   im_network.help_text = ugettext_lazy(
       
   129       'examples: irc:irc.freenode.org xmpp:gmail.com/Home')
       
   130 
       
   131   #: Optional field storing Instant Messaging handle; displayed publicly.
       
   132   im_handle = db.StringProperty(
       
   133       verbose_name=ugettext_lazy('IM Handle'))
       
   134   im_handle.help_text = ugettext_lazy(
       
   135       'personal identifier, such as: screen name, IRC nick, user name')
       
   136 
       
   137   #: Optional field storing a home page URL; displayed publicly.
       
   138   home_page = db.LinkProperty(
       
   139       verbose_name=ugettext_lazy('Home Page URL'))
       
   140 
       
   141   #: Optional field storing a blog URL; displayed publicly.
       
   142   blog = db.LinkProperty(
       
   143       verbose_name=ugettext_lazy('Blog URL'))
       
   144 
       
   145   #: Optional field storing a URL to an image, expected to be a
       
   146   #: personal photo (or cartoon avatar, perhaps); displayed publicly.
       
   147   photo_url = db.LinkProperty(
       
   148       verbose_name=ugettext_lazy('Thumbnail Photo URL'))
       
   149   photo_url.help_text = ugettext_lazy(
       
   150       'URL of 64x64 pixel thumbnail image')
       
   151 
       
   152   #: Optional field storing the latitude provided by the Role; displayed
       
   153   #: publicly.
       
   154   latitude = db.FloatProperty(
       
   155       verbose_name=ugettext_lazy('Latitude'))
       
   156   latitude.help_text = ugettext_lazy(
       
   157       'decimal degrees northerly (N), use minus sign (-) for southerly (S)')
       
   158 
       
   159   #: Optional field storing the longitude provided by the Role; displayed
       
   160   #: publicly.
       
   161   longitude = db.FloatProperty(
       
   162       verbose_name=ugettext_lazy('Longitude'))
       
   163   longitude.help_text = ugettext_lazy(
       
   164       'decimal degrees easterly (E), use minus sign (-) for westerly (W)')
       
   165 
       
   166   #====================================================================
       
   167   # (private) contact information
       
   168   #====================================================================
       
   169 
       
   170   #: Required field containing residence street address; kept private.
       
   171   #: Residence street address can only be lower ASCII, not UTF-8 text, because
       
   172   #: it may be used as a shipping address.
       
   173   res_street = db.StringProperty(required=True,
       
   174       verbose_name=ugettext_lazy('Street address'))
       
   175   res_street.help_text = ugettext_lazy(
       
   176       'street number and name, lower ASCII characters only')
       
   177 
       
   178   #: Required field containing residence address city; kept private.
       
   179   #: Residence city can only be lower ASCII, not UTF-8 text, because it
       
   180   #: may be used as a shipping address.
       
   181   res_city = db.StringProperty(required=True,
       
   182       verbose_name=ugettext_lazy('City'))
       
   183   res_city.help_text = ugettext_lazy('lower ASCII characters only')
       
   184 
       
   185   #: Required field containing residence address state or province; kept
       
   186   #: private.  Residence state/province can only be lower ASCII, not UTF-8
       
   187   #: text, because it may be used as a shipping address.
       
   188   res_state = db.StringProperty(
       
   189       verbose_name=ugettext_lazy('State/Province'))
       
   190   res_state.help_text = ugettext_lazy(
       
   191       'optional if country/territory does not have states or provinces, '
       
   192       'lower ASCII characters only')
       
   193 
       
   194   #: Required field containing residence address country or territory; kept
       
   195   #: private.
       
   196   res_country = db.StringProperty(required=True,
       
   197       verbose_name=ugettext_lazy('Country/Territory'),
       
   198       choices=countries.COUNTRIES_AND_TERRITORIES)
       
   199 
       
   200   #: Required field containing residence address postal code (ZIP code in
       
   201   #: the United States); kept private.  Residence postal code can only be
       
   202   #: lower ASCII, not UTF-8 text, because it may be used as a shipping address.
       
   203   res_postalcode = db.StringProperty(required=True,
       
   204       verbose_name=ugettext_lazy('ZIP/Postal Code'))
       
   205   res_postalcode.help_text = ugettext_lazy('lower ASCII characters only')
       
   206 
       
   207   #: Optional field containing a separate shipping street address; kept
       
   208   #: private.  If shipping address is not present in its entirety, the
       
   209   #: residence address will be used instead.  Shipping street address can only
       
   210   #: be lower ASCII, not UTF-8 text, because, if supplied, it is used as a
       
   211   #: shipping address.
       
   212   ship_street = db.StringProperty(
       
   213       verbose_name=ugettext_lazy('Street address'))
       
   214   ship_street.help_text = ugettext_lazy(
       
   215       'street number and name, lower ASCII characters only')
       
   216 
       
   217   #: Optional field containing shipping address city; kept private.
       
   218   #: Shipping city can only be lower ASCII, not UTF-8 text, because, if
       
   219   #: supplied, it is used as a shipping address.
       
   220   ship_city = db.StringProperty(
       
   221       verbose_name=ugettext_lazy('City'))
       
   222   ship_city.help_text = ugettext_lazy('lower ASCII characters only')
       
   223 
       
   224   #: Optional field containing shipping address state or province; kept
       
   225   #: private.  Shipping state/province can only be lower ASCII, not UTF-8
       
   226   #: text, because, if supplied, it is used as a shipping address.
       
   227   ship_state = db.StringProperty(
       
   228       verbose_name=ugettext_lazy('State/Province'))
       
   229   ship_state.help_text = ugettext_lazy(
       
   230       'optional if country/territory does not have states or provinces, '
       
   231       'lower ASCII characters only')
       
   232 
       
   233   #: Optional field containing shipping address country or territory; kept
       
   234   #: private.
       
   235   ship_country = db.StringProperty(
       
   236       verbose_name=ugettext_lazy('Country/Territory'),
       
   237       choices=countries.COUNTRIES_AND_TERRITORIES)
       
   238 
       
   239   #: Optional field containing shipping address postal code (ZIP code in
       
   240   #: the United States); kept private.  Shipping postal code can only be
       
   241   #: lower ASCII, not UTF-8 text, because, if supplied, it is used as a
       
   242   #: shipping address.
       
   243   ship_postalcode = db.StringProperty(
       
   244       verbose_name=ugettext_lazy('ZIP/Postal Code'))
       
   245   ship_postalcode.help_text = ugettext_lazy('lower ASCII characters only')
       
   246 
       
   247   #: Required field containing a phone number that will be supplied
       
   248   #: to shippers; kept private.
       
   249   phone = db.PhoneNumberProperty(
       
   250       required=True,
       
   251       verbose_name=ugettext_lazy('Phone Number'))
       
   252   phone.help_text = ugettext_lazy(
       
   253       'include complete international calling number with country code')
       
   254 
       
   255   #====================================================================
       
   256   # (private) personal information
       
   257   #====================================================================
       
   258 
       
   259   #: Required field containing the Role's birthdate (for
       
   260   #: determining Program participation eligibility); kept private.
       
   261   birth_date = db.DateProperty(
       
   262       required=True,
       
   263       verbose_name=ugettext_lazy('Birth Date'))
       
   264   birth_date.help_text = ugettext_lazy(
       
   265       'required for determining program eligibility')
       
   266 
       
   267   #: Optional field indicating choice of t-shirt, from XXS to XXXL;
       
   268   #: kept private.
       
   269   tshirt_size = db.StringProperty(
       
   270       verbose_name=ugettext_lazy('T-shirt Size'),
       
   271       choices=('XXS', 'XS', 'S', 'M', 'L', 'XL', 'XXL', 'XXXL'))
       
   272 
       
   273   #: Optional field indicating choice of t-shirt fit; kept private.
       
   274   tshirt_style = db.StringProperty(
       
   275       verbose_name=ugettext_lazy('T-shirt Style'),
       
   276       choices=('male', 'female'))