From e060d755e68f69218fb50d25216b5c2e163064ed Mon Sep 17 00:00:00 2001 From: gfawcett Date: Thu, 15 Jul 2010 00:55:13 +0000 Subject: [PATCH] working around z3950/unicode issues; several minor changes. git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/trunk@917 6d9bc8c9-1ec2-4278-b937-99fde70a366f --- conifer/libsystems/z3950/marcxml.py | 12 +++++-- conifer/libsystems/z3950/pyz3950_search.py | 17 +++------- conifer/syrup/models.py | 41 +++++++++++++++++------- conifer/syrup/views/sites.py | 18 +++++++---- conifer/templates/admin/index.xhtml | 8 ++++- conifer/templates/components/site.xhtml | 15 ++++++--- conifer/templates/item/item_add_cat_search.xhtml | 3 +- 7 files changed, 73 insertions(+), 41 deletions(-) diff --git a/conifer/libsystems/z3950/marcxml.py b/conifer/libsystems/z3950/marcxml.py index aaf466c..50a5f84 100644 --- a/conifer/libsystems/z3950/marcxml.py +++ b/conifer/libsystems/z3950/marcxml.py @@ -1,7 +1,11 @@ from xml.etree import ElementTree +# Note: the 'record' parameters passed to these functions must be +# Unicode strings, not plain Python strings. + def marcxml_to_records(rec): - tree = ElementTree.fromstring(rec) + assert isinstance(rec, unicode) + tree = ElementTree.fromstring(rec.encode('utf-8')) if tree.tag == '{http://www.loc.gov/MARC21/slim}collection': # then we may have multiple records records = tree.findall('{http://www.loc.gov/MARC21/slim}record') @@ -12,7 +16,8 @@ def marcxml_to_records(rec): return records def record_to_dictionary(record, multiples=True): - tree = ElementTree.fromstring(record) + assert isinstance(record, unicode) + tree = ElementTree.fromstring(record.encode('utf-8')) dct = {} for df in tree.findall('{http://www.loc.gov/MARC21/slim}datafield'): t = df.attrib['tag'] @@ -24,7 +29,8 @@ def record_to_dictionary(record, multiples=True): return dct def marcxml_to_dictionary(rec, multiples=False): - tree = ElementTree.fromstring(rec) + assert isinstance(rec, unicode) + tree = ElementTree.fromstring(rec.encode('utf-8')) if tree.tag == '{http://www.loc.gov/MARC21/slim}collection': # then we may have multiple records records = tree.findall('{http://www.loc.gov/MARC21/slim}record') diff --git a/conifer/libsystems/z3950/pyz3950_search.py b/conifer/libsystems/z3950/pyz3950_search.py index b111f46..dbdbf7e 100644 --- a/conifer/libsystems/z3950/pyz3950_search.py +++ b/conifer/libsystems/z3950/pyz3950_search.py @@ -72,22 +72,15 @@ def search(host, port, database, query, start=1, limit=10): parsed = [] for rec in raw_records: - try: - rec = _marc_utf8_pattern.sub(_decode_marc_utf8, rec) - except 'x': - raise rec + # TODO: fix this ascii/replace, once our z3950/marc encoding + # issues are sorted out. + rec = unicode(rec, 'ascii', 'replace') + + assert isinstance(rec, unicode) # this must be true. parsed.append(rec) return parsed, len(res) -# decoding MARC \X.. UTF-8 patterns. - -_marc_utf8_pattern = re.compile(r'\\X([0-9A-F]{2})', re.I) - -def _decode_marc_utf8(regex_match): - return chr(int(regex_match.group(1), 16)) - - #------------------------------------------------------------ # some tests diff --git a/conifer/syrup/models.py b/conifer/syrup/models.py index abed3a8..929423b 100644 --- a/conifer/syrup/models.py +++ b/conifer/syrup/models.py @@ -52,6 +52,9 @@ class UserExtensionMixin(object): return self.is_staff or \ bool(callhook('can_create_sites', self)) + def get_list_name(self): + return '%s, %s (%s)' % (self.last_name, self.first_name, self.username) + @classmethod def active_instructors(cls): """Return a queryset of all active instructors.""" @@ -87,7 +90,7 @@ class UserProfile(BaseModel): # Lookup tables class ServiceDesk(BaseModel): - name = m.CharField(max_length=100) + name = m.CharField(max_length=100, unique=True) active = m.BooleanField(default=True) external_id = m.CharField(max_length=256, blank=True, null=True) @@ -95,13 +98,17 @@ class ServiceDesk(BaseModel): return self.name class Term(BaseModel): - code = m.CharField(max_length=64) + code = m.CharField(max_length=64, unique=True) name = m.CharField(max_length=256) start = m.DateField('Start (Y-M-D)') finish = m.DateField('Finish (Y-M-D)') + class Meta: + ordering = ['start', 'code'] + def __unicode__(self): - return self.code or self.name + return '%s: %s' % (self.code, self.name) + class Department(BaseModel): name = m.CharField(max_length=256) @@ -111,14 +118,19 @@ class Department(BaseModel): def __unicode__(self): return self.name + class Course(BaseModel): """An abstract course (not a course offering.)""" - code = m.CharField(max_length=64) + code = m.CharField(max_length=64, unique=True) name = m.CharField(max_length=1024) department = m.ForeignKey(Department) + class Meta: + ordering = ['code'] + def __unicode__(self): - return self.name + return '%s: %s' % (self.code, self.name) + class Z3950Target(m.Model): name = m.CharField(max_length=100) @@ -132,7 +144,7 @@ class Z3950Target(m.Model): return self.name class Config(m.Model): - name = m.CharField(max_length=256) + name = m.CharField(max_length=256, unique=True) value = m.CharField(max_length=8192) @classmethod @@ -254,13 +266,18 @@ class Site(BaseModel): 'user__last_name', 'user__first_name') def can_edit(self, user): + """ + Return True if the user has permission to edit this + site. Staff, site owners and site instructors all have editing + permissions. + """ if user.is_anonymous(): return False - if user.id == self.owner_id: + if (user.id == self.owner_id) or user.is_staff: return True try: mbr = self.members().get(user=user) - except Member.DoesNotExist: + except Membership.DoesNotExist: return False return mbr.role in (u'INSTR', u'ASSIST') @@ -268,14 +285,14 @@ class Site(BaseModel): """Return True if the user could feasibly register into this site: she's not already in it, and the site allows open registration.""" - return user.is_authenticated() \ - and self.access in ('ANON', 'LOGIN') \ + return self.access in ('ANON', 'LOGIN') \ and not self.is_member(user) def is_member(self, user): assert user - return user.id == self.owner_id \ - or self.members().filter(user=user).exists() + return user.is_authenticated() and ( + user.id == self.owner_id \ + or bool(self.members().filter(user=user))) #------------------------------------------------------------ # User membership in sites diff --git a/conifer/syrup/views/sites.py b/conifer/syrup/views/sites.py index 4489f10..c0167fb 100644 --- a/conifer/syrup/views/sites.py +++ b/conifer/syrup/views/sites.py @@ -18,6 +18,14 @@ class NewSiteForm(ModelForm): else: raise ValidationError, _('invalid course code') + def __init__(self, *args, **kwargs): + owner = self.base_fields['owner'] + owner.label_from_instance = lambda u: u.get_list_name() + owner.queryset = User.objects.order_by('last_name', 'first_name', 'username') + + super(NewSiteForm, self).__init__(*args, **kwargs) + + # if we have course-code lookup, hack lookup support into the new-course form. COURSE_CODE_LIST = bool(models.campus.course_code_list) @@ -35,7 +43,7 @@ COURSE_CODE_LOOKUP_TITLE = bool(models.campus.course_code_lookup_title) # NewSiteForm.base_fields['code'].empty_label = empty_label #-------------------- - + @login_required def add_new_site(request): if not request.user.can_create_sites(): @@ -46,7 +54,7 @@ def add_new_site(request): def edit_site(request, site_id): instance = get_object_or_404(models.Site, pk=site_id) return _add_or_edit_site(request, instance=instance) - + def _add_or_edit_site(request, instance=None): is_add = (instance is None) if is_add: @@ -67,11 +75,7 @@ def _add_or_edit_site(request, instance=None): site.generate_new_passkey() site.save() assert site.id - user_in_site = site.is_member(request.user) - if not user_in_site: # for edits, might already be! - mbr = site.member_set.create(user=request.user, role='INSTR') - mbr.save() - + if is_add or (current_access_level != site.access): # we need to configure permissions. return HttpResponseRedirect(site.site_url('edit/permission/')) diff --git a/conifer/templates/admin/index.xhtml b/conifer/templates/admin/index.xhtml index e7547ec..930aea3 100644 --- a/conifer/templates/admin/index.xhtml +++ b/conifer/templates/admin/index.xhtml @@ -7,6 +7,9 @@ title = _('Administrative Options') ${title} +

${title}

@@ -24,7 +27,7 @@ title = _('Administrative Options') + diff --git a/conifer/templates/components/site.xhtml b/conifer/templates/components/site.xhtml index 7b63bc9..80382cd 100644 --- a/conifer/templates/components/site.xhtml +++ b/conifer/templates/components/site.xhtml @@ -18,7 +18,10 @@ searchtext = _('search this site...')
${site_search(site)} -
${site.course.department} • ${site.term.name}
+
+ ${site.owner.last_name} + • ${site.term.name} + • ${site.course.department}

${site.course.code}: ${site.course.name}

@@ -61,9 +64,13 @@ searchtext = _('search this site...') py:with="hier=item.hierarchy()[:-1]; lastnum=len(hier)" class="nestedtitle"> diff --git a/conifer/templates/item/item_add_cat_search.xhtml b/conifer/templates/item/item_add_cat_search.xhtml index fa8ace3..48b06f7 100644 --- a/conifer/templates/item/item_add_cat_search.xhtml +++ b/conifer/templates/item/item_add_cat_search.xhtml @@ -1,5 +1,4 @@
- +
-- 2.11.0