def __init__(self, context, request): super(UnexpectedZope2, self).__init__(context, request) contentType = 'text/html; charset=UTF-8' self.request.response.setHeader(to_ascii('Content-Type'), to_ascii(contentType)) self.request.response.setStatus(self.status) # , lock=True)
def set_header(self, filename): """Set the current request-header to the correct value. :param str filename: The name of the page if it is saved. :returns: Nothing. :raises ValueError: There is no :attr:`self.request` or :attr:`self.request.response` Normally browsers *assume* that the document being viewed in ``text/html``. This method sets the ``Content-type`` header to ``text/plain; charset=UTF-8`` so the message looks correct. In addition the ``Content-disposition`` header is set so :obj:`filename` is the name of the page when it is saved. (This is mostly useful for debugging.)""" if not hasattr(self, 'request'): m = '{0} has no "request"'.format(self) raise ValueError(m) if not hasattr(self.request, 'response'): m = '{0} ({1}) has no "response"'.format(self.request, self) raise ValueError(m) response = self.request.response ctype = 'text/plain; charset={0}'.format(self.charset) response.setHeader(to_ascii("Content-Type"), to_ascii(ctype)) disposition = 'inline; filename="{0}"'.format(filename) response.setHeader(to_ascii('Content-Disposition'), to_ascii(disposition))
def reset_content_type(self): '''Set the ``Content-type`` header for the current ``request.response``. The templates (especially the text-templates) tend to set the content type to ``text/plain; charset=utf-8``. This method sets the header back to what it was originally, or ``text/html`` if it was never set.''' self.request.response.setHeader(to_ascii('Content-Type'), to_ascii(self.oldContentType))
def __get_group_object_by_id(self, groupId): retval = None site_root = self.context.site_root() content = getattr(site_root, b'Content') site = getattr(content, to_ascii(self.siteInfo.id)) groups = getattr(site, b'groups') if hasattr(groups, to_ascii(groupId)): retval = getattr(groups, to_ascii(groupId)) return retval
def message_body(self, userInfo): gn = to_ascii(self.groupInfo.name) sn = to_ascii(self.siteInfo.name) cp = self.can_post_for_user(userInfo) m = 'I had a problem sending an email to %s on %s <%s>. '\ 'The issue was "%s (Reason Number %s)"' % \ (gn, sn, self.groupInfo.url, cp.status, cp.statusNum) retval = 'Hi!\n\n%s\n\nI need your help because...' % \ TextWrapper().fill(m) return retval
def info(self, code, instanceDatum='', supplementaryDatum=''): d = datetime.now(UTC) iD = to_ascii(instanceDatum) sD = to_ascii(supplementaryDatum) eventId = event_id_from_data(self.userInfo, self.userInfo, self.siteInfo, code, iD, sD) e = self.factory(self.userInfo.user, eventId, code, d, self.userInfo, None, self.siteInfo, None, instanceDatum, supplementaryDatum, SUBSYSTEM) self.queries.store(e) log.info(e)
def marshall_file(self, f): url = '{0}/messages/topic/{1}/#post-{1}'.format(self.groupInfo.relativeURL, f['post_id']) retval = { 'name': f['file_name'], 'url': to_ascii(url), 'icon': get_icon(f['mime_type']), } return retval
def set_data(self, data): assert self.folder assert self.form_fields assert self.versionForChange assert self.auditor assert data nvId = new_version_id() while nvId in self.folder.objectIds(): nvId = new_version_id() newVersion = new_version(self.folder, nvId) fields = self.form_fields.omit('id', 'parentVersion', 'editor', 'creationDate') form.applyChanges(newVersion, fields, data) newVersion.parentVersion = to_ascii(self.versionForChange.id) userInfo = createObject('groupserver.LoggedInUser', self.folder) newVersion.editor = to_unicode_or_bust(userInfo.id) i, s = self.get_auditDatums(self.versionForChange, newVersion) self.auditor.info(EDIT_CONTENT, i, s) # Handle publishing here if data['published']: self.folder.published_revision = newVersion.id self.status = '%s %s' % \ ('Published' if data['published'] else 'Changed', data['title']) assert self.status
def create(self, groupName, groupId, groupPrivacy, mailHost, adminInfo): if not groupName: raise ValueError('No group name') if not groupId: raise ValueError('No group identifier') if not isinstance(groupId, basestring): m = 'Group identifier a {0}, not a string' raise TypeError(m.format(type(groupId))) gid = to_ascii(groupId) if not groupPrivacy: raise ValueError('No group privacy') if not mailHost: raise ValueError('No mail host') if not adminInfo: raise ValueError('No administrator information') group = self.create_group_folder(gid.lower()) self.set_security(group, adminInfo) self.create_administration(group) self.set_group_properties(group, groupName) self.create_list(group, mailHost) self.create_messages_area(group) self.create_files_area(group) self.set_group_privacy(group, groupPrivacy) notify(GSGroupCreatedEvent(group)) groupInfo = GSGroupInfo(group) auditor = Auditor(self.site_root, self.siteInfo) auditor.info(START, adminInfo, groupInfo, groupName, groupPrivacy) assert groupInfo return groupInfo
def get_description(self): desc = '' if self.group_exists(): d = self.groupObj.getProperty('description', None) desc = d if d else '' retval = to_ascii(desc) return retval
def handle_manage(self, action, data): self.status = 'Should manage {0}'.format(data['members']) membersToManage = quote(' '.join(data['members'])) u = '{0}/managemembers.html?showOnly={1}' uri = to_ascii(u.format(self.groupInfo.relative_url(), membersToManage)) return self.request.RESPONSE.redirect(uri)
def search_files(self, searchKeywords, groupIds, authorIds, mimeTypes): # --=mpj17=--TODO: Site ID! log.debug("Performing search for %s, groups %s, authors %s" % (searchKeywords, groupIds, authorIds)) site_root = self.context.site_root() assert hasattr(site_root, 'FileLibrary2'), \ 'Cannot search: file library not found' fileLibrary = site_root.FileLibrary2 # --=mpj17=-- Without this to_ascii call I get # ValueError: invalid literal for int() with base 10: 's' # Ask me not why. fileLibraryPath = to_ascii('/'.join(fileLibrary.getPhysicalPath())) postedFiles = self.search_files_in_path( searchKeywords, groupIds, fileLibraryPath, 'XWF File 2', authorIds, mimeTypes) # --=mpj17=-- TODO: Site ID! postedFiles = [o for o in postedFiles if o] postedFiles.sort(self.sort_file_results) fileIds = [] retval = [] for o in postedFiles: if o['id'] not in fileIds: fileIds.append(o['id']) retval.append(o) return retval
def search_files(self, searchKeywords, groupIds, authorIds, mimeTypes): # --=mpj17=--TODO: Site ID! log.debug("Performing search for %s, groups %s, authors %s" % (searchKeywords, groupIds, authorIds)) site_root = self.context.site_root() assert hasattr(site_root, 'FileLibrary2'), \ 'Cannot search: file library not found' fileLibrary = site_root.FileLibrary2 # --=mpj17=-- Without this to_ascii call I get # ValueError: invalid literal for int() with base 10: 's' # Ask me not why. fileLibraryPath = to_ascii('/'.join(fileLibrary.getPhysicalPath())) postedFiles = self.search_files_in_path(searchKeywords, groupIds, fileLibraryPath, 'XWF File 2', authorIds, mimeTypes) # --=mpj17=-- TODO: Site ID! postedFiles = [o for o in postedFiles if o] postedFiles.sort(self.sort_file_results) fileIds = [] retval = [] for o in postedFiles: if o['id'] not in fileIds: fileIds.append(o['id']) retval.append(o) return retval
def marshall_author_info(authorInfo): retval = { 'id': authorInfo.id, 'exists': not authorInfo.anonymous, 'url': to_ascii(authorInfo.url), 'name': authorInfo.name, } return retval
def notify(self, userInfo, problemAddress, toAddresses): subject = 'Email delivery problems (action required)' text = self.textTemplate(userInfo=userInfo, email=problemAddress) html = self.htmlTemplate(userInfo=userInfo, email=problemAddress) ms = MessageSender(self.context, userInfo) ms.send_message(subject, text, html, toAddresses=toAddresses) self.request.response.setHeader(to_ascii('Content-Type'), self.oldContentType)
def supportAddress(self, userInfo): gn = to_ascii(self.groupInfo.name) s = 'Subject=%s' % quote('Cannot Post to %s' % gn) b = 'body=%s' % quote(self.message_body(userInfo)) # FIXME: use a siteInfo to get the support email address e = get_support_email(self.context, self.siteInfo.id) retval = 'mailto:%s?%s&%s' % (e, b, s) return retval
def manage_addXWFVirtualFileFolder2(self, folderId, title='', REQUEST=None, RESPONSE=None, submit=None): """ Add a new instance of XWFVirtualFileFolder """ folderId = convertTextToId(folderId) title = to_ascii(title) or to_ascii(folderId) obj = XWFVirtualFileFolder2(folderId, title) self._setObject(folderId, obj) obj = getattr(self, folderId) if RESPONSE and submit: if submit.strip().lower() == 'add': RESPONSE.redirect('%s/manage_main' % self.DestinationURL()) else: RESPONSE.redirect('%s/manage_main' % folderId)
class IOGNLogitudinalInfo(IContentProvider): # --=mpj17=-- No i18n needed for content provider pageTemplateFileName = ASCIILine( title="Page Template File Name", description='The name of the ZPT file that is used to ' 'render the status message.', required=False, default=to_ascii("browser/templates/tioucscript.pt"))
def notify(self, siteInfo, userInfo, resetLink, toAddr): s = 'Password reset at {0} (action required)' subject = s.format(siteInfo.name) text = self.textTemplate(userInfo=userInfo, resetLink=resetLink) html = self.htmlTemplate(userInfo=userInfo, resetLink=resetLink) ms = MessageSender(self.context, userInfo) ms.send_message(subject, text, html, toAddresses=[toAddr]) self.request.response.setHeader(to_ascii('Content-Type'), self.oldContentType)
def get_url(self): if 'image' in self.get_type(): r = '/r/img/%s' % self.get_id() else: t = self.get_title().encode('ascii', 'ignore') r = '/r/file/%s/%s' % (self.get_id(), quote(t)) url = '%s%s' % (self.groupInfo.siteInfo.url, r) retval = to_ascii(url) return retval
def marshall_file(self, f): url = '{0}/messages/topic/{1}/#post-{1}'.format( self.groupInfo.relativeURL, f['post_id']) retval = { 'name': f['file_name'], 'url': to_ascii(url), 'icon': get_icon(f['mime_type']), } return retval
def get_earlier_url(self): newStart = self.end - self.numSticky newEnd = newStart + self.summaryLength if newStart < self.numTopics: url = 'topics.html?start=%d&end=%d' % (newStart, newEnd) else: url = '' retval = to_ascii(url) return retval
def init_catalog(gss): '''Initalise the ZODB catalog.''' CATALOG_NAME = b'Catalog' mAP = gss.manage_addProduct['XWFCore'] mAP.manage_addXWFCatalog(CATALOG_NAME) catalog = getattr(gss, CATALOG_NAME) catalogEntries = ('content_type', 'dc_creator', 'group_ids', 'id', 'indexable_summary', 'meta_type', 'modification_time', 'size', 'tags', 'title', 'topic') keysToAdd = { 'allowedRolesAndUsers': 'KeywordIndex', 'content_type': 'FieldIndex', 'dc_creator': 'FieldIndex', 'group_ids': 'KeywordIndex', 'id': 'FieldIndex', 'indexable_content': 'ZCTextIndex', 'meta_type': 'FieldIndex', 'modification_time': 'DateIndex', 'tags': 'KeywordIndex', 'title': 'FieldIndex', 'topic': 'FieldIndex', 'dc_description': 'ZCTextIndex', 'dc_title': 'KeywordIndex', 'dc_valid': 'DateIndex', 'linked_resources': 'KeywordIndex', 'path': 'PathIndex', 'resource_locator': 'KeywordIndex', } for key in list(keysToAdd.keys()): try: catalog.manage_addIndex(to_ascii(key), to_ascii(keysToAdd[key])) except: # The key is already in the index pass for catalogEntry in catalogEntries: try: catalog.manage_addColumn(to_ascii(key)) except: # The key is already in the column pass
class ChangeGroupType(GroupForm): 'The Change Group Type page view' label = 'Change group type' pageTemplateFileName = to_ascii('browser/templates/form.pt') template = ZopeTwoPageTemplateFile(pageTemplateFileName) interface = IChangeGroupType @Lazy def form_fields(self): form_fields = form.Fields(self.interface, render_context=False) form_fields['groupType'].custom_widget = radio_widget return form_fields def setUpWidgets(self, ignore_request=False): currentType = IUnsetType(self.context).setTypeId data = {'groupType': currentType} self.widgets = form.setUpWidgets(self.form_fields, self.prefix, self.context, self.request, form=self, data=data, ignore_request=ignore_request) @staticmethod def a_or_an(s): return 'an' if (s[0] in 'aeiou') else 'a' @form.action(label='Change', failure='handle_change_action_failure') def handle_change(self, action, data): # Note that it is importtant to get the setter and unsetter *before* # calling unset. After unset is called the group is (briefly) not # a group, so the adapter will fail. unsetter = IUnsetType(self.context) gsm = getGlobalSiteManager() setter = gsm.getAdapter(self.context, ISetType, data['groupType']) unsetter.unset() setter.set() # The name of the group-type in the setter is long, so get the # short-name from a new unsetter. newType = IUnsetType(self.context).name.lower() oldType = unsetter.name.lower() auditor = Auditor(self.siteInfo, self.groupInfo, self.loggedInUser) auditor.info(CHANGE_TYPE, newType, oldType) s = 'Changed {0} <strong>to {1} {2}</strong> from {3} {4}.' self.status = s.format(self.groupInfo.name, self.a_or_an(newType), newType, self.a_or_an(oldType), oldType) def handle_change_action_failure(self, action, data, errors): if len(errors) == 1: self.status = '<p>There is an error:</p>' else: self.status = '<p>There are errors:</p>' self.status = data
def __init__(self, virtualMailingListFolder, request): super(StickySetter, self).__init__(virtualMailingListFolder, request) self.topicId = request.get('topicId', None) response = self.request.response response.setHeader(b"Content-Type", b'text/plain; charset=UTF-8') filename = '%s-%s-%s-set.txt' % (self.siteInfo.id, self.groupInfo.id, self.topicId) response.setHeader(b'Content-Disposition', to_ascii('inline; filename="%s"' % filename))
def thumbnail_url(self): url = '' typePart = self.get_type().split('/')[0] if typePart == 'image': d = {'group': self.get_group_info().relative_url(), 'fileId': self.get_id(), 'name': self.get_title()} url = '%(group)s/files/f/%(fileId)s/resize/405/303/%(name)s' % d retval = to_ascii(url) return retval
def subsetIds(self): adminIds = set(self.group.users_with_local_role('GroupAdmin')) for uId in adminIds.difference(self.memberIds): m = 'The user ID %s is listed as an administrator of the group %s (%s) on the '\ 'site %s (%s), but is not a member of the group.' %\ (uId, self.groupInfo.name, self.groupInfo.id, self.siteInfo.name, self.siteInfo.id) msg = to_ascii(m) log.warn(msg) retval = self.memberIds.intersection(adminIds) return retval
def get_earlier_url(self): assert hasattr(self, 'end') newStart = self.end newEnd = newStart + self.chunkLength if newStart < self.numPosts: url = 'posts.html?start=%d&end=%d' % (newStart, newEnd) else: url = '' retval = to_ascii(url) return retval
def mailto(to, subject, body): '''Create a ``mailto:`` URL''' qTo = quote(to) qSubject = quote(subject) try: qBody = quote(body) except KeyError: # --=mpj17=-- Why is it a KeyError? u = to_ascii(body) qBody = quote(u) retval = MAILTO.format(to=qTo, subject=qSubject, body=qBody) return retval
class IGSSiteStatsContentProvider(IContentProvider): siteId = ASCIILine(title='Site Identifier', description='The identifier for the site', required=True) pageTemplateFileName = ASCIILine( title="Page Template File Name", description='The name of the ZPT file that is used to render the ' 'status message.', required=False, default=to_ascii("browser/templates/contentprovider.pt"))
def thumbnail_url(self): url = '' typePart = self.get_type().split('/')[0] if typePart == 'image': d = { 'group': self.get_group_info().relative_url(), 'fileId': self.get_id(), 'name': self.get_title() } url = '%(group)s/files/f/%(fileId)s/resize/405/303/%(name)s' % d retval = to_ascii(url) return retval
def imageFile(self): g = self.groupInfo.groupObj.aq_explicit if not hasattr(g, to_ascii('files')): m = 'No "files" in {0} ({1})' msg = m.format(self.groupInfo.name, self.groupInfo.id) raise ValueError(msg) fileLibrary = self.groupInfo.groupObj.files retval = fileLibrary.get_file_by_id(self.imageId) if not retval: m = 'Could not get image for ID "{0}".'.format(self.imageId) raise ValueError(m) return retval
def __call__(self): # TODO: Add X-Sendfile for uWSGI offloading # http://uwsgi-docs.readthedocs.org/en/latest/articles/OffloadingWebsocketsAndSSE.html#uwsgi-offloading try: h = 'inline; filename={0}-square-{1}.jpg' hdr = h.format(self.userInfo.nickname, self.size) self.request.RESPONSE.setHeader(b'Content-Disposition', to_ascii(hdr)) self.request.RESPONSE.setHeader(b'Cache-Control', b'private; max-age=1200') self.request.RESPONSE.setHeader( b'Content-Length', to_ascii(str(self.image.getSize()))) self.request.RESPONSE.setHeader( b'Content-Type', to_ascii(self.image.contentType)) retval = self.image.data except IOError: missingImage = b'/++resource++gs-profile-image-square-missing.jpg' retval = self.request.RESPONSE.redirect(missingImage) return retval
def create_user(site, email, fn, password): 'Create a user' user = create_user_from_email(site, email) user.manage_changeProperties(fn=fn) # We want the userInfo in the context of the site ui = createObject('groupserver.UserFromId', site, user.getId()) pu = PasswordUser(ui) pu.set_password(password) try: vid = 'AssumedTrue%s' % email.replace('@', 'at') evu = EmailVerificationUser(site, ui, email) evu.add_verification_id(vid) evu.verify_email(vid) m = 'create_user: Verified the address <{0}> for {1} ({2}).' msg = m.format(email, fn, user.getId()) log.info(to_ascii(msg)) except Exception as e: m = 'create_user: Issues verifying the address <{0}> for {1} ({2}).' msg = m.format(email, fn, user.getId()) log.error(to_ascii(msg)) raise e return user
def member_id(groupId): '''Get the group membership ID from the group id :param str groupId: The identifier for the group :returns: The identifier for the member-group in ``acl_users`` :rtype: str''' if not (isinstance(groupId, aString)): raise TypeError('Expected string, got {0}'.format(type(groupId))) if not groupId: raise ValueError('The groupId must be set (is "{0}")'.format(groupId)) retval = to_ascii('{0}_member'.format(groupId)) return retval
def __call__(self): # TODO: Add X-Sendfile for uWSGI offloading # http://uwsgi-docs.readthedocs.org/en/latest/articles/OffloadingWebsocketsAndSSE.html#uwsgi-offloading try: h = 'inline; filename={0}-square-{1}.jpg' hdr = h.format(self.userInfo.nickname, self.size) self.request.RESPONSE.setHeader(b'Content-Disposition', to_ascii(hdr)) self.request.RESPONSE.setHeader(b'Cache-Control', b'private; max-age=1200') self.request.RESPONSE.setHeader( b'Content-Length', to_ascii(str(self.image.getSize()))) self.request.RESPONSE.setHeader(b'Content-Type', to_ascii(self.image.contentType)) retval = self.image.data except IOError: missingImage = b'/++resource++gs-profile-image-square-missing.jpg' retval = self.request.RESPONSE.redirect(missingImage) return retval
def member_id(groupId): '''Get the group membership ID from the group id :param str groupId: The identifier for the group :returns: The identifier for the member-group in ``acl_users`` :rtype: str''' if not(isinstance(groupId, aString)): raise TypeError('Expected string, got {0}'.format(type(groupId))) if not groupId: raise ValueError('The groupId must be set (is "{0}")'.format(groupId)) retval = to_ascii('{0}_member'.format(groupId)) return retval
def notify(self, toAddress, origMesg): s = '{0}: Problem Posting (Action Required)'.format( self.groupInfo.name) email = parseaddr(toAddress)[1] text = self.textTemplate(email=email) html = self.htmlTemplate(email=email) fromAddress = self.siteInfo.get_support_email() msg = self.create_message(s, text, html, origMesg, fromAddress, toAddress) # TODO: Audit # --=mpj17=-- Forward error-correction, to ensure we have everything # needed to send the message. if fromAddress and email and msg: lm = 'Sending "{0}" to <{1}> from <{2}>' logMsg = to_ascii(lm.format(s, email, fromAddress)) log.info(logMsg) send_email(fromAddress, email, msg) else: lm = 'Failed to send "{0}" message of length {1} to <{2}> '\ 'from <{3}>' logMsg = to_ascii(lm.format(s, len(msg), toAddress, fromAddress)) log.info(logMsg)
def __call__(self): # TODO: Handle the 410 (Gone) post here. Hidden posts will # sometimes raise a 410 # <https://projects.iopen.net/groupserver/ticket/316> try: retval = getMultiAdapter((self.context, self.request), name="gspost")() except NoIDError as n: # lint:ok u = '{0}/messages/topics.html'.format(self.groupInfo.url) m = 'No post ID in <%s>. Going to <%s>' log.info(m, self.request.URL, u) uri = to_ascii(u) retval = self.request.RESPONSE.redirect(uri) return retval
def get_later_url(self): newStart = self.start - self.summaryLength if newStart < 0: newStart = 0 newEnd = newStart + self.summaryLength if newStart != self.start and newStart: url = 'topics.html?start=%d&end=%d' % (newStart, newEnd) elif newStart != self.start and not newStart: url = 'topics.html' else: url = '' retval = to_ascii(url) return retval
def get_file_by_id(self, fileId): fid = to_ascii(fileId) retval = None fileInfo = self.fileQuery.file_info(fid) groupInfo = createObject('groupserver.GroupInfo', self) if fileInfo is None: raise NotFound(self, fid) elif fileInfo['group_id'] != groupInfo.id: m = u'The file {0} is not in the group {1}' raise Unauthorized(m.format(fid, groupInfo.id)) else: l = self.get_xwfFileLibrary() s = l.get_fileStorage() retval = s.get_file(fid) return retval
def notify(self, adminInfo, userInfo, fromAddr, toAddrs, invitationId, subject, message): assert toAddrs, 'No to address for %s' % userInfo.name text = self.textTemplate(adminInfo=adminInfo, userInfo=userInfo, fromAddr=fromAddr, toAddr=toAddrs[0], subject=subject, invitationId=invitationId, message=message, fakeHeader=False) html = self.htmlTemplate(adminInfo=adminInfo, userInfo=userInfo, fromAddr=fromAddr, toAddr=toAddrs[0], subject=subject, invitationId=invitationId, message=message, fakeHeader=False) ms = MessageSender(self.context, userInfo) ms.send_message(subject, text, html, fromAddr, toAddrs) self.request.response.setHeader(to_ascii('Content-Type'), self.oldContentType)