def member(self, request, segments, role, email): """Return a single member representation.""" if self._mlist is None: return http.not_found() members = getUtility(ISubscriptionService).find_members( email, self._mlist.list_id, role) if len(members) == 0: return http.not_found() assert len(members) == 1, 'Too many matches' return AMember(members[0].member_id)
def all(self, request, segments): """/members/<id>/all/preferences""" if len(segments) == 0: return http.not_found() if self._member is None: return http.not_found() child = ReadOnlyPreferences( self._member, 'members/{0}/all'.format(self._member.member_id.int)) return child, []
def test_not_found(self): r = http.not_found() assert r.status.startswith("404") assert r.headers["Content-Type"] == "text/plain" assert "404 Not Found" in r.body r = http.not_found([("Content-Type", "text/html")], "<p>404 Not Found</p>") assert r.status.startswith("404") assert r.headers["Content-Type"] == "text/html" assert r.body == "<p>404 Not Found</p>" exc = http.NotFoundError() r = exc.make_response() assert r.status.startswith("404")
def test_not_found(self): r = http.not_found() assert r.status.startswith('404') assert r.headers['Content-Type'] == 'text/plain' assert '404 Not Found' in r.body r = http.not_found([('Content-Type', 'text/html')], '<p>404 Not Found</p>') assert r.status.startswith('404') assert r.headers['Content-Type'] == 'text/html' assert r.body == '<p>404 Not Found</p>' exc = http.NotFoundError() r = exc.make_response() assert r.status.startswith('404')
def child(self, request, segments): if isinstance(self.metadata, dict): meta = self.metadata.get(segments[0]) elif isinstance(self.metadata, list): try: index = int(segments[0]) except ValueError: meta = None else: if index < 0: meta = None else: try: meta = self.metadata[index] except IndexError: meta = None else: meta = None if meta is None: return http.not_found() if isinstance(meta, Named): meta = meta.value return MetaData(metadata=meta), segments[1:]
def memberships(self, request, segments): """/addresses/<email>/memberships""" if len(segments) != 0: return http.bad_request() if self._address is None: return http.not_found() return AddressMemberships(self._address)
def moderate(self, request): try: validator = Validator(action=enum_validator(Action)) arguments = validator(request) except ValueError as error: return http.bad_request([], str(error)) requests = IListRequests(self._mlist) try: request_id = int(self._request_id) except ValueError: return http.bad_request() results = requests.get_request(request_id) if results is None: return http.not_found() key, data = results try: request_type = RequestType(data['_request_type']) except ValueError: return http.bad_request() if request_type is RequestType.subscription: handle_subscription(self._mlist, request_id, **arguments) elif request_type is RequestType.unsubscription: handle_unsubscription(self._mlist, request_id, **arguments) else: return http.bad_request() return no_content()
def patch_membership(self, request): """Patch the membership. This is how subscription changes are done. """ if self._member is None: return http.not_found() try: values = Validator( address=unicode, delivery_mode=enum_validator(DeliveryMode), _optional=('address', 'delivery_mode'))(request) except ValueError as error: return http.bad_request([], str(error)) if 'address' in values: email = values['address'] address = getUtility(IUserManager).get_address(email) if address is None: return http.bad_request([], b'Address not registered') try: self._member.address = address except (MembershipError, UnverifiedAddressError) as error: return http.bad_request([], str(error)) if 'delivery_mode' in values: self._member.preferences.delivery_mode = values['delivery_mode'] return no_content()
def delete(self, request): """Delete the member (i.e. unsubscribe).""" # Leaving a list is a bit different than deleting a moderator or # owner. Handle the former case first. For now too, we will not send # an admin or user notification. if self._member is None: return http.not_found() mlist = getUtility(IListManager).get_by_list_id(self._member.list_id) if self._member.role is MemberRole.member: try: delete_member(mlist, self._member.address.email, False, False) except NotAMemberError: return http.not_found() else: self._member.unsubscribe() return no_content()
def serve(self, request): if isinstance(self.metadata, (dict, list)): return http.not_found() else: return http.ok( [('Content-Type', 'text/plain')], [self.metadata], )
def find_template(self, request): # XXX We currently only support .txt and .html files. extension = EXTENSIONS.get(self.content_type) if extension is None: return http.not_found() template = self.template + extension fp = None try: try: path, fp = find(template, self.mlist, self.language) except TemplateNotFoundError: return http.not_found() else: return fp.read() finally: if fp is not None: fp.close()
def delete(self, request): """Delete the domain.""" try: getUtility(IDomainManager).remove(self._domain) except KeyError: # The domain does not exist. return http.not_found() return no_content()
def unverify(self, request, segments): """/addresses/<email>/verify""" if len(segments) != 0: return http.bad_request() if self._address is None: return http.not_found() child = _VerifyResource(self._address, 'unverify') return child, []
def status(self, request): session = models.Session.get_by_key_name(self.name) if session is None: return http.not_found([], '') return http.ok( [('Content-Type', 'application/json')], json.dumps({'created_at': str(session.created_at)}) )
def lists(self, request, segments): """/domains/<domain>/lists""" if len(segments) == 0: domain = getUtility(IDomainManager).get(self._domain) if domain is None: return http.not_found() return ListsForDomain(domain) else: return http.bad_request()
def details(self, request): try: request_id = int(self._request_id) except ValueError: return http.bad_request() resource = self._make_resource(request_id) if resource is None: return http.not_found() return http.ok([], etag(resource))
def preferences(self, request, segments): """/addresses/<email>/preferences""" if len(segments) != 0: return http.bad_request() if self._user is None: return http.not_found() child = Preferences( self._user.preferences, 'users/{0}'.format(self._user.user_id.int)) return child, []
def preferences(self, request, segments): """/members/<id>/preferences""" if len(segments) != 0: return http.bad_request() if self._member is None: return http.not_found() child = Preferences( self._member.preferences, 'members/{0}'.format(self._member.member_id.int)) return child, []
def details(self, request): try: request_id = int(self._request_id) except ValueError: return http.bad_request() resource = self._make_resource(request_id, MEMBERSHIP_CHANGE_REQUESTS) if resource is None: return http.not_found() # Remove unnecessary keys. del resource['key'] return http.ok([], etag(resource))
def delete_user(self, request): """Delete the named user, all her memberships, and addresses.""" if self._user is None: return http.not_found() for member in self._user.memberships.members: member.unsubscribe() user_manager = getUtility(IUserManager) for address in self._user.addresses: user_manager.delete_address(address) user_manager.delete_user(self._user) return no_content()
def child(self, request, segments): """ Find the appropriate image to return including cacheing and resizing """ # Build the full filename from the segments. filestore, key = util.decode_file_resource_path('/'.join(segments)) # get the requested filepath from the segments etag = str(request.if_none_match) f = self.get_file(request, filestore, key, etag) if f: return f return http.not_found()
def scrape(self, request): session = models.Session.get_by_key_name(self.name) if session is None: return http.not_found([], '') data = json.loads(request.body) content, matched = session.scrape(data['url'], data['match']) return http.ok( [('Content-Type', 'application/json')], json.dumps({'content': content, 'matched': matched}) )
def patch_update(self, request): """Patch the user's configuration (i.e. partial update).""" if self._user is None: return http.not_found() try: validator = PatchValidator(request, ATTRIBUTES) except UnknownPATCHRequestError as error: return http.bad_request( [], b'Unknown attribute: {0}'.format(error.attribute)) except ReadOnlyPATCHRequestError as error: return http.bad_request( [], b'Read-only attribute: {0}'.format(error.attribute)) validator.update(self._user, request) return no_content()
def moderate(self, request): try: validator = Validator(action=enum_validator(Action)) arguments = validator(request) except ValueError as error: return http.bad_request([], str(error)) requests = IListRequests(self._mlist) try: request_id = int(self._request_id) except ValueError: return http.bad_request() results = requests.get_request(request_id, RequestType.held_message) if results is None: return http.not_found() handle_message(self._mlist, request_id, **arguments) return no_content()
def put_update(self, request): """Put the user's configuration (i.e. full update).""" if self._user is None: return http.not_found() validator = Validator(**ATTRIBUTES) try: validator.update(self._user, request) except UnknownPATCHRequestError as error: return http.bad_request( [], b'Unknown attribute: {0}'.format(error.attribute)) except ReadOnlyPATCHRequestError as error: return http.bad_request( [], b'Read-only attribute: {0}'.format(error.attribute)) except ValueError as error: return http.bad_request([], str(error)) return no_content()
def details(self, request): requests = IListRequests(self._mlist) try: request_id = int(self._request_id) except ValueError: return http.bad_request() results = requests.get_request(request_id, RequestType.held_message) if results is None: return http.not_found() key, data = results msg = getUtility(IMessageStore).get_message_by_id(key) resource = dict( key=key, data=data, msg=msg.as_string(), id=request_id, ) return http.ok([], etag(resource))
def templates(self, request, segments): """/<api>/templates/<fqdn_listname>/<template>/[<language>] Use content negotiation to request language and suffix (content-type). """ if len(segments) == 3: fqdn_listname, template, language = segments elif len(segments) == 2: fqdn_listname, template = segments language = 'en' else: return http.bad_request() mlist = getUtility(IListManager).get(fqdn_listname) if mlist is None: return http.not_found() # XXX dig out content-type from request content_type = None return TemplateFinder( fqdn_listname, template, language, content_type)
def patch_put(self, request, is_optional): if self._parent is None: return http.not_found() kws = dict( acknowledge_posts=GetterSetter(as_boolean), delivery_mode=GetterSetter(enum_validator(DeliveryMode)), delivery_status=GetterSetter(enum_validator(DeliveryStatus)), preferred_language=GetterSetter(language_validator), receive_list_copy=GetterSetter(as_boolean), receive_own_postings=GetterSetter(as_boolean), ) if is_optional: # For a PUT, all attributes are optional. kws['_optional'] = kws.keys() try: Validator(**kws).update(self._parent, request) except ValueError as error: return http.bad_request([], str(error)) return no_content()
def login(self, request, segments): """Log the user in, sort of, by verifying a given password.""" if self._user is None: return http.not_found() # We do not want to encrypt the plaintext password given in the POST # data. That would hash the password, but we need to have the # plaintext in order to pass into passlib. validator = Validator(cleartext_password=GetterSetter(unicode)) try: values = validator(request) except ValueError as error: return http.bad_request([], str(error)) is_valid, new_hash = config.password_context.verify( values['cleartext_password'], self._user.password) if is_valid: if new_hash is not None: self._user.password = new_hash return no_content() return http.forbidden()
def patch_put(self, request, is_optional): if self._parent is None: return http.not_found() kws = dict( acknowledge_posts=as_boolean, delivery_mode=enum_validator(DeliveryMode), delivery_status=enum_validator(DeliveryStatus), preferred_language=language_validator, receive_list_copy=as_boolean, receive_own_postings=as_boolean, ) if is_optional: # For a PUT, all attributes are optional. kws['_optional'] = kws.keys() try: values = Validator(**kws)(request) except ValueError as error: return http.bad_request([], str(error)) for key, value in values.items(): setattr(self._parent, key, value) return no_content()
def serve(self, request): git_dir = request.environ['config']['git-dir'] tmp = os.tmpfile() tar_out = tarfile.open( name='/{test}.tar.bz2'.format(test=self.test), mode='w|bz2', fileobj=tmp, ) try: for (tarinfo, fileobj) in self._archive( git_dir=git_dir, rev='{rev}:tests/{test}/'.format(rev=self.rev, test=self.test), ): tar_out.addfile(tarinfo, fileobj=fileobj) except GitArchiveError: return http.not_found( [('Content-Type', 'text/plain')], 'Revision or test not found.\n', ) # this one is expected to work; don't catch exceptions for (tarinfo, fileobj) in self._archive( git_dir=git_dir, rev=self.rev, path='teuthology/', ): tar_out.addfile(tarinfo, fileobj=fileobj) tar_out.close() tmp.seek(0) res = http.Response( status='200 OK', headers=[('Content-Type', 'application/x-bzip')], body=tmp, ) return res
def show(self, request): """Return the resource representation in the requested content type""" if not self.method: # The method needs to be set at least return http.not_found([('Content-type', 'text/javascript')], '') # Inject the project specific project databases self.dbs = request.environ['dbs'] # Get the configurations for the given level of detail confs = get_configurations(request, self.level, self.resolution, self.partition, self.dbs, **self.kwargs) # Run the method containing the code to access the database data = run_method_using_mysqldb(self.method, self.dbs, confs, http.not_found) if data == http.not_found: # If the returned value is the marker http.not_found, we know # that something related to MySQL went wrong when the method # was called. The marker is used so that no internals of the # MySQL adapter need to be considered here. return http.not_found() if data is None: log.warning("Method appears to be unimplemented: %s" % self.method) return http.not_found([('Content-type', 'text/javascript')], '') accept_header = request.headers.get('Accept', 'text/javascript') body = None # Different results are returned depending on whether this is a table if 'table_description' in data and 'table_data' in data: #print "Extract table info and return info" # This chart is using the google visualization library table = gviz_api.DataTable(data['table_description']) try: table.AppendData(data['table_data']) except DataTableException: print self.method raise if accept_header == 'text/plain': body = table.ToJSonResponse() elif accept_header == 'text/html': body = table.ToHtml() elif accept_header == 'text/x-cfg': body = to_cfg(data) elif accept_header == 'text/csv': body = table.ToCsv() elif accept_header == 'text/tab-separated-values': body = table.ToCsv(separator="\t") elif accept_header == 'text/x-python-pickled-dict': body = pickle.dumps(data) else: try: body = table.ToJSon() except DataTableException: print self.method print data['table_description'] print data['table_data'] raise except: raise else: accept_header = request.headers.get('Accept', None) if accept_header == 'text/x-python-pickled-dict': body = pickle.dumps(data) else: body = json.dumps(data) headers = [('Content-type', accept_header), ('Content-Length', len(body))] return http.ok(headers, body)