Source code for situation

# -*- coding: utf-8 -*-
# situation (c) Ian Dennis Miller

import string
import random
from flask_diamond import db
from flask_diamond.mixins.crud import CRUDMixin
from flask_diamond.mixins.marshmallow import MarshmallowMixin
from .schemas import ResourceSchema, ExcerptSchema, PersonSchema, AcquaintanceSchema, \
    PlaceSchema, ItemSchema, GroupSchema, EventSchema
from .secondary import AcquaintanceExcerpt


# https://stackoverflow.com/questions/2257441/python-random-string-generation-with-upper-case-letters-and-digits
[docs]def id_generator(size=8, chars=None): """ Create a random sequence of letters and numbers. :param int size: the desired length of the sequence :param str chars: the eligible character set to draw from when picking random characters :returns: a string with the random sequence """ if chars is None: chars = string.ascii_uppercase + string.ascii_lowercase + string.digits return ''.join(random.choice(chars) for x in range(size))
[docs]class Resource(db.Model, CRUDMixin, MarshmallowMixin): """ A Resource is an authoritative information source from which evidence is drawn. Usually, a Resource is an artifact like a newspaper article, a report, or another document. These documents usually have an associated URL. There may be many Resource from a single publisher or organization. Currently, the publisher is not a special component of the situation ontology. If it is necessary to include a publisher in a model, represent it as a Group. :param int id: the database object identifier :param str unique: alpha-numeric code for shorthand identifier :param str name: what the resource is called (usually the title or headline) :param str url: the canonical URL for the resource :param str publisher: the name of the institution whose reputation backs this resource :param str author: the name of the author(s) :param str description: a short summary of this resource """ __schema__ = ResourceSchema id = db.Column(db.Integer, primary_key=True) unique = db.Column(db.String(255), unique=True, default=id_generator) name = db.Column(db.String(4096), nullable=False) url = db.Column(db.String(4096)) publisher = db.Column(db.String(4096)) author = db.Column(db.String(4096)) description = db.Column(db.String(8**7)) def __str__(self): return(self.url)
[docs]class Excerpt(db.Model, CRUDMixin, MarshmallowMixin): """ An Excerpt is a direct quote that comes from any Resource. Any time an Excerpt is used, that Excerpt must be directly quotable from a Resource. :param int id: the database object identifier :param str unique: alpha-numeric code for shorthand identifier :param str content: the actual quoted material of the excerpt :param Resource resource: the Resource from which this excerpt comes :param str xpath: the xpath leading to this excerpt within the Resource """ __schema__ = ExcerptSchema id = db.Column(db.Integer, primary_key=True) unique = db.Column(db.String(255), unique=True, default=id_generator) content = db.Column(db.String(8**7)) resource = db.relationship('Resource', backref='excerpts') resource_id = db.Column(db.Integer, db.ForeignKey('resource.id'), nullable=False) xpath = db.Column(db.String(4096)) def __str__(self): return(self.content)
[docs]class Person(db.Model, CRUDMixin, MarshmallowMixin): """ A Person is an actor in a Situation. :param int id: the database object identifier :param str unique: alpha-numeric code for shorthand identifier :param str name: what the person is called :param str alias: that *other* thing the person is called :param str slug: a URL-friendly identifier :param [Excerpt] excerpts: excerpts related to this Person :param [Event] events: events related to this Person :param [Place] places: places related to this Person :param [Item] possessions: items related to this Person :param [Place] properties: places owned by this Person :param [Group] groups: groups this Person is a member of :param [Acquaintance] acquaintances: people this Person knows """ __schema__ = PersonSchema id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(255), nullable=False) alias = db.Column(db.String(255)) unique = db.Column(db.String(255), unique=True, default=id_generator) excerpts = db.relationship('Excerpt', secondary="persons_excerpts", lazy='dynamic')
[docs] def isa(self, isa_type, of): """ A Person is a type of Acquaintance with the Acquainted. alice = Person.find(name="Alice") bob = Person.find(name="Bob") bob.isa("friend", of=alice) """ e = Acquaintance(person=self, isa=isa_type, acquainted=of) result = e.save() return result
def __str__(self): return(self.name)
[docs]class Acquaintance(db.Model, CRUDMixin, MarshmallowMixin): """ An Acquaintance is a relationship between Persons. This represents a directed edge, so a separate Acquaintance must be created to establish reciprocity. :param str isa: a description of the type of relationship :param Person person: the "source" of the acquaintance :param Person acquainted: the "target" of the acquaintance :param [Excerpt] excerpts: excerpts related to this Acquaintance """ __schema__ = AcquaintanceSchema isa = db.Column(db.String(64)) excerpts = db.relationship('Excerpt', secondary="acquaintance_excerpts", lazy='dynamic') person_id = db.Column(db.Integer(), db.ForeignKey('person.id'), primary_key=True) person = db.relationship(Person, primaryjoin=person_id == Person.id, backref='acquaintances') acquainted_id = db.Column(db.Integer(), db.ForeignKey('person.id'), primary_key=True) acquainted = db.relationship(Person, primaryjoin=acquainted_id == Person.id) def add_excerpt(self, excerpt): annotation = AcquaintanceExcerpt.create( excerpt_id=excerpt.id, person_id=self.person_id, acquainted_id=self.acquainted_id ) return annotation def __str__(self): return("%s isa %s of %s)" % (self.person, self.isa, self.acquainted))
[docs]class Place(db.Model, CRUDMixin, MarshmallowMixin): """ A Place is a location. :param int id: the database object identifier :param str unique: alpha-numeric code for shorthand identifier :param str name: what the place is called :param str description: a short summary of this place :param str address: a human-readable postal address :param float lat: latitude :param float lon: longitudel :param [Person] owners: the property owner(s) :param [Excerpt] excerpts: excerpts related to this Place """ __schema__ = PlaceSchema id = db.Column(db.Integer, primary_key=True) unique = db.Column(db.String(255), unique=True, default=id_generator) name = db.Column(db.String(255), nullable=False) description = db.Column(db.String(8**7)) address = db.Column(db.String(4096)) lat = db.Column(db.Float()) lon = db.Column(db.Float()) owners = db.relationship('Person', secondary="places_owners", lazy='dynamic', backref="properties") excerpts = db.relationship('Excerpt', secondary="places_excerpts", lazy='dynamic') def __str__(self): return(self.name)
[docs]class Item(db.Model, CRUDMixin, MarshmallowMixin): """ An item is any "thing" that is work describing. :param int id: the database object identifier :param str unique: alpha-numeric code for shorthand identifier :param str name: what the item is called :param str description: a short summary of this item :param [Person] owners: the property owner(s) :param [Excerpt] excerpts: excerpts related to this Item """ __schema__ = ItemSchema id = db.Column(db.Integer, primary_key=True) unique = db.Column(db.String(255), unique=True, default=id_generator) name = db.Column(db.String(255), nullable=False) description = db.Column(db.String(8**7)) owners = db.relationship('Person', secondary="items_owners", lazy='dynamic', backref="items") excerpts = db.relationship('Excerpt', secondary="items_excerpts", lazy='dynamic') def __str__(self): return(self.name)
[docs]class Group(db.Model, CRUDMixin, MarshmallowMixin): """ A Group is a collection of Persons who are associated with one another. Membership in a group implies a many-to-many relationship between the members. A group is different from an Acquaintance; it is bi-directional, not uni-directional. :param int id: the database object identifier :param str unique: alpha-numeric code for shorthand identifier :param str name: what the group is called :param [Person] members: people who are members of this Group :param [Excerpt] excerpts: excerpts related to this Group """ __schema__ = GroupSchema id = db.Column(db.Integer, primary_key=True) unique = db.Column(db.String(255), unique=True, default=id_generator) name = db.Column(db.String(255), nullable=False) members = db.relationship('Person', secondary="groups_members", lazy='dynamic', backref="groups") excerpts = db.relationship('Excerpt', secondary="groups_excerpts", lazy='dynamic') def __str__(self): return self.name
[docs]class Event(db.Model, CRUDMixin, MarshmallowMixin): """ An Event is an occurrence that somehow alters the Situation. :param int id: the database object identifier :param str unique: alpha-numeric code for shorthand identifier :param str name: what the event is called :param str description: a short summary of this item :param Place place: null :param bool phone: *true* if this event is a phone call :param DateTime timestamp: null :param [Person] actors: null :param [Excerpt] excerpts: excerpts related to this Event :param [Item] items: null """ __schema__ = EventSchema id = db.Column(db.Integer, primary_key=True) unique = db.Column(db.String(255), unique=True, default=id_generator) name = db.Column(db.String(255), nullable=False) description = db.Column(db.String(8**7)) place_id = db.Column(db.Integer, db.ForeignKey('place.id')) place = db.relationship("Place", backref="events") phone = db.Column(db.Boolean(), default=False) timestamp = db.Column(db.DateTime()) actors = db.relationship('Person', secondary="events_actors", lazy='dynamic', backref="events") excerpts = db.relationship('Excerpt', secondary="events_excerpts", lazy='dynamic') items = db.relationship('Item', secondary="events_items", lazy='dynamic') def __str__(self): return self.name