class EmailLogMapper(BaseNodeMapper): entity = EmailLog __PROPERTIES__ = { 'email': String(), 'to': String(), 'subject': String(), 'content': String(), 'success': Boolean(default=False), }
class PasswordResetMapper(BaseNodeMapper): from .user import User from datcode.common.model.graph.relationship import RequestedPasswordReset entity = PasswordReset __PROPERTIES__ = { 'code': String(default=uuid4), 'fulfilled': Boolean(default=False), 'date_fulfilled': DateTime(), 'reset_timeout': DateTime( default=lambda: datetime.utcnow().timestamp()\ + options.password_reset_timeout), } __RELATIONSHIPS__ = { 'User': RelatedEntity(relationship_entity=RequestedPasswordReset, direction='in'), } def get_by_code(self, code, current_time=None): current_time = current_time or datetime.utcnow().timestamp() pypher = self.builder() pypher.WHERE.CAND(pypher.entity.__code__ == code, pypher.entity.__reset_timeout__ >= current_time, pypher.entity.__fulfilled__ == False) pypher.RETURN(pypher.entity) return self.mapper.query(pypher=pypher).first()
class TagMapper(BaseNodeMapper): entity = Tag __PROPERTIES__ = { 'tag': String(ensure_unique=True), 'tag_normalized': String(), } def get_or_create_by_tags(self, *tags): if len(tags) == 0: raise Exception('Must pass in at least one tag') work = self.get_work() for t in tags: props = { 'tag': t, 'tag_normalized': normalize(t), } tag = self.create(properties=props) work = self.save(tag, work=work) return work.send() def get_tags_by_tags(self, *tags): if len(tags) == 0: raise Exception('Must pass in at least one tag') normalized_tags = map(normalize, tags) wheres = [] for nt in normalized_tags: wheres.append(__().__tag_normalized__ == nt) pypher = self.builder() pypher.WHERE.COR(*wheres) pypher.RETURN(pypher.entity) return self.mapper.query(pypher=pypher)
class UserMapper(EntityNodeMapper): entity = User __PROPERTIES__ = { 'username': String(), } __RELATIONSHIPS__ = { 'Follows': RelatedEntity(relationship_entity=Follows, ensure_unique=True), 'Followers': RelatedEntity(relationship_entity=Follows, ensure_unique=True, direction='in'), 'Tweets': RelatedEntity(relationship_entity=Tweeted, ensure_unique=True), }
class TweetMapper(EntityNodeMapper): entity = Tweet __PROPERTIES__ = { 'created': DateTime(default=datetime.now), 'text': String(), }
class ResourceMapper(BaseNodeMapper, HasOwnership): entity = Resource __PROPERTIES__ = { 'title': String(), 'description': String(), 'uri': String(), } __RELATIONSHIPS__ = { 'Tags': RelatedEntity(relationship_entity=HasTag, ensure_unique=False) } def save_resource(self, resource, *tags, work=None): work = work or self.mapper.get_work() work = self.save(resource, work=work) work = self(resource)['Tags'].replace(tags, work=work) work.send() def get_by_uri(self, uri): pypher = self.builder() pypher.WHERE.CAND(pypher.entity.__uri__ == uri) pypher.RETURN(pypher.entity) resource = self.mapper.query(pypher=pypher) return resource.first() def get_by_search_string(self, search_string, ensure_privacy=True, limit=options.pagination, skip=0): """based on a search string of: pyhon #code @mark build a query with the foundation of: MATCH (tag_resource:`Resource`)-[:`HasTag`]->(tag:`Tag`) WHERE tag.tag_normalized = 'code' WITH tag_resource MATCH (user_resource:`Resource`)<-[:`AddedResource`]-(user:`User`) WHERE id(user_resource) = id(tag_resource) WITH user_resource, user MATCH (resource:`Resource`)-[:`HasTag`]->(tag:`Tag`) id(resource) = id(user_resource) RETURN resource, user, collect(tag) """ from datcode.common.model.graph.node import User search = parse_search_string(search_string) user_mapper = self.get_mapper(User) user_mapper.ensure_privacy = ensure_privacy p = Pypher() p.node('resource', labels='Resource') p.rel_in(labels='AddedResource').node('user', labels='User') p2 = Pypher() p2.node('resource').rel_out(labels='HasTag').node('tag', labels='Tag') p2 = Pypher() p2.node('resource').rel_out(labels='HasTag').node('tag', labels='Tag') p3 = Pypher() p3.node('resource').rel_out(labels='HasTag').node('tags', labels='Tag') query = Pypher() query.MATCH(p, p2, p3) wheres = [] search_ors = [] user_ors = [] tag_ors = [] # filter the resource title and descripiton by search string powersets for contains in search['search']['contains']: term = "(?i).*{}.*".format(contains) d = Pypher() t = Pypher() d.resource.__description__.re(term) t.resource.__title__.re(term) search_ors.append(d) search_ors.append(t) if search_ors: ors = Pypher() ors.COR(*search_ors) wheres.append(ors) # filter by users for user in search['users']: u = Pypher() u.user.__username__ == user user_ors.append(u) if user_ors: ors = Pypher() ors.COR(*user_ors) wheres.append(ors) # filter by tags for tag in search['tags']: u = Pypher() u.tag.__tag_normalized__ == normalize(tag) tag_ors.append(u) if tag_ors: ors = Pypher() ors.COR(*tag_ors) wheres.append(ors) if wheres: query.WHERE.CAND(*wheres) # paginate and get a total count total = query.clone() total.RETURN('COUNT(DISTINCT(resource)) AS total') total_res = self.mapper.query(pypher=total) try: total_results = total_res.first()['result'] except: total_results = 0 query.RETURN('DISTINCT(resource)', 'user') query.ORDERBY('resource.date_created').DESC query.SKIP(skip).LIMIT(limit) results = self.mapper.query(pypher=query) result_data = [] all_tags = [] all_tag_ids = [] for res in results: tags = self(res['resource'])['Tags']() username = res['user']['username'] if ensure_privacy: username = '******' result_data.append({ 'resource': self.data(res['resource']), 'user': { 'username': username, }, 'tags': self.data(tags), }) for tag in tags: if tag.id not in all_tag_ids: all_tags.append(tag.data) all_tag_ids.append(tag.id) return { 'total': total_results, 'results': result_data, 'all_tags': all_tags, }
class LoginLogMapper(BaseNodeMapper): entity = LoginLog __PROPERTIES__ = { 'email_address': String(), 'success': Boolean(default=False), }
class UniqueMultiplePropertiesNodeMapper(EntityMapper): entity = UniqueMultiplePropertiesNode __PROPERTIES__ = { 'name': String(ensure_unique=True), 'location': String(ensure_unique=True), }
class UserMapper(BaseNodeMapper, HasOwnership): from datcode.common.model.graph.relationship import (AddedResource, RequestedPasswordReset ) # Flag for user models that says to mask the username ensure_privacy = True entity = User __PROPERTIES__ = { 'username': String(), 'password': String(), 'bio': String(), 'slack_id': String(), 'email_address': String(), 'verified': Boolean(default=False), 'private': Boolean(default=True), 'first_name': String(), 'last_name': String(), 'middle_name': String(), 'access_level': Integer(default=Roles.USER.value), 'registration_step': Integer(), } __RELATIONSHIPS__ = { 'PasswordResetRequest': RelatedEntity(relationship_entity=RequestedPasswordReset), 'Resources': RelatedEntity(relationship_entity=AddedResource, ensure_unique=True), } def data(self, entity): if isinstance(entity, Collection): return [self.data(e) for e in entity] data = super().data(entity) if 'username' in data and (self.ensure_privacy or entity['private']): data['username'] = '******' if 'password' in data: del data['password'] return data def update_password(self, user, password, password_check): if password != password_check: raise Exception('Determine correct exception') user['password'] = encrypt_password(password) self.mapper.save(user).send() return user def get_by_slack_id(self, slack_id): pypher = self.builder() pypher.WHERE.CAND(pypher.entity.__slack_id__ == slack_id) pypher.RETURN(pypher.entity) user = self.mapper.query(pypher=pypher) return user.first() def get_by_email(self, email_address): pypher = self.builder() pypher.WHERE.CAND(pypher.entity.__email_address__ == email_address) pypher.RETURN(pypher.entity) user = self.mapper.query(pypher=pypher) return user.first() def get_by_email_password(self, email_address, password): password = encrypt_password(password) pypher = self.builder() pypher.WHERE.CAND(pypher.entity.__email_address__ == email_address, pypher.entity.__password__ == password) pypher.RETURN(pypher.entity) user = self.mapper.query(pypher=pypher) return user.first() def auth_user(self, email_address, password): login = LoginLog(properties={'email_address': email_address}) self.mapper.save(login).send() try: user = self.get_by_email_password(email_address, password) login['success'] = True self.mapper.save(login).send() return user except: return None def on_after_create(self, entity, response=None, **kwargs): # send out a registration email to the user email = entity['email_address'] params = {} if email: self.email_html(to=email, key='new_user', **params) def request_password_change(self, user): from datcode.common.model.graph.node import PasswordReset code = self.mapper.create(entity=PasswordReset) _, work = self.mapper(user)['PasswordResetRequest'].add(code) _, work = self.add_ownership(user, code, work=work, submit=False) work.send() return code def on_password_property_changed(self, entity, field, value_from, value_to): """ Send the user an email if their password has changed """ email = entity['email_address'] params = {} self.email_html(to=email, key='password_changed', **params) def on_relationship_passwordresetrequest_added(self, entity, response, relationship_entity, relationship_end, **kwargs): """ This will send out an email once the password reset change has been added for a given user """ email = entity['email_address'] params = { 'uri': 'some.url.com', } self.email_html(to=email, key='password_reset_request', **params)
class MyNodexx(Node): __PROPERTIES__ = { 'name': String(), 'age': Integer() }
class MyNodexy(Node): __PROPERTIES__ = { prop_name: String() }
class MyNodex(Node): __PROPERTIES__ = { 'name': String() }
class SingleUpdateMapper(EntityMapper): entity = SingleUpdate __PROPERTIES__ = { 'name': String(), }
class MyNodeXXXMapper(EntityMapper): entity = MyNodeXXX __ALLOW_UNDEFINED__ = True __PROPERTIES__ = { 'name': String(), }