class Media(StructuredNode): media_id = IntegerProperty(unique_index=True) caption = StringProperty() taken_at = DateTimeProperty() comments_disabled = BooleanProperty() display_url = StringProperty() shortcode = StringProperty() location = RelationshipFrom('.locations.Location', 'TAGGED_LOCATION') accessibility_caption = StringProperty() height = IntegerProperty() width = IntegerProperty() liked_by = RelationshipFrom('.users.User', "LIKES") comments = RelationshipFrom('.interactions.Comment', 'ON') hashtags = RelationshipTo('.tags.Hashtag', "MENTIONED") tagged_users = RelationshipTo('.users.User', "TAGGED_USER", model=TaggedUserRel) edge_liked_by_count = IntegerProperty() edge_comments_count = IntegerProperty() has_ranked_comments = BooleanProperty() is_ad = BooleanProperty() caption_is_edited = BooleanProperty() owner = RelationshipFrom('.users.User', "POSTED", model=PostRel, cardinality=One) sponsors = RelationshipTo('.users.User', "SPONSORED_BY")
class Login(StructuredNode): date = DateTimeProperty(required=True) username = StringProperty() IP = StringProperty() location = StringProperty() user = RelationshipFrom("User", "HAS_LOGIN", cardinality=ZeroOrOne) failed = BooleanProperty(default=False) flushed = BooleanProperty(default=False)
class SBVersioned(TaggableContent): edit = lambda self: self.__class__.__name__ original = BooleanProperty(default=True) draft = BooleanProperty(default=False) # relationships edits = RelationshipTo(SBContent.get_model_name(), 'EDIT') edit_to = RelationshipTo(SBContent.get_model_name(), 'EDIT_TO')
class Person(StructuredNode): name = StringProperty(unique_index=True) friend = Relationship("Person", "KNOWS") politician = BooleanProperty() cricketer = BooleanProperty() actor = BooleanProperty() entertainment = BooleanProperty() team = BooleanProperty()
class Playlist(SpotifyNode): ''' Represents a Playlist on Spotify ''' owner = RelationshipTo('model.graph.spotify.user.User', 'OWNED BY') tracks = RelationshipFrom('model.graph.spotify.track.Track', 'FEATURED IN') spotify_id = StringProperty(unique_index=True) name = StringProperty() collaborative = BooleanProperty() description = StringProperty() external_urls = JSONProperty() href = StringProperty() images = JSONProperty() primary_color = StringProperty() public = BooleanProperty() snapshot_id = StringProperty() type = StringProperty() uri = StringProperty() @staticmethod def post_clean(obj, to_connect: dict): from model.graph.spotify.user import User owner = to_connect['owner'] owner = User.inst(**owner) obj.owner.connect(owner) return obj @classmethod def clean(cls, **kwargs): if 'tracks' in kwargs: del kwargs['tracks'] if 'id' in kwargs: kwargs['spotify_id'] = kwargs.pop('id') to_connect = {'owner': kwargs.pop('owner')} obj = cls(**kwargs) return obj, to_connect @classmethod def get_tracks(cls, spotify_id): s = time() from model.graph.spotify.track import SmallTrack db.set_connection(connection_url()) query = ''' MATCH (p: Playlist {spotify_id: "%s"}) <-[r1: `FEATURED IN`]- (t: Track) RETURN t.uri, t.zVector, t.spotify_id, t.name ''' % spotify_id results, meta = db.cypher_query(query) print('Results fetched', time() - s) keys = ['uri', 'zVector', 'spotify_id', 'name'] kwargs = [{keys[i]: val for i, val in enumerate(result)} for result in results] return [SmallTrack(**result) for result in kwargs]
class Redditor(StructuredNode): rid = StringProperty(unique_index=True) name = StringProperty(index=True) comment_karma = IntegerProperty() link_karma = IntegerProperty() is_employee = BooleanProperty() is_mod = BooleanProperty() is_gold = BooleanProperty() created_utc = DateTimeProperty(index=True)
class Person(StructuredNode): name = StringProperty(unique_index=True) friends = Relationship("Person", "KNOWS") politician = BooleanProperty() cricketer = BooleanProperty() bollywood = BooleanProperty() alive = BooleanProperty() pageLink = StringProperty() imgLink = StringProperty() indian = BooleanProperty()
class ConductedSurveyQuestion(SemiStructuredNode): nodeId = UniqueIdProperty() sentimentSet = BooleanProperty(default=False) sentimentCalculated = BooleanProperty(default=False) addedOn = DateTimeProperty(default_now=True) def pre_save(self): if self.sentimentSet is False: SentimentSetter.setSentimentVariables(self)
class Restaurant(StructuredNode): rid = UniqueIdProperty() name = StringProperty() avg_cost = FloatProperty() rating = FloatProperty() ratings_count = IntegerProperty() url = StringProperty() has_online_delivery = BooleanProperty() has_table_booking = BooleanProperty() SERVES = RelationshipTo(Cuisine, 'SERVES') IN = RelationshipTo(Location, 'IN', model=Locrel) WITH = RelationshipTo(Price, 'WITH_COST')
class Notification(SBObject): seen = BooleanProperty(default=False) time_sent = DateTimeProperty(default=get_current_time) time_seen = DateTimeProperty(default=None) about = StringProperty() sent = BooleanProperty(default=False) url = StringProperty() action_name = StringProperty() # public_notification used to determine if real names should be used in # vote notifications public_notification = BooleanProperty(default=False) # relationships notification_from = RelationshipTo('plebs.neo_models.Pleb', 'NOTIFICATION_FROM') notification_to = RelationshipTo('plebs.neo_models.Pleb', 'NOTIFICATION_TO') @classmethod def unseen(cls, username): """ Returns the amount of unseen notifications for a given user :param username: :return: """ query = 'MATCH (a:Pleb {username: "******"})<-[:NOTIFICATION_TO]-' \ '(n:Notification) WHERE n.seen=False ' \ 'RETURN count(n)' % (username) res, col = db.cypher_query(query) return res[0][0] @classmethod def clear_unseen(cls, username): """ Sets all the notifications for the given user to True so that there are no more unread notifications. Doesn't return anything because if the query fails a Cypher Exception is thrown and a 500 error will propagate out. :param username: :return: """ value = get_current_time().astimezone(pytz.utc) epoch_date = datetime(1970, 1, 1, tzinfo=pytz.utc) time_seen = float((value - epoch_date).total_seconds()) query = 'MATCH (a:Pleb {username: "******"})<-[:NOTIFICATION_TO]-' \ '(n:Notification) WHERE n.seen=False' \ ' SET n.seen = True, ' \ 'n.time_seen = %s' % (username, time_seen) db.cypher_query(query)
class Message(StructuredRel): text = StringProperty() spam = BooleanProperty() soup = BooleanProperty() death = BooleanProperty() raven = BooleanProperty() bed = BooleanProperty() food = BooleanProperty() alch = BooleanProperty() rabbit = BooleanProperty() sql = BooleanProperty()
class Userprofile(StructuredNode): is_client = BooleanProperty(default=False) username = StringProperty(index=True) knows = RelationshipTo('Userprofile', 'KNOWS') known = RelationshipFrom('Userprofile', 'KNOWS') def append_message(self, message): """ Add message to the list of user messages. """ if self.__node__.get('messages', None): self.__node__['messages'].append(message) else: self.__node__['messages'] = [message] def pull_messages(self): """ Get and delete messages. """ messages = self.__node__['messages'] del self.__node__['messages'] _create_locks = {} _set_client_locks = {} def set_is_client(self, is_client): if not is_client: self.is_client = False self.save() return batch = WriteBatch(neomodel.core.connection()) for rel in self.known.all(): batch.delete(rel) batch.set_node_property(self.__node__, 'is_client', True) self.get_set_client_lock().acquire() try: batch.submit() finally: self.get_set_client_lock().release() def get_set_client_lock(self): return self._set_client_locks.setdefault(self, Lock()) @classmethod def get_or_create(cls, **keyvalue): """ To be modified and moved to neomodel.Index. """ category_node = cls.category().__node__ node = cls.index.__index__.get_or_create('username', keyvalue['username'], keyvalue) if not category_node.is_related_to(node, Direction.OUTGOING, cls.relationship_type()): category_node.create_relationship_to(node, cls.relationship_type(), {'__instance__': True}) structured = cls() structured.__node__ = node structured.refresh() return structured
class TaggableContent(SBContent): added_to_search_index = BooleanProperty(default=False) # relationships tags = RelationshipTo('sb_tags.neo_models.Tag', 'TAGGED_AS') # methods def add_auto_tags(self, tag_list): from sb_tags.neo_models import AutoTag auto_tag_list = [] for tag in tag_list: name = slugify(tag['tags']['text']) query = 'MATCH (autotag:AutoTag {name: "%s"}) RETURN autotag' % ( name) res, _ = db.cypher_query(query) if res.one is None: AutoTag(name=name).save() res, _ = db.cypher_query( 'MATCH (autotag:AutoTag {name: "%s"}),' ' (content:TaggableContent {object_uuid: "%s"}) ' 'CREATE UNIQUE (autotag)<-[rel:TAGGED_AS]-(content) ' 'SET rel.relevance=%f ' 'RETURN autotag' % (name, self.object_uuid, tag['tags']['relevance'])) auto_tag_list.append(AutoTag.inflate(res.one)) return auto_tag_list
class ConfigurableNodeSettings(Settings): display_name = StringProperty(required=False) avatar = StringProperty(required=False) proxy_tag = StringProperty(required=False) autoproxy = BooleanProperty(default=False) entity = RelationshipFrom('app.dal.nodes._base.ConfigurableNode', 'SETTINGS', One) scope = RelationshipTo('app.dal.nodes.server.Server', 'SCOPE')
class Searchable(SBObject): search_id = StringProperty() populated_es_index = BooleanProperty(default=False) view_count = IntegerProperty(default=0) summary = StringProperty() # relationships viewed_by = RelationshipTo('plebs.neo_models.Pleb', "VIEWED_BY", model=Impression) def get_view_count(self): return self.view_count def increment_view_count(self): try: # This is to ensure the number doesn't cross into a BigInteger # which our current setup does not support. If views get over a # billion we probably can just mark it as "a lot" as more than that # is probably only useful for internal analysis or sorting/trending # which are probably better analyzed on a week/day basis than # overall anyways. if self.view_count >= 4611686018427387900: return 4611686018427387900 self.view_count += 1 self.save() return self.view_count except IndexError: return 0
class User(StructuredNode): username = StringProperty() active = BooleanProperty(default=False) messages = RelationshipTo('User', 'MESSAGE', model=Message) def __str__(self) -> str: return 'user_with_id' + str(self.id)
class Transaction_Node(StructuredNode): tid = UniqueIdProperty() price = FloatProperty(required=True) buy = BooleanProperty(required=True) quantity = IntegerProperty(required=True) date = DateProperty(required=True) stock = RelationshipTo(Stock_Node, "TRANSACTIONTOSTOCK")
class COSObject(StructuredNode): # type: ignore """A `neomodel` model representing an object inside of a cloud object storage bucket used in tracking data provenance.""" name = StringProperty(unique_index=True, required=True) imported = BooleanProperty() bucket = RelationshipTo('COSBucket', 'in_bucket')
class Review(StructuredNode): """ Represents a user opinion downloaded from a social network about a restaurant Source: http://schema.org/Review """ reference = StringProperty(unique_index=True, default=uuid4) identifier = StringProperty(unique_index=True, default=uuid4) item_reviewed = RelationshipFrom('SocialNetworkRestaurant', 'REVIEW', cardinality=One) review_body = StringProperty() appearances = RelationshipFrom('KeyPoint', 'REVIEW_POINT', cardinality=ZeroOrMore) is_spam = BooleanProperty() sentiment = FloatProperty() def add_key_point(self, key_point): self.appearances.connect(key_point) def is_from_project(self, project_id): return self.item_reviewed.single().\ from_project.single().\ identifier == project_id
class Movie(StructuredNode): oid = StringProperty(unique_index=True) imdb_id = StringProperty() original_title = StringProperty() title = StringProperty() original_language = StringProperty() overview = StringProperty() popularity = FloatProperty() status = StringProperty() tagline = StringProperty() adult = BooleanProperty() poster_path = StringProperty() video = StringProperty() release_date = DateProperty() revenue = IntegerProperty() budget = IntegerProperty() runtime = FloatProperty() homepage = StringProperty() vote_average = FloatProperty() vote_count = IntegerProperty() genres = RelationshipTo(".genre.Genre", "IS_KIND") spoken_languages = RelationshipFrom(".language.Language", "SPOKEN_IN") keywords = RelationshipTo("Keyword", "CONTAINS") produced_by = RelationshipTo(".production_company.ProductionCompany", "PRODUCED_BY") produced_in = RelationshipTo(".production_country.ProductionCountry", "PRODUCED_IN") is_part_of = RelationshipTo(".collection.Collection", "IS_PART_OF") acted_in = RelationshipFrom("Person", "ACTS_IN", model=ActsIn) crew_in = RelationshipFrom("Person", "CREW_IN", model=CrewIn)
class InterpersonalRelationship(StructuredRel): """ Relationship base for handling relations between two or more people such as friends and followers/following. """ since = DateTimeProperty(default=get_current_time) active = BooleanProperty(default=True)
class ContainerKojiBuild(KojiBuild): """A Neo4j definition of a build that represents a container build in Koji.""" original_nvr = StringProperty() triggered_by_freshmaker_event = RelationshipFrom( '.freshmaker.FreshmakerEvent', 'TRIGGERED', cardinality=ZeroOrOne) operator = BooleanProperty(default=False)
class Account(StructuredNode, UserMixin): ''' Contains actual account data. Note that personal data is stored in the "Person" model instead. ''' username = StringProperty(unique_index=True, required=True) password = StringProperty() email = StringProperty() email_belongs_to = StringProperty() owner = RelationshipFrom('Person', 'HAS_ACCOUNT', cardinality=One) is_active = BooleanProperty(default=False) signin_mode = StringProperty(choices=SIGNIN_MODE_CHOICES, default='none') creation_date = DateTimeProperty(default=lambda: datetime.now()) last_login = DateTimeProperty(default=lambda: datetime.now()) def get_id(self): return self.username def set_password(self, plaintext): self.password = generate_password_hash(plaintext) def check_password(self, plaintext): if check_password_hash(self.password, plaintext): return True return False
class DigitalEntity(StructuredNode): """ iRODS entity (file or collection) """ id = StringProperty(required=True, unique_index=True) # UUID location = StringProperty(index=True) # filename = StringProperty(index=True) # path = StringProperty() # collection is a DigitalEntity.. collection = BooleanProperty(default=False) parent = RelationshipFrom('DigitalEntity', 'INSIDE') child = RelationshipTo('DigitalEntity', 'INSIDE') aggregation = RelationshipTo('Aggregation', 'BELONGS_TO') owned = RelationshipTo(IrodsUser, 'IS_OWNED_BY') located = RelationshipTo(Zone, 'IS_LOCATED_IN') stored = RelationshipTo(Resource, 'STORED_IN') replica = RelationshipTo('DigitalEntity', 'IS_REPLICA_OF', model=Replication) master = RelationshipFrom('DigitalEntity', 'IS_MASTER_OF', model=Replication) described = RelationshipFrom('MetaData', 'DESCRIBED_BY') identity = RelationshipFrom('PID', 'UNIQUELY_IDENTIFIED_BY') _fields_to_show = ['location'] _relationships_to_follow = ['belonging', 'located', 'stored']
class Node(StructuredNode): handle_id = IntegerProperty(blank=False) is_real = BooleanProperty(default = False) tree_size = IntegerProperty(default = 1) content = StringProperty(default='') content_size = IntegerProperty() max_id = IntegerProperty(default=0) min_id = IntegerProperty(default=0) left = RelationshipTo('Node', 'left') right = RelationshipTo('Node', 'right') father = RelationshipTo('Node', 'father') #depth = IntegerProperty(blank=False, default=1) def update(self): lsize = 0 if len(self.left.all()) == 0 else self.left.all()[0].tree_size rsize = 0 if len(self.right.all()) == 0 else self.right.all()[0].tree_size self.tree_size = lsize + rsize + 1 nc = "" for i in range(0, self.content_size): lc = 0 if len(self.left.all()) == 0 else int(self.left.all()[0].content[i]) rc = 0 if len(self.right.all()) == 0 else int(self.right.all()[0].content[i]) nc += str(lc | rc) if self.tree_size > 1: self.min_id = self.left.all()[0].min_id if not len(self.left.all()) == 0 else self.right.all()[0].min_id self.max_id = self.right.all()[0].max_id if not len(self.right.all()) == 0 else self.left.all()[0].max_id self.id = self.right.all()[0].min_id if not len(self.right.all()) == 0 else self.left.all()[0].max_id + 1
class GT_RCVotes(StructuredNode): category_one = StringProperty(default="") category_label = StringProperty(default="") chamber = StringProperty(default="") chamber_label = StringProperty(default="") congress = IntegerProperty() created = StringProperty(default="") vote_id = IntegerProperty(unique_index=True) link = StringProperty(default="") missing_data = BooleanProperty() number = IntegerProperty() question = StringProperty(default="") question_details = StringProperty(default="") related_amendment = IntegerProperty() related_bill = JSONProperty() required = StringProperty() result = StringProperty(default="") session = StringProperty(default="") source = StringProperty(default="") source_label = StringProperty(default="") total_minus = IntegerProperty() total_other = IntegerProperty() total_plus = IntegerProperty() vote_type = StringProperty(default="") # relationships option = RelationshipTo('GTVoteOption', 'HAS_A')
class Track(StructuredNode): uid = UniqueIdProperty() url = StringProperty(unique_index=True, required=True) title = StringProperty() media_not_available = BooleanProperty(default=False) discogs_url = StringProperty() tags = RelationshipTo('Tag', 'TAGGED', model=TagRel)
class ArticleRel(StructuredRel): created_at = DateTimeProperty( default=lambda: datetime.now() ) tf_idf = FloatProperty() hidden = BooleanProperty(default=False) label = StringProperty()
class ConductedSurvey(SemiStructuredNode): nodeId = UniqueIdProperty() addedOn = DateTimeProperty(default_now=True) updatedOn = DateTimeProperty() closedOn = DateTimeProperty(default_now=True) status = StringProperty(default="active", choices={ "closed": "closed", "active": "active", "abandoned": "abandoned" }) sentimentSet = BooleanProperty(default=False) def pre_save(self): if self.updatedOn is None: self.updatedOn = self.addedOn else: self.updatedOn = datetime.utcnow().replace(tzinfo=pytz.utc) if self.sentimentSet is False: SentimentSetter.setSentimentVariables(self) def set_closedOn(self, dt: Optional[datetime] = None) -> None: if dt is None: self.closedOn = datetime.utcnow().replace(tzinfo=pytz.utc) else: self.closedOn = dt.replace(tzinfo=pytz.utc)
class App(StructuredNode, models.Node): """ app model 1. (App)-[USE]->(DevLanguage) 2. (App)-[USE]->(ServiceType) 3. (App)-[USE]->(ServletsEngine) 4. (App)-[USE]->(ConfigType) 5. (App)-[Belong_TO]->(Environment) 6. (App)-[Depend_ON]->(Host) 7. (App)-[USE]->(DatabaseConnect) 8. (App)-[USE]->(FileServer) 9. (App)-[Depend_ON]->(K8SNamespace) 10. (person)-[Manager_TO]->(app) """ app_id = UniqueIdProperty() app_name = StringProperty() code_git_path = StringProperty() CD_path = StringProperty() port = IntegerProperty() smoke_test = BooleanProperty() code_review = BooleanProperty() config_type = StringProperty() config_namespace = StringProperty() version = FloatProperty() run_status = StringProperty() # app使用开发语言,服务类型, web服务框架, 配置类型 devlanguage = RelationshipTo(DevLanguage, "USE", model=DevLanguageInfo) servicetype = RelationshipTo(ServiceType, "USE", model=ServiceTypeInfo) servletsengine = RelationshipTo(ServletsEngine, "USE", model=ServletsEngineInfo) configtype = RelationshipTo(ConfigType, "USE", model=ConfigTypeInfo) environment = RelationshipTo(Environment, "Belong_TO", model=EnvironmentInfo) host = RelationshipTo(Host, 'Depend_ON', model=HostInfo) databaseconnect = RelationshipTo(DatabaseConnect, "USE", model=DatabaseConnectInfo) fileServer = RelationshipTo(FileServer, "USE", model=FileServerInfo) k8snamespace = RelationshipTo(K8SNamespace, "Depend_ON", model=K8SNamespaceInfo) person = RelationshipFrom('Person', "Manage_TO")