app/soc/logic/key_name.py
changeset 222 63e5f42e2e83
parent 213 75a8cc0200ad
child 251 8f23804302d0
equal deleted inserted replaced
221:9cca97feadaa 222:63e5f42e2e83
    21   '"Todd Larsen" <tlarsen@google.com>',
    21   '"Todd Larsen" <tlarsen@google.com>',
    22   '"Pawel Solyga" <pawel.solyga@gmail.com>',
    22   '"Pawel Solyga" <pawel.solyga@gmail.com>',
    23   ]
    23   ]
    24 
    24 
    25 
    25 
    26 import soc.models.club
    26 # start with ASCII digit or lowercase
    27 import soc.models.group
    27 #   (additional ASCII digit or lowercase
    28 import soc.models.organization
    28 #     -OR-
    29 import soc.models.school
    29 #   underscore and ASCII digit or lowercase)
    30 import soc.models.sponsor
    30 #     zero or more of OR group
    31 import soc.models.document
    31 LINKNAME_PATTERN_CORE = r'[0-9a-z](?:[0-9a-z]|_[0-9a-z])*'
    32 import soc.models.site_settings
    32 
    33 import soc.models.user
    33 LINKNAME_PATTERN = r'^%s$' % LINKNAME_PATTERN_CORE
       
    34 LINKNAME_ARG_PATTERN = r'(?P<linkname>%s)' % LINKNAME_PATTERN_CORE
       
    35 
       
    36 
       
    37 # partial path is multiple linkname chunks,
       
    38 #   each separated by a trailing /
       
    39 #     (at least 1)
       
    40 # followed by a single linkname with no trailing /
       
    41 WORK_PATH_LINKNAME_ARGS_PATTERN = (
       
    42     r'(?P<partial_path>%(linkname)s(?:/%(linkname)s)*)/'
       
    43      '(?P<linkname>%(linkname)s)' % {
       
    44         'linkname': LINKNAME_PATTERN_CORE})
       
    45 
       
    46 WORK_PATH_LINKNAME_PATTERN = r'^%s$' % WORK_PATH_LINKNAME_ARGS_PATTERN
       
    47 
       
    48 
       
    49 class Error(Exception):
       
    50   """Base class for all exceptions raised by this module."""
       
    51   pass
       
    52 
       
    53 
       
    54 def getFullClassName(cls):
       
    55   """Returns fully-qualified module.class name string.""" 
       
    56   return '%s.%s' % (cls.__module__, cls.__name__) 
       
    57 
       
    58 
       
    59 def combinePath(path_parts):
       
    60   """Returns path components combined into a single string.
       
    61   
       
    62   Args:
       
    63     path_parts: a single path string, or a list of path part strings,
       
    64       or a nested list of path part strings (where the zeroeth element in
       
    65       the list is itself a list); for example:
       
    66         'a/complete/path/in/one/string'
       
    67         ['some', 'path', 'parts']
       
    68         [['path', 'parts', 'and', 'a'], 'link name']
       
    69 
       
    70   Returns:
       
    71     None if path_parts is False (None, empty string, etc.) or if
       
    72     any list elements are False (an empty list, empty string, etc.);
       
    73     otherwise, the combined string with the necessary separators.
       
    74   """
       
    75   if not path_parts:
       
    76     # completely empty input, so return early
       
    77     return None
       
    78 
       
    79   if not isinstance(path_parts, (list, tuple)):
       
    80     # a single path string, so just return it as-is (nothing to do)
       
    81     return path_parts
       
    82   
       
    83   flattened_parts = []
       
    84   
       
    85   for part in path_parts:
       
    86     if not part:
       
    87       # encountered a "False" element, which invalidates everything else
       
    88       return None    
       
    89   
       
    90     if isinstance(part, (list, tuple)):
       
    91       flattened_parts.extend(part)
       
    92     else:
       
    93       flattened_parts.append(part)
       
    94 
       
    95   return '/'.join(flattened_parts)
       
    96 
       
    97 
       
    98 def nameDocument(partial_path, link_name=None):
       
    99   """Returns a Document key name constructed from a path and link name.
       
   100     
       
   101   Args:
       
   102     partial_path: the first portion of the path to the Document that uniquely
       
   103       identifies it
       
   104     link_name: optional link name to append to path (when omitted,
       
   105       partial_path is actually the entire path, with the link_name already
       
   106       appended)
       
   107 
       
   108   Raises:
       
   109     Error if partial_path and link_Name produce a "False" path (None,
       
   110     empty string, etc.)
       
   111   """
       
   112   path = [partial_path]
       
   113   
       
   114   if link_name:
       
   115     path.append(link_name)
       
   116 
       
   117   path = combinePath(path)
       
   118 
       
   119   if not path:
       
   120     raise Error('"path" must be non-False: "%s"' % path)
       
   121 
       
   122   return 'Document:%s' % path
    34 
   123 
    35 
   124 
    36 def nameSiteSettings(path):
   125 def nameSiteSettings(path):
    37   """Returns a SiteSettings key name constructed from a supplied path."""
   126   """Returns a SiteSettings key name constructed from a supplied path.
    38   return '%(type)s:%(path)s' % {
   127   
    39       'type': soc.models.site_settings.SiteSettings.__name__,
   128   Raises:
    40       'path': path,
   129     Error if path is "False" (None, empty string, etc.)
    41       }
   130   """
    42 
   131   if not path:
    43 
   132     raise Error('"path" must be non-False: "%s"' % path)
    44 def nameDocument(path, link_name):
   133 
    45   """Returns a Document key name constructed from a path and link name."""
   134   return 'SiteSettings:%s' % path
    46   return '%(type)s:%(path)s/%(link_name)s' % {
       
    47       'type': soc.models.document.Document.__name__,
       
    48       'path': path,
       
    49       'link_name': link_name,
       
    50       }
       
    51 
   135 
    52 
   136 
    53 def nameUser(email):
   137 def nameUser(email):
    54   """Returns a User key name constructed from a supplied email address."""
   138   """Returns a User key name constructed from a supplied email address.
    55   return '%(type)s:%(email)s' % {
   139   
    56       'type': soc.models.user.User.__name__,
   140   Raises:
    57       'email': email,
   141     Error if email is "False" (None, empty string, etc.)
    58       }
   142   """
       
   143   if not email:
       
   144     raise Error('"email" must be non-False: "%s"' % email)
       
   145 
       
   146   return 'User:%s' % email
    59 
   147 
    60 
   148 
    61 def nameSponsor(link_name):
   149 def nameSponsor(link_name):
    62   """Returns a Sponsor key name constructed from a supplied link name."""
   150   """Returns a Sponsor key name constructed from a supplied link name.
    63   return '%(group)s/%(type)s:%(link_name)s' % {
   151 
    64       'group': soc.models.group.Group.__name__,
   152   Raises:
    65       'type': soc.models.sponsor.Sponsor.__name__,
   153     Error if link_name is "False" (None, empty string, etc.)
    66       'link_name': link_name,
   154   """
    67       }
   155   if not link_name:
       
   156     raise Error('"link_name" must be non-False: "%s"' % link_name)
       
   157 
       
   158   return 'Group/Sponsor:%s' % link_name
    68 
   159 
    69 
   160 
    70 def nameSchool(sponsor_ln, program_ln, link_name):
   161 def nameSchool(sponsor_ln, program_ln, link_name):
    71   """Returns a School key name constructed from a supplied sponsor,
   162   """Returns a School key name constructed from link names.
    72      program and school link names.
   163      
    73   """
   164   Args:
    74   return '%(group)s/%(type)s:%(sponsor)s/%(program)s/%(link_name)s' % {
   165     sponsor_ln: Sponsor link name
    75       'group': soc.models.group.Group.__name__,
   166     program_ln: Program link name
    76       'type': soc.models.school.School.__name__,
   167     link_name: School link name
    77       'sponsor': sponsor_ln,
   168 
    78       'program': program_ln,
   169   Raises:
    79       'link_name': link_name,
   170     Error if sponsor_ln, program_ln, and link_Name combine to produce
    80       }
   171     a "False" path (None, empty string, etc.)
       
   172   """
       
   173   path = combinePath([[sponsor_ln, program_ln], link_name])
       
   174   
       
   175   if not path:
       
   176     raise Error('"path" must be non-False: "%s"' % path)
       
   177   
       
   178   return 'Group/School:%s' % path
    81 
   179 
    82 
   180 
    83 def nameOrganization(sponsor_ln, program_ln, link_name):
   181 def nameOrganization(sponsor_ln, program_ln, link_name):
    84   """Returns a Organization key name constructed from a supplied sponsor,
   182   """Returns a Organization key name constructed from link names.
    85      program and organization link names.
   183      
    86   """
   184   Args:
    87   return '%(group)s/%(type)s:%(sponsor)s/%(program)s/%(link_name)s' % {
   185     sponsor_ln: Sponsor link name
    88       'group': soc.models.group.Group.__name__,
   186     program_ln: Program link name
    89       'type': soc.models.organization.Organization.__name__,
   187     link_name: Organization link name
    90       'sponsor': sponsor_ln,
   188 
    91       'program': program_ln,
   189   Raises:
    92       'link_name': link_name,
   190     Error if sponsor_ln, program_ln, and link_Name combine to produce
    93       }
   191     a "False" path (None, empty string, etc.)
       
   192   """
       
   193   path = combinePath([[sponsor_ln, program_ln], link_name])
       
   194   
       
   195   if not path:
       
   196     raise Error('"path" must be non-False: "%s"' % path)
       
   197   
       
   198   return 'Group/Organization:%s' % path 
    94 
   199 
    95 
   200 
    96 def nameClub(link_name):
   201 def nameClub(link_name):
    97   """Returns a Club key name constructed from a supplied link name."""
   202   """Returns a Club key name constructed from a supplied link name.
    98   return '%(group)s/%(type)s:%(link_name)s' % {
   203 
    99       'group': soc.models.group.Group.__name__,
   204   Raises:
   100       'type': soc.models.sponsor.Sponsor.__name__,
   205     Error if link_name is "False" (None, empty string, etc.)
   101       'link_name': link_name,
   206   """
   102       }
   207   if not link_name:
   103   
   208     raise Error('"link_name" must be non-False: "%s"' % link_name)
       
   209 
       
   210   return 'Group/Club:%s' % link_name