class Message(orm.SQLObject): """The class generates a Message table containing information about user messages. Args: text (str, optional): time (int, optional): filePicture (byte, optional): fileVideo (byte, optional): fileAudio (byte, optional): fileDocument (byte, optional): emoji (str, optional): editedTime (int, optional): editedStatus (bool, optional): Returns: None """ text = orm.StringCol(default=None) time = orm.IntCol(default=None) filePicture = orm.BLOBCol(default=None) fileVideo = orm.BLOBCol(default=None) fileAudio = orm.BLOBCol(default=None) fileDocument = orm.BLOBCol(default=None) emoji = orm.BLOBCol(default=None) editedTime = orm.IntCol(default=None) editedStatus = orm.BoolCol(default=False) userConfig = orm.ForeignKey('UserConfig', refColumn="uuid") flow = orm.ForeignKey('Flow', refColumn="flowId")
class Subjects(sqlobject.SQLObject): _connection = conn maths = sqlobject.IntCol(name=None) hindi = sqlobject.IntCol(name=None) science = sqlobject.IntCol(name=None) english = sqlobject.IntCol(name=None) student = sqlobject.ForeignKey('Student')
class Author(sqlobject.SQLObject): name = sqlobject.StringCol(alternateID=True, length=50) urls = sqlobject.MultipleJoin('URL') comments = sqlobject.MultipleJoin('Comments') points_new = sqlobject.IntCol(default=0) points_old = sqlobject.IntCol(default=0) points_credit = sqlobject.IntCol(default=0)
class Mood(Record): """ Table to hold mood data. """ # Emotional score from -2 to +2. emotion = so.IntCol(default=0) # Eight key emotional areas. joy = so.IntCol(default=0) trust = so.IntCol(default=0) fear = so.IntCol(default=0) surprise = so.IntCol(default=0) sadness = so.IntCol(default=0) disgust = so.IntCol(default=0) anger = so.IntCol(default=0) anticipation = so.IntCol(default=0) def _set_emotion(self, value): """ Enforce rule that emotion value must be an integer or of a type which can be parsed to integer. And must be -2, -1, 0, 1 or 2. """ try: intValue = int(value) except TypeError: raise 'TypeError, Emotion score must be an integer.' assert -2<=intValue<=2, \ 'ValueError, Emotion score must be between -2 and +2.' self._SO_set_emotion(intValue)
class Board(SO.SQLObject): chunk_size = SO.IntCol() chunk_mines = SO.IntCol() chunks = SO.MultipleJoin('Chunk') def get_chunk(self, i, k): chunk = Chunk.selectBy(i=i, k=k, board=self) if chunk.count(): return chunk.getOne() chunk = Chunk(i=i, k=k, board=self) chunk.generate_mines() return chunk
class Lyric(sqlobject.SQLObject): _connection = conn sid = sqlobject.IntCol(length=14, unique=True) song = sqlobject.UnicodeCol(length=255) lrc = sqlobject.UnicodeCol(length=255) artist_id = sqlobject.ForeignKey('Artist') aid = sqlobject.IntCol(length=14) #new add field local_path = sqlobject.UnicodeCol(length=255, default=None) sizes = sqlobject.IntCol(default=None) source = sqlobject.UnicodeCol(default=None)
class User(sqlobject.SQLObject): _connection = establish_connection() userName = sqlobject.StringCol(length=100, unique=False) age = sqlobject.IntCol(default=None) height = sqlobject.IntCol(default=None) weight = sqlobject.IntCol(default=None) gender = sqlobject.StringCol(length=6) activity = sqlobject.FloatCol(default=None) def __repr__(self): return "name: {}\nage: {}\nheight: {}\nweight: {}\ngender: {}\nactv: {}".format(self.userName,\ self.age, self.height, self.weight, self.gender, self.activity)
class FileMeta(sqlobject.SQLObject, File): """ store rating metadata about a file, create thumbnails, and more! """ class sqlmeta: lazyUpdate = True # must call #syncUpdate or #sync to save changes MOCK = False absolute = sqlobject.StringCol(notNone=True, unique=True, alternateID=True) hits = sqlobject.IntCol(notNone=True, default=0) rating = sqlobject.FloatCol(notNone=True, default=0.0) rating_hits = sqlobject.IntCol(notNone=True, default=0) def rate(self, rating): """ store an incoming rating value, out of 10 would rate/10 """ # no crazy bznz if rating > 10 or rating < 0: raise ValueError('Rating value out of bounds [0 - 10]') return self.rating so_far = self.rating * self.ratingHits now = (so_far + rating) / (self.rating_hits + 1) self.rating = now self.ratingHits = self.rating_hits + 1 self.syncUpdate() return now def hit(self): self.hits += 1 self.syncUpdate() return self.hits @classmethod def for_path(cls, absolute, root=None): """get or create for this path""" if cls.MOCK: return MockFileMeta(absolute=absolute, hits=0, rating=5.5, rating_hits=100) try: instance = cls.byAbsolute(absolute) except sqlobject.SQLObjectNotFound: instance = cls(absolute=absolute) instance.syncUpdate() instance.root = root return instance
class ValorMedicion(SO.SQLObject, Serializer): class sqlmeta: style = SO.MixedCaseStyle(longID=True) valor = SO.DecimalCol(size=10, precision=2) unixTimeStamp = SO.IntCol() medicion = SO.ForeignKey('Medicion')
class Medicion(SO.SQLObject, Serializer): class sqlmeta: style = SO.MixedCaseStyle(longID=True) nombre = SO.StringCol(length=40, varchar=True) intervalo = SO.IntCol() linea = SO.ForeignKey('Linea') unidad = SO.ForeignKey('Unidad')
class Product(sqlobject.SQLObject): _connection = establish_connection() productName = sqlobject.StringCol(length=100) energyPoints = sqlobject.IntCol(default=None) date = sqlobject.DateCol() def __repr__(self): return "date: {} name = {}, energy = {}".format(self.date,\ self.productName, self.energyPoints)
class SingleImageRow(sqlobject.SQLObject): # single big text field for tags tags = sqlobject.StringCol() rawData = sqlobject.StringCol() hits = sqlobject.IntCol() originalPathName = sqlobject.StringCol() name = sqlobject.StringCol() dataType = sqlobject.StringCol() series = sqlobject.ForeignKey("ImageSeriesRow", default=None)
class Guest(DictSQLObject): """ Collects information about Guests Refrenced to by the ChatMsg Table """ name = so.UnicodeCol() admin = so.BoolCol(default=False) parprop = so.IntCol(default=-1) token = so.StringCol(length=8) event = so.ForeignKey('Event')
class Movie(sqlobject.SQLObject): """Class voor het databaseobject movie""" _connection = conn ft_link = sqlobject.StringCol() ft_title = sqlobject.StringCol() ft_year = sqlobject.StringCol() ft_director = sqlobject.StringCol() ft_cast = sqlobject.StringCol() ft_genre = sqlobject.StringCol() ft_country = sqlobject.StringCol() ft_cover_img = sqlobject.StringCol() ft_tagline = sqlobject.StringCol() ft_length = sqlobject.StringCol() ft_synopsis = sqlobject.StringCol() ft_rating = sqlobject.FloatCol() ft_votes = sqlobject.IntCol() imdb_id = sqlobject.StringCol(unique=True) imdb_rating = sqlobject.FloatCol() imdb_votes = sqlobject.IntCol() ft_movietip = sqlobject.StringCol()
class Flow(orm.SQLObject): """The class generates a Flow table containing information about threads and their types (chat, channel, group). Args: flowId (int, required): timeCreated (int, optional): flowType (str, optional): title (str, optional): info (str, optional): Returns: None """ flowId = orm.IntCol(alternateID=True, unique=True, notNone=True) timeCreated = orm.IntCol(default=None) flowType = orm.StringCol(default=None) title = orm.StringCol(default=None) info = orm.StringCol(default=None) # Connection to the Message table message = orm.MultipleJoin('Message')
class URL(sqlobject.SQLObject): class sqlmeta: table = 'url' url = sqlobject.StringCol() clean = sqlobject.StringCol() author = sqlobject.ForeignKey('Author') channel = sqlobject.ForeignKey('Channel') citations = sqlobject.IntCol(default=0) posted = sqlobject.DateTimeCol(default=datetime.now) comments = sqlobject.MultipleJoin('Comments')
class Job(sqlobject.SQLObject): status = sqlobject.IntCol(default=JobStatus.UNKNOWN) package = sqlobject.ForeignKey('Package', cascade=True) dist = sqlobject.StringCol(default='unreleased') arch = sqlobject.StringCol(default='any') creation_date = sqlobject.DateTimeCol(default=sqlobject.DateTimeCol.now) build_host = sqlobject.StringCol(default=None) status_changed = sqlobject.DateTimeCol(default=None) build_start = sqlobject.DateTimeCol(default=None) build_end = sqlobject.DateTimeCol(default=None) def __init__(self, *args, **kwargs): sqlobject.SQLObject.__init__(self, *args, **kwargs) self.status_lock = status_lock def __setattr__(self, name, value): if name == "status": self.status_changed = sqlobject.DateTimeCol.now() sqlobject.SQLObject.__setattr__(self, name, value) def dict(self): result = { "id": self.id, "task": "%s/%s" % (self.dist, self.arch), "build_host": self.build_host, "status": JobStatus.whatis(self.status), "dist": self.dist, "arch": self.arch, "creation_date": try_strftime(self.creation_date), "build_start": try_strftime(self.build_start), "build_end": try_strftime(self.build_end), "status_changed": try_strftime(self.status_changed) } return result def start(self, slave, builder): if self.status != JobStatus.WAIT_LOCKED: raise ValueError("JobStatus is not WAIT_LOCKED") else: self.status = JobStatus.BUILDING self.build_start = sqlobject.DateTimeCol.now() self.build_host = slave.name kwargs = self.dict() kwargs.update(self.package.dict()) return slave.build(self.id, builder, kwargs)
class UwatchPkgVersion(sqlobject.SQLObject): id_pkg = sqlobject.IntCol(dbName="ID_PKG") gar_path = sqlobject.UnicodeCol(length=255, dbName="PKG_GAR_PATH") pkgname = sqlobject.UnicodeCol(length=64, dbName="PKG_NAME") catalogname = sqlobject.UnicodeCol(length=64, dbName="PKG_CATALOGNAME") gar_version = sqlobject.UnicodeCol(length=255, dbName="PKG_GAR_VERSION") upstream_version = sqlobject.UnicodeCol(length=255, dbName="PKG_UPSTREAM_VERSION") master_sites = sqlobject.UnicodeCol(length=255, dbName="PKG_UPSTREAM_MASTER_SITES") distfiles = sqlobject.UnicodeCol(length=255, dbName="PKG_GAR_DISTFILES") regex = sqlobject.UnicodeCol(length=255, dbName="PKG_UFILES_REGEXP") class sqlmeta(object): table = "UWATCH_PKG_VERSION" idName = "id_pkg"
class Errors(orm.SQLObject): """The class generates an Errors table in which all types of errors are pre-stored. Args: status (str, optional): code (int, optional): detail (str, optional): Returns: None """ # status and code is standart HTTP status code status = orm.StringCol(default=None) code = orm.IntCol(default=None) detail = orm.StringCol(default=None)
class UserConfig(orm.SQLObject): """The class generates a table containing data about the user and his settings. Args: uuid (int, required): login (str, required): password (str, required): hash_password (str, optional) username (str, optional): isBot (bool, optional): default False authId (str, optional): email (str, optional): avatar (str, optional): bio (str, optional): salt (str, optional): key (str, optional): Returns: None """ # added alternateID for added class method @byUUID # which will return that object uuid = orm.IntCol(alternateID=True, unique=True, notNone=True) login = orm.StringCol() password = orm.StringCol() hashPassword = orm.StringCol(default=None) username = orm.StringCol(default=None) isBot = orm.BoolCol(default=False) authId = orm.StringCol(default=None) email = orm.StringCol(default=None) avatar = orm.BLOBCol(default=None) bio = orm.StringCol(default=None) salt = orm.BLOBCol(default=None) key = orm.BLOBCol(default=None) # Connection to the Message table message = orm.MultipleJoin('Message')
class Srv4FileStats(sqlobject.SQLObject): """Represents a srv4 file. It focuses on the stats, but it can as well represent just a srv4 file. """ arch = sqlobject.ForeignKey('Architecture', notNone=True) basename = sqlobject.UnicodeCol(notNone=True) catalogname = sqlobject.UnicodeCol(notNone=True) # The data structure can be missing - necessary for fake SUNW # packages. data_obj = sqlobject.ForeignKey('Srv4FileStatsBlob', notNone=False) filename_arch = sqlobject.ForeignKey('Architecture', notNone=True) latest = sqlobject.BoolCol(notNone=True) maintainer = sqlobject.ForeignKey('Maintainer', notNone=False) md5_sum = sqlobject.UnicodeCol(notNone=True, unique=True, length=32) size = sqlobject.IntCol() mtime = sqlobject.DateTimeCol(notNone=False) os_rel = sqlobject.ForeignKey('OsRelease', notNone=True) pkginst = sqlobject.ForeignKey('Pkginst', notNone=True) registered = sqlobject.BoolCol(notNone=True) use_to_generate_catalogs = sqlobject.BoolCol(notNone=True) rev = sqlobject.UnicodeCol(notNone=False) stats_version = sqlobject.IntCol(notNone=True) version_string = sqlobject.UnicodeCol(notNone=True) in_catalogs = sqlobject.MultipleJoin('Srv4FileInCatalog', joinColumn='srv4file_id') files = sqlobject.MultipleJoin('CswFile', joinColumn='id') def __init__(self, *args, **kwargs): super(Srv4FileStats, self).__init__(*args, **kwargs) self._cached_pkgstats = None def DeleteAllDependentObjects(self): data_obj = self.data_obj self.data_obj = None if data_obj: # It could be already missing data_obj.destroySelf() self.RemoveAllCswFiles() self.RemoveAllCheckpkgResults() self.RemoveOverrides() def RemoveAllCswFiles(self): # Removing existing files, using sqlbuilder to use sql-level # mechanisms without interacting with Python. # http://www.mail-archive.com/[email protected]/msg00520.html sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr( sqlbuilder.Delete(CswFile.sqlmeta.table, CswFile.q.srv4_file == self))) def GetOverridesResult(self): return CheckpkgOverride.select(CheckpkgOverride.q.srv4_file == self) def GetErrorTagsResult(self, os_rel, arch, catrel): assert arch.name != 'all', ( "Asked for the 'all' architecture, this is not valid " "for GetErrorTagsResult().") return CheckpkgErrorTag.select( sqlobject.AND(CheckpkgErrorTag.q.srv4_file == self, CheckpkgErrorTag.q.os_rel == os_rel, CheckpkgErrorTag.q.arch == arch, CheckpkgErrorTag.q.catrel == catrel)) def RemoveCheckpkgResults(self, os_rel, arch, catrel): logging.debug("%s: RemoveCheckpkgResults(%s, %s, %s)", self, os_rel, arch, catrel) sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr( sqlbuilder.Delete( CheckpkgErrorTag.sqlmeta.table, sqlobject.AND(CheckpkgErrorTag.q.srv4_file == self, CheckpkgErrorTag.q.os_rel == os_rel, CheckpkgErrorTag.q.arch == arch, CheckpkgErrorTag.q.catrel == catrel)))) def RemoveAllCheckpkgResults(self): logging.debug("%s: RemoveAllCheckpkgResults()", self) sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr( sqlbuilder.Delete(CheckpkgErrorTag.sqlmeta.table, CheckpkgErrorTag.q.srv4_file == self))) def RemoveOverrides(self): logging.debug("%s: RemoveOverrides()", self) sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr( sqlbuilder.Delete(CheckpkgOverride.sqlmeta.table, CheckpkgOverride.q.srv4_file == self))) def __unicode__(self): return (u"Package: %s-%s, %s" % (self.catalogname, self.version_string, self.arch.name)) def GetUnicodeOrNone(self, s): """Tries to decode UTF-8. If the object does not decode as UTF-8, it's forced to do so, while ignoring any potential errors. Returns: a unicode object or a None type. """ if s is None: return None if type(s) != unicode: try: s = unicode(s, 'utf-8') except UnicodeDecodeError, e: s = s.decode("utf-8", "ignore") s = s + u" (bad unicode detected)" return s
class Mine(SO.SQLObject): x = SO.IntCol() y = SO.IntCol() chunk = SO.ForeignKey('Chunk')
class CswConfig(sqlobject.SQLObject): option_key = sqlobject.UnicodeCol(length=255, unique=True) float_value = sqlobject.FloatCol(default=None) int_value = sqlobject.IntCol(default=None) str_value = sqlobject.UnicodeCol(default=None, length=250)
class Srv4FileStats(sqlobject.SQLObject): """Represents a srv4 file. It focuses on the stats, but it can as well represent just a srv4 file. """ arch = sqlobject.ForeignKey('Architecture', notNone=True) basename = sqlobject.UnicodeCol(notNone=True, length=250) catalogname = sqlobject.UnicodeCol(notNone=True, length=250) filename_arch = sqlobject.ForeignKey('Architecture', notNone=True) maintainer = sqlobject.ForeignKey('Maintainer', notNone=False) md5_sum = sqlobject.UnicodeCol(notNone=True, unique=True, length=32) size = sqlobject.IntCol() mtime = sqlobject.DateTimeCol(notNone=False) os_rel = sqlobject.ForeignKey('OsRelease', notNone=True) osrel_str = sqlobject.UnicodeCol(notNone=True, length=9) # "SunOS5.10" pkginst = sqlobject.ForeignKey('Pkginst', notNone=True) pkginst_str = sqlobject.UnicodeCol(notNone=True, length=255) registered_level_one = sqlobject.BoolCol(notNone=True) registered_level_two = sqlobject.BoolCol(notNone=True) use_to_generate_catalogs = sqlobject.BoolCol(notNone=True) rev = sqlobject.UnicodeCol(notNone=False, length=250) stats_version = sqlobject.IntCol(notNone=True) version_string = sqlobject.UnicodeCol(notNone=True, length=250) bundle = sqlobject.UnicodeCol(length=250) in_catalogs = sqlobject.MultipleJoin( 'Srv4FileInCatalog', joinColumn='srv4file_id') files = sqlobject.MultipleJoin('CswFile', joinColumn='id') catalog_idx = sqlobject.DatabaseIndex('catalogname') basename_idx = sqlobject.DatabaseIndex('basename') pkginst_idx = sqlobject.DatabaseIndex('pkginst') def __init__(self, *args, **kwargs): super(Srv4FileStats, self).__init__(*args, **kwargs) def __unicode__(self): return u'%s/%s, %s' % (self.pkginst.pkgname, self.catalogname, self.md5_sum) def __str__(self): return str(unicode(self)) def DeleteAllDependentObjects(self): """Prepares the object to be deleted. Use this function with caution. """ self.DeleteDependentObjectsPopulatedFromPackageItself() logger.debug('Removing all dependent objects from %s; it will cause the ' 'package to be removed from all catalogs.', self) self.RemoveCatalogAssignments() self.RemoveAllCheckpkgResults() def DeleteDependentObjectsPopulatedFromPackageItself(self): """Removing all the objects that only depend on the package contents. It doesn't touch rows that are created for other reasons, e.g. assignments of packages to catalogs. """ logger.debug('%s - Deleting objects that only depend on the package ' 'contents', self) self.RemoveAllCswFiles() self.RemoveOverrides() self.RemoveDepends() self.RemoveIncompatibles() def RemoveAllCswFiles(self): # Removing existing files, using sqlbuilder to use sql-level # mechanisms without interacting with Python. # http://www.mail-archive.com/[email protected]/msg00520.html sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr(sqlbuilder.Delete( CswFile.sqlmeta.table, CswFile.q.srv4_file==self))) def RemoveDepends(self): sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr(sqlbuilder.Delete( Srv4DependsOn.sqlmeta.table, Srv4DependsOn.q.srv4_file==self))) def RemoveIncompatibles(self): sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr(sqlbuilder.Delete( Srv4IncompatibleWith.sqlmeta.table, Srv4IncompatibleWith.q.srv4_file==self))) def RemoveCatalogAssignments(self): sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr(sqlbuilder.Delete( Srv4FileInCatalog.sqlmeta.table, Srv4FileInCatalog.q.srv4file==self))) def GetOverridesResult(self): return CheckpkgOverride.select(CheckpkgOverride.q.srv4_file==self) def GetErrorTagsResult(self, os_rel, arch, catrel): assert arch.name != 'all', ( "Asked for the 'all' architecture, this is not valid " "for GetErrorTagsResult().") return CheckpkgErrorTag.select( sqlobject.AND( CheckpkgErrorTag.q.srv4_file==self, CheckpkgErrorTag.q.os_rel==os_rel, CheckpkgErrorTag.q.arch==arch, CheckpkgErrorTag.q.catrel==catrel)) def RemoveCheckpkgResults(self, os_rel, arch, catrel): logger.debug("%s: RemoveCheckpkgResults(%s, %s, %s)", self, os_rel, arch, catrel) sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr(sqlbuilder.Delete( CheckpkgErrorTag.sqlmeta.table, sqlobject.AND( CheckpkgErrorTag.q.srv4_file==self, CheckpkgErrorTag.q.os_rel==os_rel, CheckpkgErrorTag.q.arch==arch, CheckpkgErrorTag.q.catrel==catrel)))) def RemoveAllCheckpkgResults(self): logger.debug("%s: RemoveAllCheckpkgResults()", self) sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr(sqlbuilder.Delete( CheckpkgErrorTag.sqlmeta.table, CheckpkgErrorTag.q.srv4_file==self))) def RemoveOverrides(self): logger.debug("%s: RemoveOverrides()", self) sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr(sqlbuilder.Delete( CheckpkgOverride.sqlmeta.table, CheckpkgOverride.q.srv4_file==self))) def GetUnicodeOrNone(self, s): """Tries to decode UTF-8. If the object does not decode as UTF-8, it's forced to do so, while ignoring any potential errors. Returns: a unicode object or a None type. """ if s is None: return None if type(s) != unicode: try: s = unicode(s, 'utf-8') except UnicodeDecodeError, e: s = s.decode("utf-8", "ignore") s = s + u" (bad unicode detected)" return s
class Profile(so.SQLObject): """ Models a user profile on Twitter. Note that URL columns are named as 'Url', since SQLOlbject converts 'imageURL' to db column named 'image_ur_l'. Twitter screen name and username rules: https://help.twitter.com/en/managing-your-account/twitter-username-rules We use slightly higher values than the ones there, to be safe. Notes on screen name: - This should not have unique restriction as users can edit their screen name so others can take an older screen name. Or someone could delete and recreate their account. - Twitter itself enforces uniqueness across case. """ # Profile's ID (integer), as assigned by Twitter when the Profile was # created. This is a global ID, rather than an ID specific to our local db. guid = so.IntCol(alternateID=True) # Profile screen name. screenName = so.StringCol(notNull=True, length=30) # Profile display Name. name = so.StringCol(notNull=True, length=60) # Description, as set in profile's bio. description = so.StringCol(default=None) # Location, as set in profile's bio. location = so.StringCol(default=None) # Link to the profile's image online. This will only be thumbnail size. imageUrl = so.StringCol(default=None, validator=URL) # Count of profile's followers. followersCount = so.IntCol(notNull=True) # Count of profile's statuses (tweets) posted by this profile. statusesCount = so.IntCol(notNull=True) # Profile's verified status. verified = so.BoolCol(notNull=True, default=False) # Join the Profile with its created tweets in the Tweet table. tweets = so.MultipleJoin("Tweet") # Date and time when follower and status counts were last updated. modified = so.DateTimeCol(notNull=True, default=so.DateTimeCol.now) modifiedIdx = so.DatabaseIndex(modified) # Get Category objects which this Profile has been assigned to, if any. categories = so.SQLRelatedJoin("Category", intermediateTable="profile_category", createRelatedTable=False) def set(self, **kwargs): """ Override the update hook to update the modified field if necessary. """ if ("followersCount" in kwargs or "statusesCount" in kwargs) and "modified" not in kwargs: kwargs["modified"] = so.DateTimeCol.now() super(Profile, self).set(**kwargs) def getFlatDescription(self): """ Return the description with newline characters replaced with spaces. """ if self.description is not None: return lib.text_handling.flattenText(self.description) return None def getProfileUrl(self): """ Get link to the profile's page online. :return: Twitter profile's URL, as a string. """ return "https://twitter.com/{0}".format(self.screenName) def getLargeImageUrl(self): """ Get link to a large version profile's image, based on thumbnail URL. The image URL comes from the API as '..._normal.jpeg', but from API calls on loading a twitter.com page, it is possible to see that the image media server allows variations of the last part, to return a large image. Such as - '..._bigger.jpeg' (which is not much bigger than the normal thumbnail) - '..._400x400.jpeg' (which is much bigger). :return: image URL using 400x400 size parameter, or None if value was not set. """ if self.imageUrl: return self.imageUrl.replace("_normal", "_400x400") return None def prettyPrint(self): """ Method to print the attributes of the Profile instance neatly. :return: dictionary of data which was printed. """ output = """\ Screen name : @{screenName} Name : {name} Verified : {verified} Followers : {followers:,d} Statuses : {statuses:,d} DB tweets : {tweetCount} Description : {description} Profile URL : {url} Image URL : {imageUrl} Stats modified : {statsModified} """ data = dict( screenName=self.screenName, name=self.name, verified=self.verified, followers=self.followersCount, statuses=self.statusesCount, tweetCount=len(self.tweets), description=self.getFlatDescription(), url=self.getProfileUrl(), imageUrl=self.getLargeImageUrl(), statsModified=self.modified, ) print(output.format(**data)) return data
class Tweet(so.SQLObject): """ Models a tweet on Twitter. If we are inserting the Tweet in our db, we expect to always have the author's profile in the Profile table. If the tweet is a reply, we will have references to the target Profile and original Tweet as GUID integers. But we are unlikely to have those object stored in our db. Use the `.getInReplyToTweet` and `.getInReplyToProfile` methods to see if those exist in the db, otherwise use the GUIDs to look up data from the Twitter API and then store them locally as db records. For relating a Tweet to its author Profile with a foreign key, a `setProfileByGuid` method could be implemented to set the profile foreign key using a given GUID, but that would require doing a search each time. So, when creating a Tweet object or multiple objects for one Profile, it is preferable to get the Profile object's ID once and then repeately pass that in as an argument for each Tweet object that is created for that Profile. For ordering, the '-guid' syntax is here is preferred, since 'guid DESC' results in an error when getting tweets of a Profile object, even though doing a query on Tweet class itself is fine. `AttributeError: 'Tweet' object has no attribute 'guid DESC'` The error is also raised for multiple names e.g. '-guid, message'. """ class sqlmeta: # Show recent Tweets (with higher GUID values) first. defaultOrder = "-guid" # Tweet ID (integer), as assigned by Twitter when the Tweet was posted. # This is a global ID, rather than specific to our local db. guid = so.IntCol(alternateID=True) # Link to Tweet's author in the Profile table. Delete Tweet if # the Profile is deleted. profile = so.ForeignKey("Profile", notNull=True, cascade=True) profileIdx = so.DatabaseIndex(profile) # Date and time the tweet was posted. createdAt = so.DateTimeCol(notNull=True) createdAtIdx = so.DatabaseIndex(createdAt) # Tweet message text. Length is not validated since expanded tweets can # be longer than the standard 280 (previously 140) characters. message = so.StringCol(notNull=True) # Count of favorites on this Tweet. favoriteCount = so.IntCol(notNull=True) # Count of retweets of this Tweet. retweetCount = so.IntCol(notNull=True) # If the tweet is a reply, the GUID of the Tweet which the reply is # directed at (from reply_to_status_id field). This does not require # the Tweet to be in the local db. inReplyToTweetGuid = so.IntCol(default=None) # If the tweet is a reply, the GUID of the Profile which the reply is # directed at (from reply_to_user_id field). This does not require # the Tweet to be in the local db. inReplyToProfileGuid = so.IntCol(default=None) # Date and time when favorite and retweet counts where last updated. modified = so.DateTimeCol(notNull=True, default=so.DateTimeCol.now) modifiedIdx = so.DatabaseIndex(modified) # Get Campaign objects which this Profile has been assigned to, if any. campaigns = so.SQLRelatedJoin("Campaign", intermediateTable="tweet_campaign", createRelatedTable=False) def set(self, **kwargs): """ Override the update hook to update the modified field if necessary. """ if ("favoriteCount" in kwargs or "retweetCount" in kwargs) and "modified" not in kwargs: kwargs["modified"] = so.DateTimeCol.now() super(Tweet, self).set(**kwargs) def isRT(self): return self.message.startswith("RT ") def isReply(self): return self.inReplyToProfileGuid is not None def getFlatMessage(self): """ Return the message with newline characters replaced with spaces. """ return lib.text_handling.flattenText(self.message) def getInReplyToTweet(self): """ If this Tweet is a reply, get the original Tweet it was directed at. :return: single Tweet object. Return None if this is not a reply. Raise an error if the Tweet is not in the local db. """ if self.inReplyToTweetGuid: try: return Tweet.byGuid(self.inReplyToTweetGuid) except SQLObjectNotFound as e: raise type(e)( "Could not find Tweet in db with GUID: {0}".format( self.inReplyToTweetGuid)) return None def getInReplyToProfile(self): """ If this Tweet is a reply, get the Profile which it was directed at. :return: single Profile object. Return None if this is not a reply. Raise an error if the Tweet is not in the local db. """ if self.inReplyToProfileGuid: try: return Profile.byGuid(self.inReplyToProfileGuid) except SQLObjectNotFound as e: raise type(e)( "Could not find Profile in db with GUID: {0}".format( self.inReplyToProfileGuid)) return None def getTweetURL(self): """ Return URL for the tweet as a string, using tweet author's screen name and the tweet's GUID. """ return "https://twitter.com/{screenName}/status/{tweetID}".format( screenName=self.profile.screenName, tweetID=self.guid) def prettyPrint(self): """ Method to print the attributes of the Tweet instance neatly. :return: dictionary of data which was printed. """ output = """\ Author : @{screenName} - {name} - {followers:,d} followers Created at : {createdAt} Message : {message} Favorites : {favoriteCount:,d} Retweets : {retweetCount:,d} Reply To User ID : {replyProf} Reply To Tweet ID : {replyTweet} URL : {url} Stats modified : {statsModified} """ author = self.profile data = dict( screenName=author.screenName, createdAt=self.createdAt, name=author.name, followers=author.followersCount, message=self.getFlatMessage(), favoriteCount=self.favoriteCount, retweetCount=self.retweetCount, replyProf=self.inReplyToProfileGuid, replyTweet=self.inReplyToTweetGuid, url=self.getTweetURL(), statsModified=self.modified, ) print(output.format(**data)) return data def report(self): """ Return Tweet and Profile data as dict for writing a CSV report. """ author = self.profile return { "Screen name": author.screenName, "Followers": author.followersCount, "Tweet URL": self.getTweetURL(), "Tweet ID": self.guid, "Tweeted at": str(self.createdAt), "Is reply": "Y" if self.isReply() else "N", "Is RT": "Y" if self.isRT() else "N", "Message": self.message, "Favs": self.favoriteCount, "RTs": self.retweetCount, }
class Srv4FileStats(sqlobject.SQLObject): """Represents a srv4 file. It focuses on the stats, but it can as well represent just a srv4 file. """ arch = sqlobject.ForeignKey('Architecture', notNone=True) basename = sqlobject.UnicodeCol(notNone=True) catalogname = sqlobject.UnicodeCol(notNone=True) # The data structure can be missing - necessary for fake SUNW # packages. data_obj = sqlobject.ForeignKey('Srv4FileStatsBlob', notNone=False) filename_arch = sqlobject.ForeignKey('Architecture', notNone=True) latest = sqlobject.BoolCol(notNone=True) maintainer = sqlobject.ForeignKey('Maintainer', notNone=False) md5_sum = sqlobject.UnicodeCol(notNone=True, unique=True, length=32) size = sqlobject.IntCol() mtime = sqlobject.DateTimeCol(notNone=False) os_rel = sqlobject.ForeignKey('OsRelease', notNone=True) pkginst = sqlobject.ForeignKey('Pkginst', notNone=True) registered = sqlobject.BoolCol(notNone=True) use_to_generate_catalogs = sqlobject.BoolCol(notNone=True) rev = sqlobject.UnicodeCol(notNone=False) stats_version = sqlobject.IntCol(notNone=True) version_string = sqlobject.UnicodeCol(notNone=True) in_catalogs = sqlobject.MultipleJoin('Srv4FileInCatalog', joinColumn='srv4file_id') files = sqlobject.MultipleJoin('CswFile', joinColumn='id') def __init__(self, *args, **kwargs): super(Srv4FileStats, self).__init__(*args, **kwargs) self._cached_pkgstats = None def DeleteAllDependentObjects(self): data_obj = self.data_obj self.data_obj = None if data_obj: # It could be already missing data_obj.destroySelf() self.RemoveAllCswFiles() self.RemoveAllCheckpkgResults() self.RemoveOverrides() def RemoveAllCswFiles(self): # Removing existing files, using sqlbuilder to use sql-level # mechanisms without interacting with Python. # http://www.mail-archive.com/[email protected]/msg00520.html sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr( sqlbuilder.Delete(CswFile.sqlmeta.table, CswFile.q.srv4_file == self))) def GetOverridesResult(self): return CheckpkgOverride.select(CheckpkgOverride.q.srv4_file == self) def GetErrorTagsResult(self, os_rel, arch, catrel): assert arch.name != 'all', ( "Asked for the 'all' architecture, this is not valid " "for GetErrorTagsResult().") return CheckpkgErrorTag.select( sqlobject.AND(CheckpkgErrorTag.q.srv4_file == self, CheckpkgErrorTag.q.os_rel == os_rel, CheckpkgErrorTag.q.arch == arch, CheckpkgErrorTag.q.catrel == catrel)) def RemoveCheckpkgResults(self, os_rel, arch, catrel): logging.debug("%s: RemoveCheckpkgResults(%s, %s, %s)", self, os_rel, arch, catrel) sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr( sqlbuilder.Delete( CheckpkgErrorTag.sqlmeta.table, sqlobject.AND(CheckpkgErrorTag.q.srv4_file == self, CheckpkgErrorTag.q.os_rel == os_rel, CheckpkgErrorTag.q.arch == arch, CheckpkgErrorTag.q.catrel == catrel)))) def RemoveAllCheckpkgResults(self): logging.debug("%s: RemoveAllCheckpkgResults()", self) sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr( sqlbuilder.Delete(CheckpkgErrorTag.sqlmeta.table, CheckpkgErrorTag.q.srv4_file == self))) def RemoveOverrides(self): logging.debug("%s: RemoveOverrides()", self) sqlobject.sqlhub.processConnection.query( sqlobject.sqlhub.processConnection.sqlrepr( sqlbuilder.Delete(CheckpkgOverride.sqlmeta.table, CheckpkgOverride.q.srv4_file == self))) def __unicode__(self): return (u"Package: %s-%s, %s" % (self.catalogname, self.version_string, self.arch.name)) def GetStatsStruct(self): if not self._cached_pkgstats: self._cached_pkgstats = cPickle.loads(str(self.data_obj.pickle)) return self._cached_pkgstats def _GetBuildSource(self): data = self.GetStatsStruct() build_src = None if "OPENCSW_REPOSITORY" in data["pkginfo"]: build_src = data["pkginfo"]["OPENCSW_REPOSITORY"] return build_src def GetSvnUrl(self): build_src = self._GetBuildSource() svn_url = None if build_src: svn_url = re.sub(r'([^@]*).*', r'\1/Makefile', build_src) return svn_url def GetTracUrl(self): build_src = self._GetBuildSource() trac_url = None if build_src: trac_url = re.sub( r'https://gar.svn.(sf|sourceforge).net/svnroot/gar/([^@]+)@(.*)', r'http://sourceforge.net/apps/trac/gar/browser/\2/Makefile?rev=\3', build_src) return trac_url def GetVendorUrl(self): data = self.GetStatsStruct() vendor_url = None if "VENDOR" in data["pkginfo"]: vendor_url = re.split(r"\s+", data["pkginfo"]["VENDOR"])[0] return vendor_url def GetRestRepr(self): mimetype = "application/x-vnd.opencsw.pkg;type=srv4-detail" data = { 'arch': self.arch.name, 'basename': self.basename, # For compatibility with the catalog parser from catalog.py 'file_basename': self.basename, 'catalogname': self.catalogname, 'filename_arch': self.filename_arch.name, 'maintainer_email': self.maintainer.email, 'maintainer_full_name': self.maintainer.full_name, 'md5_sum': self.md5_sum, 'mtime': unicode(self.mtime), 'osrel': self.os_rel.short_name, 'pkgname': self.pkginst.pkgname, 'rev': self.rev, 'size': self.size, 'version_string': self.version_string, # For compatibility with the catalog parser from catalog.py 'version': self.version_string, # 'in_catalogs': unicode([unicode(x) for x in self.in_catalogs]), 'vendor_url': self.GetVendorUrl(), 'repository_url': self.GetSvnUrl(), } return mimetype, data
class UrlMapping(sqlobject.SQLObject): shortUrl = sqlobject.StringCol(length=8, unique=True) originalUrl = sqlobject.StringCol() ctime = sqlobject.IntCol(default=None) shortUrl_index = sqlobject.DatabaseIndex(shortUrl) ctime_index = sqlobject.DatabaseIndex(ctime)
class Action(SO.SQLObject): x = SO.IntCol() y = SO.IntCol() chunk = SO.ForeignKey('Chunk') time = SO.TimestampCol() action = SO.EnumCol(enumValues=['DIG', 'SWITCH_FLAG'])
class Chunk(SO.SQLObject): i = SO.IntCol() k = SO.IntCol() board = SO.ForeignKey('Board') mines = SO.MultipleJoin('Mine') def generate_mines(self): size = self.board.chunk_size #generate square list squares = set() while len(squares) < self.board.chunk_mines: x = random.randrange(size) y = random.randrange(size) squares.add((x, y)) #create mines in the squares for square in squares: Mine(x=square[0], y=square[1], chunk=self) def get_display(self): size = self.board.chunk_size #generate display grid display = [] for y in range(size): display.append([]) for x in range(size): display[y].append({ 'is_mine': False, 'count': 0, 'is_hidden': True, 'flag': False }) #check self mines for mine in self.mines: display[mine.y][mine.x]['is_mine'] = True for x in range(mine.x - 1, mine.x + 2): for y in range(mine.y - 1, mine.y + 2): if x >= 0 and x < size and y >= 0 and y < size: display[y][x]['count'] += 1 #check left mines chunk = self.board.get_chunk(i=self.i - 1, k=self.k) mines = Mine.selectBy(chunk=chunk, x=size - 1) for mine in mines: for y in range(mine.y - 1, mine.y + 2): if y >= 0 and y < size: display[y][0]['count'] += 1 #check right mines chunk = self.board.get_chunk(i=self.i + 1, k=self.k) mines = Mine.selectBy(chunk=chunk, x=0) for mine in mines: for y in range(mine.y - 1, mine.y + 2): if y >= 0 and y < size: display[y][size - 1]['count'] += 1 #check up mines chunk = self.board.get_chunk(i=self.i, k=self.k - 1) mines = Mine.selectBy(chunk=chunk, y=size - 1) for mine in mines: for x in range(mine.x - 1, mine.x + 2): if x >= 0 and x < size: display[0][x]['count'] += 1 #check down mines chunk = self.board.get_chunk(i=self.i, k=self.k + 1) mines = Mine.selectBy(chunk=chunk, y=0) for mine in mines: for x in range(mine.x - 1, mine.x + 2): if x >= 0 and x < size: display[size - 1][x]['count'] += 1 #check left_up mines chunk = self.board.get_chunk(i=self.i - 1, k=self.k - 1) mine = Mine.selectBy(chunk=chunk, x=size - 1, y=size - 1) if mine.count(): display[0][0]['count'] += 1 #check right_up mines chunk = self.board.get_chunk(i=self.i + 1, k=self.k - 1) mine = Mine.selectBy(chunk=chunk, x=0, y=size - 1) if mine.count(): display[0][size - 1]['count'] += 1 #check left_down mines chunk = self.board.get_chunk(i=self.i - 1, k=self.k + 1) mine = Mine.selectBy(chunk=chunk, x=size - 1, y=0) if mine.count(): display[size - 1][0]['count'] += 1 #check right_down mines chunk = self.board.get_chunk(i=self.i + 1, k=self.k + 1) mine = Mine.selectBy(chunk=chunk, x=0, y=0) if mine.count(): display[size - 1][size - 1]['count'] += 1 #return display return display def update_display(self, display, max_action): #set non hidden mines actions = Action.select( SO.AND(Action.q.chunk == self, Action.q.id <= max_action)) for action in actions: if action.action == 'DIG': display[action.y][action.x]['is_hidden'] = False else: display[action.y][ action.x]['flag'] = not display[action.y][action.x]['flag'] return display