def login(self, username=None, password=None): ''' Login/authenticate a user. :param user: Name of the user you're managing :param password: Password (plain text), if any of user ''' username = set_default(username, self.config.username, err_msg='username required') password = set_default(password, self.config.password, err_msg='password required') if username and not username == self.config.username: self.config.username = username if password and not password == self.config.password: self.config.password = password self._load_session() # new session result = self._post('login', username=username, password=password, api_url=False) if result: self.config['username'] = username self.config['password'] = password self.cookiejar_save() self.logged_in = True return result
def test_set_default(): ''' args: key, default, null_ok=False, err_msg=None ''' from metriqueu.utils import set_default k = None # key d = None # default n = True # null_ok e = None # err_msg assert set_default(k, d, n, e) is None k = [] assert set_default(k, d, n, e) == [] d = list assert set_default(k, d, n, e) == [] d = 'hello' assert set_default(k, d, n, e) != d assert set_default(k, d, n, e) != 42 n = False try: set_default(k, d, n, e) except RuntimeError: pass e = 'oops' try: set_default(k, d, n, e) except RuntimeError as e: assert e == 'oops'
def get_profile(self, _cube, _id, keys=None, raise_if_not=True, exists_only=False, mask=None, null_value=None): ''' Find and return a profile object from the designated cube. :param _cube: proxy to profile collection to query :param _id: object _id to query :param keys: profile keys to return :param raise_if_not: raise exception if any are invalid :param exists_only: only return bool whether profile exists :param mask: keys to exclude from results :param null_value: value to use to fill resulting list to keep the same list length, when used in a tuple unpacking assignments ''' if not _id: self._raise(400, "_id required") keys = set_default(keys, list, null_ok=True, err_msg="keys must be a list") mask = set_default(mask, list, null_ok=True, err_msg="keys must be a list") spec = {'_id': _id} cursor = _cube.find(spec) count = cursor.count() if not count: if raise_if_not: self._raise(400, 'resource does not exist: %s' % _id) elif exists_only: return False else: return {} elif exists_only: # return back only the count return True if count else False else: # return back the profile doc # which is the first and only item in the cursor profile = cursor.next() if keys: if profile: # extract out the nested items; we have # lists of singleton lists result = [profile.get(k, null_value) for k in keys if not k in mask] else: # keep the same list length, for tuple unpacking assignments # like a, b = ...get_profile(..., keys=['a', 'b']) result = [null_value for k in keys] if len(keys) == 1: # return it un-nested result = result[0] else: result = profile return result
def count(self, owner, cube, query, date=None): self.cube_exists(owner, cube) self.requires_owner_read(owner, cube) set_default(query, '') logger.info('pql query: %s' % query) try: spec = pql.find(query_add_date(query, date)) except Exception as e: self._raise(400, "Invalid Query (%s)" % str(e)) logger.debug('mongo query: %s' % spec) _cube = self.timeline(owner, cube) docs = _cube.find(spec=spec) return docs.count() if docs else 0
def update_passwd(self, new_password, old_password=None, username=None, save=False): ''' Update existing user profile properties :param String user: Name of the user you're managing :param String password: Password (plain text), if any of user ''' username = set_default(username, self.config.username) if not new_password: raise ValueError("new password required") cmd = os.path.join(username, 'passwd') response = self._post(cmd, username=username, old_password=old_password, new_password=new_password, api_url=False, allow_redirects=False, full_response=True) if response.status_code == 302 and username == self.config.username: self._load_session() self.config.password = new_password if save: self.config.save() if response.headers.get('location') == '/login': login(self, self.config.username, self.config.password) return True
def update_passwd(self, new_password, old_password=None, username=None, save=False): ''' Update existing user's password :param new_password: New user password to set :param old_password: Old user password to unset :param username: Name of the user to manipulate :param save: update local config file with new password ''' username = set_default(username, self.config.username) if not new_password: raise ValueError("new password required") cmd = os.path.join(username, 'passwd') response = self._post(cmd, username=username, old_password=old_password, new_password=new_password, api_url=False, allow_redirects=False, full_response=True) if response.status_code == 302 and username == self.config.username: self._load_session() self.config.password = new_password if save: self.config.save() if response.headers.get('location') == '/login': login(self, self.config.username, self.config.password) return response
def aboutme(self, username=None): ''' ''' username = set_default(username, self.config.username) cmd = os.path.join(username, 'aboutme') result = self._get(cmd, api_url=False) return result
def update_profile(self, username=None, backup=False, email=None): username = set_default(username, self.config.username) cmd = os.path.join(username, 'update_profile') result = self._post(cmd, backup=backup, email=email, api_url=False) return result
def get_profile(self, _cube, _id, keys=None, raise_if_not=False, exists_only=False, mask=None, null_value=None): ''' find and return the user's profile data exists will just check if the user exists or not, then return ''' if not _id: self._raise(400, "_id required") keys = set_default(keys, list, null_ok=True, err_msg="keys must be a list") mask = set_default(mask, list, null_ok=True, err_msg="keys must be a list") spec = {'_id': _id} cursor = _cube.find(spec) count = cursor.count() if not count: if raise_if_not: self._raise(400, 'resource does not exist: %s' % _id) elif exists_only: return False else: return {} elif exists_only: # return back only the count return True if count else False else: # return back the profile doc # which is the first and only item in the cursor profile = cursor.next() if keys: if profile: # extract out the nested items; we have # lists of singleton lists result = [profile.get(k, null_value) for k in keys if not k in mask] else: # keep the same list length, for tuple unpacking assignments # like a, b = ...get_profile(..., keys=['a', 'b']) result = [null_value for k in keys] if len(keys) == 1: # return it un-nested result = result[0] else: result = profile return result
def register(self, username=None, password=None, logon_as=True): ''' Register new user. :param user: Name of the user you're managing :param password: Password (plain text), if any of user ''' username = set_default(username, self.config.username) password = set_default(password, self.config.password) result = self._post('register', username=username, password=password, api_url=False) if result and logon_as: # start a fresh session (empty cookiesjar), with the # new registered users self.config['username'] = username self.config['password'] = password return login(self, username, password) else: return result
def aboutme(self, username=None): ''' Get user profile details. :param username: username to query profile data for ''' username = set_default(username, self.config.username) cmd = os.path.join(username, 'aboutme') result = self._get(cmd, api_url=False) return result
def update_properties(self, username=None, backup=True, cube_quota=None): ''' Update existing system level user properties :param username: Name of the user to manipulate :param backup: request previous state of property values :param int cube_quota: cube quota count to set ''' username = set_default(username, self.config.username) cmd = os.path.join(username, 'update_properties') result = self._post(cmd, backup=backup, cube_quota=cube_quota, api_url=False) return result
def aggregate(self, owner, cube, pipeline): ''' Wrapper around pymongo's aggregate command. Aggregation sytax parsing is handled by `pql`. :param cube: cube name :param owner: username of cube owner :param pipeline: pql aggretation pipeline ''' self.requires_read(owner, cube) pipeline = set_default(pipeline, None, null_ok=False) return self.timeline(owner, cube).aggregate(pipeline)
def sample_timeline(self, owner, cube, sample_size=None, query=None): if not (owner and cube): self._raise(400, "owner and cube required") if sample_size is None: sample_size = SAMPLE_SIZE query = set_default(query, '', null_ok=True) spec = parse_pql_query(query) _cube = self.timeline(owner, cube) docs = _cube.find(spec) n = docs.count() if n <= sample_size: docs = tuple(docs) else: to_sample = sorted(set(random.sample(xrange(n), sample_size))) docs = [docs[i] for i in to_sample] return docs
def remove(self, username=None, quiet=False): ''' Remove existing user. :param username: Name of the user you're managing :param quiet: ignore exceptions ''' username = set_default(username, self.config.username) cmd = os.path.join(username, 'remove') try: result = self._delete(cmd, username=username, api_url=False) except Exception: if quiet: result = None else: raise return result
def sample_cube(self, owner, cube, sample_size=None, query=None): ''' Take a psuedo-random sampling of objects from a given cube. :param cube: cube name :param owner: username of cube owner :param sample_size: number of objects to sample :param query: high-level query used to create population to sample ''' if not (owner and cube): self._raise(400, "owner and cube required") if sample_size is None: sample_size = SAMPLE_SIZE query = set_default(query, '', null_ok=True) spec = parse_pql_query(query) _cube = self.timeline(owner, cube) docs = _cube.find(spec) n = docs.count() if n <= sample_size: docs = tuple(docs) else: to_sample = sorted(set(random.sample(xrange(n), sample_size))) docs = [docs[i] for i in to_sample] return docs
def aggregate(self, owner, cube, pipeline): self.cube_exists(owner, cube) self.requires_owner_read(owner, cube) pipeline = set_default(pipeline, None, null_ok=False) return self.timeline(owner, cube).aggregate(pipeline)
def update_properties(self, username=None, backup=True, cube_quota=None): username = set_default(username, self.config.username) cmd = os.path.join(username, 'update_properties') result = self._post(cmd, backup=backup, cube_quota=cube_quota, api_url=False) return result