def __init__(self, config): ApplicationSession.__init__(self, config) self.count = 0 self.engine = None metadata = MetaData() self.telemetry = Table("telemetry", metadata, Column("id", Integer(), primary_key=True), Column("MSG_ID", Integer()), Column("V_FC", Integer()), Column("V_CAP", Integer()), Column("A_ENG", Integer()), Column("A_CAP", Integer()), Column("T_O2_In", Integer()), Column("T_O2_Out", Integer()), Column("T_FC_H2O_Out", Integer()), Column("Water_In", Integer()), Column("Water_Out", Integer()), Column("Master_SW", Integer()), Column("CAP_Down_SW", Integer()), Column("Drive_SW", Integer()), Column("FC_state", Integer()), Column("Mosfet_state", Integer()), Column("Safety_state", Integer()), Column("Air_Pump_load", Numeric()), Column("Mosfet_load", Integer()), Column("Water_Pump_load", Integer()), Column("Fan_load", Integer()), Column("Acc_X", Integer()), Column("Acc_Y", Integer()), Column("Acc_Z", Integer()), Column("AUX", Numeric()), Column("GPS_X", Integer()), Column("GPS_Y", Integer()), Column("GPS_Z", Integer()), Column("GPS_Speed", Integer()), Column("V_Safety", Integer()), Column("H2_Level", Integer()), Column("O2_calc", Numeric()), Column("lat", Numeric()), Column("lng", Numeric()), )
class QolSG(TaskHasPatientMixin, Task): """ Server implementation of the QoL-SG task. """ __tablename__ = "qolsg" shortname = "QoL-SG" info_filename_stem = "qol" provides_trackers = True category_start_time = Column( "category_start_time", PendulumDateTimeAsIsoTextColType, comment="Time categories were offered (ISO-8601)", ) category_responded = CamcopsColumn( "category_responded", Integer, permitted_value_checker=BIT_CHECKER, comment="Responded to category choice? (0 no, 1 yes)", ) category_response_time = Column( "category_response_time", PendulumDateTimeAsIsoTextColType, comment="Time category was chosen (ISO-8601)", ) category_chosen = Column( "category_chosen", String(length=len("medium")), comment="Category chosen: high (QoL > 1) " "medium (0 <= QoL <= 1) low (QoL < 0)", ) gamble_fixed_option = Column( "gamble_fixed_option", String(length=len("current")), comment="Fixed option in gamble (current, healthy, dead)", ) gamble_lottery_option_p = Column( "gamble_lottery_option_p", String(length=len("current")), comment="Gamble: option corresponding to p " "(current, healthy, dead)", ) gamble_lottery_option_q = Column( "gamble_lottery_option_q", String(length=len("current")), comment="Gamble: option corresponding to q " "(current, healthy, dead) (q = 1 - p)", ) gamble_lottery_on_left = CamcopsColumn( "gamble_lottery_on_left", Integer, permitted_value_checker=BIT_CHECKER, comment="Gamble: lottery shown on the left (0 no, 1 yes)", ) gamble_starting_p = CamcopsColumn( "gamble_starting_p", Float, permitted_value_checker=ZERO_TO_ONE_CHECKER, comment="Gamble: starting value of p", ) gamble_start_time = Column( "gamble_start_time", PendulumDateTimeAsIsoTextColType, comment="Time gamble was offered (ISO-8601)", ) gamble_responded = CamcopsColumn( "gamble_responded", Integer, permitted_value_checker=BIT_CHECKER, comment="Gamble was responded to? (0 no, 1 yes)", ) gamble_response_time = Column( "gamble_response_time", PendulumDateTimeAsIsoTextColType, comment="Time subject responded to gamble (ISO-8601)", ) gamble_p = CamcopsColumn( "gamble_p", Float, permitted_value_checker=ZERO_TO_ONE_CHECKER, comment="Final value of p", ) utility = Column("utility", Float, comment="Calculated utility, h") @staticmethod def longname(req: "CamcopsRequest") -> str: _ = req.gettext return _("Quality of Life: Standard Gamble") def get_trackers(self, req: CamcopsRequest) -> List[TrackerInfo]: return [ TrackerInfo( value=self.utility, plot_label="Quality of life: standard gamble", axis_label="QoL (0-1)", axis_min=0, axis_max=1, ) ] def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]: if not self.is_complete(): return CTV_INCOMPLETE return [ CtvInfo( content=f"Quality of life: {ws.number_to_dp(self.utility, DP)}" ) ] def is_complete(self) -> bool: return self.utility is not None and self.field_contents_valid() def get_task_html(self, req: CamcopsRequest) -> str: h = f""" <div class="{CssClass.SUMMARY}"> <table class="{CssClass.SUMMARY}"> {self.get_is_complete_tr(req)} {tr_qa("Utility", ws.number_to_dp(self.utility, DP, default=None))} </table> </div> <div class="{CssClass.EXPLANATION}"> Quality of life (QoL) has anchor values of 0 (none) and 1 (perfect health). The Standard Gamble offers a trade-off to determine utility (QoL). Values <0 and >1 are possible with some gambles. </div> <table class="{CssClass.TASKDETAIL}"> <tr><th width="50%">Measure</th><th width="50%">Value</th></tr> """ h += tr_qa("Category choice: start time", self.category_start_time) h += tr_qa( "Category choice: responded?", get_yes_no_none(req, self.category_responded), ) h += tr_qa( "Category choice: response time", self.category_response_time ) h += tr_qa("Category choice: category chosen", self.category_chosen) h += tr_qa("Gamble: fixed option", self.gamble_fixed_option) h += tr_qa( "Gamble: lottery option for <i>p</i>", self.gamble_lottery_option_p ) h += tr_qa( "Gamble: lottery option for <i>q</i> = 1 – <i>p</i>", self.gamble_lottery_option_q, ) h += tr_qa( "Gamble: lottery on left?", get_yes_no_none(req, self.gamble_lottery_on_left), ) h += tr_qa("Gamble: starting <i>p</i>", self.gamble_starting_p) h += tr_qa("Gamble: start time", self.gamble_start_time) h += tr_qa( "Gamble: responded?", get_yes_no_none(req, self.gamble_responded) ) h += tr_qa("Gamble: response time", self.gamble_response_time) h += tr_qa( "Gamble: <i>p</i>", ws.number_to_dp(self.gamble_p, DP, default=None), ) h += tr_qa( "Calculated utility", ws.number_to_dp(self.utility, DP, default=None), ) h += """ </table> """ return h def get_snomed_codes(self, req: CamcopsRequest) -> List[SnomedExpression]: if not self.is_complete(): return [] return [SnomedExpression(req.snomed(SnomedLookup.QOL_SCALE))]
class ReceiptHeader(Base): __tablename__ = "receipt_header_tbl" __table_args__ = {'schema': 'apps'} receipt_header_id = Column('receipt_header_id', Integer, Sequence('receipt_header_sequence', schema='apps'), primary_key=True) receipt_number = Column('receipt_number', String) challan_number = Column('challan_number', String) receipt_date = Column('receipt_date', DateTime) challan_date = Column('challan_date', DateTime) source_transaction_header_id = Column('source_transaction_header_id', String) source_transaction_type = Column('source_transaction_type', String) vehicle_number = Column('vehicle_number', String) bata = Column('bata', Float) net_weight = Column('net_weight', Float) average_weight = Column('average_weight', Float) total_bags = Column('total_bags', Float) unit_of_measure = Column('unit_of_measure', String, default='KG') created_by = Column('created_by', Integer) creation_date = Column('creation_date', DateTime, default=datetime.datetime.utcnow) last_update_date = Column('last_update_date', DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow) last_updated_by = Column('last_updated_by', Integer) receipt_header_status = Column('receipt_header_status', String) receipt_lines = relationship('model.ReceiptLines.ReceiptLines', back_populates='receipt_header')
class Video(CocoBase): __tablename__ = 'videos' id = Column(Integer, primary_key=True, doc='unique internal id') name = Column(String(256), nullable=False, index=True, unique=True) caption = Column(String(256), nullable=True) foreign = Column(JSON)
class SnapLog(BaseModel): id = Column(Integer, primary_key=True, autoincrement=True) graph_id = Column( String(128), ForeignKey(f"{SNAPFLOW_METADATA_TABLE_PREFIX}graph_metadata.hash"), nullable=False, ) node_key = Column(String(128), nullable=False) node_start_state = Column(JSON, nullable=True) node_end_state = Column(JSON, nullable=True) snap_key = Column(String(128), nullable=False) snap_params = Column(JSON, nullable=True) runtime_url = Column(String(128), nullable=True) # TODO queued_at = Column(DateTime, nullable=True) started_at = Column(DateTime, nullable=True) completed_at = Column(DateTime, nullable=True) error = Column(JSON, nullable=True) data_block_logs: RelationshipProperty = relationship( "DataBlockLog", backref="snap_log" ) graph: "GraphMetadata" def __repr__(self): return self._repr( id=self.id, graph_id=self.graph_id, node_key=self.node_key, snap_key=self.snap_key, runtime_url=self.runtime_url, started_at=self.started_at, ) def output_data_blocks(self) -> Iterable[DataBlockMetadata]: return [ dbl for dbl in self.data_block_logs if dbl.direction == Direction.OUTPUT ] def input_data_blocks(self) -> Iterable[DataBlockMetadata]: return [dbl for dbl in self.data_block_logs if dbl.direction == Direction.INPUT] def set_error(self, e: Exception): tback = traceback.format_exc() # Traceback can be v large (like in max recursion), so we truncate to 5k chars self.error = {"error": str(e) or type(e).__name__, "traceback": tback[:5000]} def persist_state(self, env: Environment) -> NodeState: state = env.md_api.execute( select(NodeState).filter(NodeState.node_key == self.node_key) ).scalar_one_or_none() if state is None: state = NodeState(node_key=self.node_key) env.md_api.add(state) state.state = self.node_end_state env.md_api.flush([state]) return state
class Ciwa(TaskHasPatientMixin, TaskHasClinicianMixin, Task, metaclass=CiwaMetaclass): """ Server implementation of the CIWA-Ar task. """ __tablename__ = "ciwa" shortname = "CIWA-Ar" longname = ("Clinical Institute Withdrawal Assessment for Alcohol " "Scale, Revised") provides_trackers = True NSCOREDQUESTIONS = 10 SCORED_QUESTIONS = strseq("q", 1, NSCOREDQUESTIONS) q10 = CamcopsColumn( "q10", Integer, permitted_value_checker=PermittedValueChecker(minimum=0, maximum=4), comment="Q10, orientation/clouding of sensorium (0-4, higher worse)") t = Column("t", Float, comment="Temperature (degrees C)") hr = CamcopsColumn("hr", Integer, permitted_value_checker=MIN_ZERO_CHECKER, comment="Heart rate (beats/minute)") sbp = CamcopsColumn("sbp", Integer, permitted_value_checker=MIN_ZERO_CHECKER, comment="Systolic blood pressure (mmHg)") dbp = CamcopsColumn("dbp", Integer, permitted_value_checker=MIN_ZERO_CHECKER, comment="Diastolic blood pressure (mmHg)") rr = CamcopsColumn("rr", Integer, permitted_value_checker=MIN_ZERO_CHECKER, comment="Respiratory rate (breaths/minute)") MAX_SCORE = 67 def get_trackers(self, req: CamcopsRequest) -> List[TrackerInfo]: return [ TrackerInfo(value=self.total_score(), plot_label="CIWA total score", axis_label="Total score (out of {})".format( self.MAX_SCORE), axis_min=-0.5, axis_max=self.MAX_SCORE + 0.5, horizontal_lines=[14.5, 7.5], horizontal_labels=[ TrackerLabel(17, req.wappstring("severe")), TrackerLabel(11, req.wappstring("moderate")), TrackerLabel(3.75, req.wappstring("mild")), ]) ] def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]: if not self.is_complete(): return CTV_INCOMPLETE return [ CtvInfo(content="CIWA total score: {}/{}".format( self.total_score(), self.MAX_SCORE)) ] def get_summaries(self, req: CamcopsRequest) -> List[SummaryElement]: return self.standard_task_summary_fields() + [ SummaryElement(name="total", coltype=Integer(), value=self.total_score(), comment="Total score (/{})".format(self.MAX_SCORE)), SummaryElement(name="severity", coltype=SummaryCategoryColType, value=self.severity(req), comment="Likely severity"), ] def is_complete(self) -> bool: return (self.are_all_fields_complete(self.SCORED_QUESTIONS) and self.field_contents_valid()) def total_score(self) -> int: return self.sum_fields(self.SCORED_QUESTIONS) def severity(self, req: CamcopsRequest) -> str: score = self.total_score() if score >= 15: severity = self.wxstring(req, "category_severe") elif score >= 8: severity = self.wxstring(req, "category_moderate") else: severity = self.wxstring(req, "category_mild") return severity def get_task_html(self, req: CamcopsRequest) -> str: score = self.total_score() severity = self.severity(req) answer_dicts_dict = {} for q in self.SCORED_QUESTIONS: d = {None: None} for option in range(0, 8): if option > 4 and q == "q10": continue d[option] = self.wxstring(req, q + "_option" + str(option)) answer_dicts_dict[q] = d q_a = "" for q in range(1, Ciwa.NSCOREDQUESTIONS + 1): q_a += tr_qa( self.wxstring(req, "q" + str(q) + "_s"), get_from_dict(answer_dicts_dict["q" + str(q)], getattr(self, "q" + str(q)))) h = """ <div class="{CssClass.SUMMARY}"> <table class="{CssClass.SUMMARY}"> {tr_is_complete} {total_score} {severity} </table> </div> <table class="{CssClass.TASKDETAIL}"> <tr> <th width="35%">Question</th> <th width="65%">Answer</th> </tr> {q_a} {subhead_vitals} {t} {hr} {bp} {rr} </table> <div class="{CssClass.FOOTNOTES}"> [1] Total score ≥15 severe, ≥8 moderate, otherwise mild/minimal. </div> """.format( CssClass=CssClass, tr_is_complete=self.get_is_complete_tr(req), total_score=tr(req.wappstring("total_score"), answer(score) + " / {}".format(self.MAX_SCORE)), severity=tr_qa( self.wxstring(req, "severity") + " <sup>[1]</sup>", severity), q_a=q_a, subhead_vitals=subheading_spanning_two_columns( self.wxstring(req, "vitals_title")), t=tr_qa(self.wxstring(req, "t"), self.t), hr=tr_qa(self.wxstring(req, "hr"), self.hr), bp=tr(self.wxstring(req, "bp"), answer(self.sbp) + " / " + answer(self.dbp)), rr=tr_qa(self.wxstring(req, "rr"), self.rr), ) return h def get_snomed_codes(self, req: CamcopsRequest) -> List[SnomedExpression]: codes = [ SnomedExpression( req.snomed(SnomedLookup.CIWA_AR_PROCEDURE_ASSESSMENT)) ] # noqa if self.is_complete(): codes.append( SnomedExpression(req.snomed(SnomedLookup.CIWA_AR_SCALE), { req.snomed(SnomedLookup.CIWA_AR_SCORE): self.total_score(), })) return codes
""" Database model for the JobScript resource. """ from sqlalchemy import DateTime, ForeignKey, Integer, String, Table from sqlalchemy.sql import func from sqlalchemy.sql.schema import Column from jobbergate_api.metadata import metadata job_scripts_table = Table( "job_scripts", metadata, Column("id", Integer, primary_key=True), Column("job_script_name", String, nullable=False, index=True), Column("job_script_description", String, default=""), Column("job_script_data_as_string", String, nullable=False), Column("job_script_owner_email", String, nullable=False, index=True), Column("application_id", ForeignKey("applications.id")), Column("created_at", DateTime, nullable=False, default=func.now()), Column("updated_at", DateTime, nullable=False, default=func.now(), onupdate=func.now()), ) searchable_fields = [ job_scripts_table.c.job_script_name, job_scripts_table.c.job_script_description, job_scripts_table.c.job_script_owner_email, ]
class Vehicle(declarative_base()): __tablename__ = 'vehicles' __table_args__ = ( PrimaryKeyConstraint('country', 'vehicle_id', 'licence'), ) country = Column(String(4)) vehicle_id = Column(String(255)) licence = Column(String(255)) make = Column(String(255)) model = Column(String(255)) type = Column(String(255)) trim = Column(String(255)) colour = Column(String(255)) bodytype = Column(String(255)) fueltype = Column(String(255)) engine_capacity = Column(String(255)) engine_power = Column(String(255)) cylindercapacity = Column(String(255)) horsepower = Column(String(255)) geartype = Column(String(255)) number_of_gears = Column(String(255)) emission_class = Column(String(255)) emission_class_incl_co2 = Column(String(255)) co2_level_combined = Column(String(255)) segmentation = Column(String(255)) number_of_doors = Column(String(255)) number_of_seats = Column(String(255)) milage = Column(String(255)) age = Column(String(255)) firstuse = Column(String(255)) build_year = Column(String(255)) amount_damage = Column(String(255)) price_class = Column(String(255)) has_air_conditioning = Column(String(255)) has_air_conditioning_automatic = Column(String(255)) has_alloy_wheels = Column(String(255)) has_automatic_transmission = Column(String(255)) has_cruise_control = Column(String(255)) has_heated_seats = Column(String(255)) has_leather_alcantara = Column(String(255)) has_leather_upholstery = Column(String(255)) amount_damage_norm = Column(Numeric(10, 9)) @classmethod def create_topx(cls, top: int = 10, filter_on_year: int = 2016) -> sase.select: rank_avg_dmg_year = sase.select([ cls.country, cls.make, cls.model, sase.func.avg(cls.amount_damage_norm).label("avg_dmg"), sase.func.rank().over( partition_by=cls.country, order_by=sase.func.avg(cls.amount_damage_norm).desc() ).label("rnk")]) \ .where(cls.build_year == str(filter_on_year)) \ .where(cls.make != "") \ .where(cls.model != "") \ .where(cls.amount_damage_norm != None) \ .group_by( cls.country, cls.make, cls.model ).alias("rank_dmg") return sase.select(rank_avg_dmg_year.columns).where(rank_avg_dmg_year.c.rnk <= top).alias("top_x") @classmethod def normalize_amount_damage(cls) -> sase.Update: """ Apply feature normalization on the amount_damage in the table. :return: A sql statement to update the amount_damage_norm column with normalized amount_damage per country/car """ # First compute the minimum and maximum amount damage per country min_max = sase.select([ cls.country, sase.case([(sase.func.max(sase.cast(cls.amount_damage, Numeric(14, 2))) == 0, 1)], else_=sase.func.max(sase.cast(cls.amount_damage, Numeric(14, 2)))).label("max_dmg"), sase.func.min(sase.cast(cls.amount_damage, Numeric(14, 2))).label("min_dmg") ]).group_by(cls.country).alias("min_max") # Second, use the min and max damage to normalize the damage per car per country and store in separate column norm = sase.update(cls). \ where(min_max.c.country == cls.country). \ values(amount_damage_norm=( (sase.cast(cls.amount_damage, Numeric(14, 2)) - min_max.c.min_dmg) / (sase.case([(min_max.c.max_dmg == 0, 1)], else_=min_max.c.max_dmg) - min_max.c.min_dmg) )) return norm @classmethod def nr_of_rows(cls): return sase.select([sase.func.count()]).select_from(cls) @classmethod def null_empty_string(cls, session: Type[sessionmaker], field: Type[Any] = amount_damage) -> None: """ Fields to be case to Numeric need to be NULL first instead of an empty string because CAST works differently underwater in SELECT than it does in UPDATE queries. The UPDATE query raises a "Incorrect DECIMAL value: '0' for column '' at row -1" error This update uses ORM to immediately run query against the passed session :param session: sqlalchemy session object to talk to the database :param field: Field that needs to NULLed :return: None """ session.query(cls).filter(field == "").update({field: sase.null()}, synchronize_session=False) @classmethod def sanitize_build_year(cls) -> sase.Update: """ Query to update build_year with the year in firstuse if build_year is lower than 1940 and higher than 2020. A quick scna of the data showed that 1940 is approximately the lowest build_year found that looks reasonable compared with firstuse. Somewhere it showed that the data files were created in 2018, therefore 2020 is a bit optimistic. All "years" that fall outside of this range are overwritten with the year of firstuse. If firstuse has a diverging year that is not further remedied because there is not anything to quickly test or check against. :return: A sql statement to update the build_year column with the firstuse year """ stmt = sase.update(cls).prefix_with("IGNORE").where(sase.or_( sase.cast(cls.build_year, Integer) < constants.MIN_YEAR, sase.cast(cls.build_year, Integer) > constants.MAX_YEAR) ).values( build_year=sase.cast(sase.extract('year', sase.cast(cls.firstuse, Date)), String) ) return stmt
class Mater(declarative_base()): __tablename__ = 'mater' __table_args__ = ( PrimaryKeyConstraint('country', 'vehicle_id', 'licence'), ) country = Column(String(4)) vehicle_id = Column(String(255)) licence = Column(String(255)) col04 = Column(String(255)) col05 = Column(String(255)) col06 = Column(String(255)) col07 = Column(String(255)) col08 = Column(String(255)) col09 = Column(String(255)) col10 = Column(String(255)) col11 = Column(String(255)) col12 = Column(String(255)) col13 = Column(String(255)) col14 = Column(String(255)) col15 = Column(String(255)) col16 = Column(String(255)) col17 = Column(String(255)) col18 = Column(String(255)) col19 = Column(String(255)) col20 = Column(String(255)) col21 = Column(String(255)) col22 = Column(String(255)) col23 = Column(String(255)) col24 = Column(String(255)) col25 = Column(String(255)) col26 = Column(String(255)) col27 = Column(String(255)) col28 = Column(String(255)) col29 = Column(String(255)) col30 = Column(String(255)) col31 = Column(String(255)) col32 = Column(String(255)) col33 = Column(String(255)) col34 = Column(String(255)) col35 = Column(String(255)) col36 = Column(String(255)) col37 = Column(String(255)) col38 = Column(String(255)) col39 = Column(String(255)) col40 = Column(String(255))
class GMCPQ(Task): """ Server implementation of the GMC-PQ task. """ __tablename__ = "gmcpq" shortname = "GMC-PQ" longname = "GMC Patient Questionnaire" RATING_TEXT = " (1 poor - 5 very good, 0 does not apply)" AGREE_TEXT = " (1 strongly disagree - 5 strongly agree, 0 does not apply)" doctor = Column("doctor", UnicodeText, comment="Doctor's name") q1 = CamcopsColumn("q1", Integer, permitted_value_checker=PermittedValueChecker( minimum=1, maximum=4), comment="Filling in questionnaire for... (1 yourself, " "2 child, 3 spouse/partner, 4 other relative/friend)") q2a = CamcopsColumn("q2a", Integer, permitted_value_checker=BIT_CHECKER, comment="Reason: advice? (0 no, 1 yes)") q2b = CamcopsColumn("q2b", Integer, permitted_value_checker=BIT_CHECKER, comment="Reason: one-off problem? (0 no, 1 yes)") q2c = CamcopsColumn("q2c", Integer, permitted_value_checker=BIT_CHECKER, comment="Reason: ongoing problem? (0 no, 1 yes)") q2d = CamcopsColumn("q2d", Integer, permitted_value_checker=BIT_CHECKER, comment="Reason: routine check? (0 no, 1 yes)") q2e = CamcopsColumn("q2e", Integer, permitted_value_checker=BIT_CHECKER, comment="Reason: treatment? (0 no, 1 yes)") q2f = CamcopsColumn("q2f", Integer, permitted_value_checker=BIT_CHECKER, comment="Reason: other? (0 no, 1 yes)") q2f_details = Column("q2f_details", UnicodeText, comment="Reason, other, details") q3 = CamcopsColumn( "q3", Integer, permitted_value_checker=ONE_TO_FIVE_CHECKER, comment="How important to health/wellbeing was the reason " "(1 not very - 5 very)") q4a = CamcopsColumn("q4a", Integer, permitted_value_checker=ZERO_TO_FIVE_CHECKER, comment="How good: being polite" + RATING_TEXT) q4b = CamcopsColumn("q4b", Integer, permitted_value_checker=ZERO_TO_FIVE_CHECKER, comment="How good: making you feel at ease" + RATING_TEXT) q4c = CamcopsColumn("q4c", Integer, permitted_value_checker=ZERO_TO_FIVE_CHECKER, comment="How good: listening" + RATING_TEXT) q4d = CamcopsColumn("q4d", Integer, permitted_value_checker=ZERO_TO_FIVE_CHECKER, comment="How good: assessing medical condition" + RATING_TEXT) q4e = CamcopsColumn("q4e", Integer, permitted_value_checker=ZERO_TO_FIVE_CHECKER, comment="How good: explaining" + RATING_TEXT) q4f = CamcopsColumn("q4f", Integer, permitted_value_checker=ZERO_TO_FIVE_CHECKER, comment="How good: involving you in decisions" + RATING_TEXT) q4g = CamcopsColumn("q4g", Integer, permitted_value_checker=ZERO_TO_FIVE_CHECKER, comment="How good: providing/arranging treatment" + RATING_TEXT) q5a = CamcopsColumn("q5a", Integer, permitted_value_checker=ZERO_TO_FIVE_CHECKER, comment="Agree/disagree: will keep info confidential" + AGREE_TEXT) q5b = CamcopsColumn("q5b", Integer, permitted_value_checker=ZERO_TO_FIVE_CHECKER, comment="Agree/disagree: honest/trustworthy" + AGREE_TEXT) q6 = CamcopsColumn( "q6", Integer, permitted_value_checker=BIT_CHECKER, comment="Confident in doctor's ability to provide care (0 no, 1 yes)") q7 = CamcopsColumn( "q7", Integer, permitted_value_checker=BIT_CHECKER, comment="Would be completely happy to see this doctor again " "(0 no, 1 yes)") q8 = CamcopsColumn( "q8", Integer, permitted_value_checker=BIT_CHECKER, comment="Was this visit with your usual doctor (0 no, 1 yes)") q9 = Column("q9", UnicodeText, comment="Other comments") q10 = CamcopsColumn("q10", SexColType, permitted_value_checker=PermittedValueChecker( permitted_values=["M", "F"]), comment="Sex of rater (M, F)") q11 = CamcopsColumn( "q11", Integer, permitted_value_checker=ONE_TO_FIVE_CHECKER, comment="Age (1 = under 15, 2 = 15-20, 3 = 21-40, " "4 = 40-60, 5 = 60 or over" # yes, I know it's daft ) q12 = CamcopsColumn( "q12", Integer, permitted_value_checker=PermittedValueChecker(minimum=1, maximum=16), comment="Ethnicity (1 = White British, 2 = White Irish, " "3 = White other, 4 = Mixed W/B Caribbean, " "5 = Mixed W/B African, 6 = Mixed W/Asian, 7 = Mixed other, " "8 = Asian/Asian British - Indian, 9 = A/AB - Pakistani, " "10 = A/AB - Bangladeshi, 11 = A/AB - other, " "12 = Black/Black British - Caribbean, 13 = B/BB - African, " "14 = B/BB - other, 15 = Chinese, 16 = other)") q12_details = Column("q12_details", UnicodeText, comment="Ethnic group, other, details") def is_complete(self) -> bool: return ( self.is_field_complete("q1") and self.is_field_complete("q3") and self.is_field_complete("q4a") and self.is_field_complete("q4b") and self.is_field_complete("q4c") and self.is_field_complete("q4d") and self.is_field_complete("q4e") and self.is_field_complete("q4f") and self.is_field_complete("q4g") and self.is_field_complete("q5a") and self.is_field_complete("q5b") and self.is_field_complete("q6") and self.is_field_complete("q7") and self.is_field_complete("q8") and self.field_contents_valid()) def get_task_html(self, req: CamcopsRequest) -> str: dict_q1 = {None: None} dict_q3 = {None: None} dict_q4 = {None: None} dict_q5 = {None: None} dict_q11 = {None: None} dict_q12 = {None: None} for option in range(1, 5): dict_q1[option] = self.wxstring(req, "q1_option" + str(option)) for option in range(1, 6): dict_q3[option] = self.wxstring(req, "q3_option" + str(option)) dict_q11[option] = self.wxstring(req, "q11_option" + str(option)) for option in range(0, 6): prefix = str(option) + " – " if option > 0 else "" dict_q4[option] = prefix + self.wxstring(req, "q4_option" + str(option)) dict_q5[option] = prefix + self.wxstring(req, "q5_option" + str(option)) for option in range(1, 17): dict_q12[option] = self.wxstring(req, "ethnicity_option" + str(option)) h = """ <div class="{CssClass.SUMMARY}"> <table class="{CssClass.SUMMARY}"> {tr_is_complete} </table> </div> <table class="{CssClass.TASKDETAIL}"> <tr> <th width="60%">Question</th> <th width="40%">Answer</th> </tr> """.format( CssClass=CssClass, tr_is_complete=self.get_is_complete_tr(req), ) ell = "… " # horizontal ellipsis sep_row = subheading_spanning_two_columns("<br>") blank_cell = td("", td_class=CssClass.SUBHEADING) h += tr_qa(self.wxstring(req, "q_doctor"), ws.webify(self.doctor)) h += sep_row h += tr_qa(self.wxstring(req, "q1"), get_from_dict(dict_q1, self.q1)) h += tr(td(self.wxstring(req, "q2")), blank_cell, literal=True) h += tr_qa(ell + self.wxstring(req, "q2_a"), get_yes_no_none(req, self.q2a), default="") h += tr_qa(ell + self.wxstring(req, "q2_b"), get_yes_no_none(req, self.q2b), default="") h += tr_qa(ell + self.wxstring(req, "q2_c"), get_yes_no_none(req, self.q2c), default="") h += tr_qa(ell + self.wxstring(req, "q2_d"), get_yes_no_none(req, self.q2d), default="") h += tr_qa(ell + self.wxstring(req, "q2_e"), get_yes_no_none(req, self.q2e), default="") h += tr_qa(ell + self.wxstring(req, "q2_f"), get_yes_no_none(req, self.q2f), default="") h += tr_qa(ell + ell + self.wxstring(req, "q2f_s"), ws.webify(self.q2f_details)) h += tr_qa(self.wxstring(req, "q3"), get_from_dict(dict_q3, self.q3)) h += tr(td(self.wxstring(req, "q4")), blank_cell, literal=True) h += tr_qa(ell + self.wxstring(req, "q4_a"), get_from_dict(dict_q4, self.q4a)) h += tr_qa(ell + self.wxstring(req, "q4_b"), get_from_dict(dict_q4, self.q4b)) h += tr_qa(ell + self.wxstring(req, "q4_c"), get_from_dict(dict_q4, self.q4c)) h += tr_qa(ell + self.wxstring(req, "q4_d"), get_from_dict(dict_q4, self.q4d)) h += tr_qa(ell + self.wxstring(req, "q4_e"), get_from_dict(dict_q4, self.q4e)) h += tr_qa(ell + self.wxstring(req, "q4_f"), get_from_dict(dict_q4, self.q4f)) h += tr_qa(ell + self.wxstring(req, "q4_g"), get_from_dict(dict_q4, self.q4g)) h += tr(td(self.wxstring(req, "q5")), blank_cell, literal=True) h += tr_qa(ell + self.wxstring(req, "q5_a"), get_from_dict(dict_q5, self.q5a)) h += tr_qa(ell + self.wxstring(req, "q5_b"), get_from_dict(dict_q5, self.q5b)) h += tr_qa(self.wxstring(req, "q6"), get_yes_no_none(req, self.q6)) h += tr_qa(self.wxstring(req, "q7"), get_yes_no_none(req, self.q7)) h += tr_qa(self.wxstring(req, "q8"), get_yes_no_none(req, self.q8)) h += tr_qa(self.wxstring(req, "q9_s"), ws.webify(self.q9)) h += sep_row h += tr_qa(req.wappstring("sex"), ws.webify(self.q10)) h += tr_qa(self.wxstring(req, "q11"), get_from_dict(dict_q11, self.q11)) h += tr_qa(self.wxstring(req, "q12"), get_from_dict(dict_q12, self.q12)) h += tr_qa(ell + self.wxstring(req, "ethnicity_other_s"), ws.webify(self.q12_details)) h += """ </table> """ return h
class PeriodicTask(GenericTable): __tablename__ = "periodictasks" id = Column(Integer, primary_key=True) name = Column(String(100), nullable=False) task = Column(String(100), nullable=False) enabled = Column(Boolean, nullable=False, default=True) crontab_minute = Column(String(20), nullable=False, default="*") crontab_hour = Column(String(20), nullable=False, default="*") crontab_day_of_week = Column(String(20), nullable=False, default="*") crontab_day_of_month = Column(String(20), nullable=False, default="*") crontab_month_of_year = Column(String(20), nullable=False, default="*") last_run_at = Column(DateTime(timezone=True), nullable=True) args = Column(JSONType, nullable=False, default=[]) kwargs = Column(JSONType, nullable=False, default={}) @property def is_run_action(self) -> bool: return self.task == "pyfaf.celery_tasks.run_action" @property def args_parsed(self): return self._foo @property def nice_name(self): return self.name @property def nice_task(self) -> str: if self.is_run_action and self.args: return "Action {0}".format(self.args[0]) return self.task
class Person (Base): __tablename__ = "person_tbl" __table_args__ = {'schema' : 'apps'} person_id = Column('person_id', Integer, Sequence('person_id_sequence', schema='apps') , primary_key = True) employee_number = Column('employee_number', String) first_name = Column('first_name', String) middle_name = Column('middle_name', String) last_name = Column('last_name', String) date_of_birth = Column('date_of_birth', Date) gender = Column('gender', String) address = Column('address', String) phone_number1 = Column('phone_number1', String) phone_number2 = Column('phone_number2', String) email = Column('email', String) effective_from = Column('effective_from', DateTime) effective_to = Column('effective_to', DateTime) created_by = Column('created_by', Integer) creation_date = Column('creation_date', DateTime) last_updated_by = Column('last_updated_by', Integer) last_update_date = Column('last_update_date', DateTime)
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ from sqlalchemy.sql.schema import Column, Table from sqlalchemy.sql.sqltypes import Integer, String from heliotrope.database.orm.base import mapper_registry galleryinfo_table = Table( "galleryinfo", mapper_registry.metadata, Column("id", Integer, primary_key=True, nullable=False), Column("type", String, nullable=False), # title Column("title", String, nullable=False), Column("japanese_title", String), # video Column("video", String), Column("videofilename", String), # language Column("language_url", String), Column("language_localname", String, nullable=False), Column("language", String, nullable=False), Column("date", String, nullable=False), )
from sqlalchemy.sql.schema import Column, ForeignKey, MetaData, Table from sqlalchemy.sql.sqltypes import Date, Integer, String metadata = MetaData() users_table = Table( "users", metadata, Column("id", Integer, primary_key=True, autoincrement=True), Column("email", String(255)), Column("password", String(255)), ) projects_table = Table( "projects", metadata, Column("id", Integer, primary_key=True, autoincrement=True), Column("user_id", Integer, ForeignKey("users.id")), Column("name", String(255)), Column("max_incomplete_tasks_number", Integer), ) tasks_table = Table( "tasks", metadata, Column("id", Integer, primary_key=True, autoincrement=True), Column("project_id", Integer, ForeignKey("projects.id")), Column("name", String(255)), Column("completed_at", Date, nullable=True), )
class KernelModule(GenericTable): __tablename__ = "kernelmodules" id = Column(Integer, primary_key=True) name = Column(String(64), nullable=False, unique=True, index=True)
class Connection(db.Model): __tablename__ = 'connections' id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String) configFile = Column(String, name='config_path') config = Column(BLOB) active = Column(Boolean, default=False) processesList = relationship('Process', backref='parentConnection') def href(self): return url_for('connectionsapi0.connectionsapi', instid=self.id) def processes(self): return [url_for('processesapi0.processesapi', instid=processUrl.pid) for processUrl in self.processesList] def files(self): return [{'name': path.basename(filename[1]), 'href': url_for('getFile', connection_id=self.id, file_id=filename[0])} for filename in self.attachments()] def attachments(self): workDir = path.join(path.abspath(app.config['WORK_DIR']), self.workingDir()) if not path.exists(workDir): os.mkdir(workDir) filenames = [filename for (_, _, filename) in walk(workDir)] if filenames: return [(hashlib.md5(filename).hexdigest(), path.join(workDir, filename)) for filename in filenames[0]] else: return [] def disconnect(self): self.active = False db.session.add(self) db.session.commit() for process in [process for process in self.processesList if 1 == process.status()]: process.stop() def getFreePort(self): s = socket.socket() s.bind(('', 0)) port = s.getsockname()[1] s.close() return port def connect(self): configFile = self.configFileAbsPath() socketPath = path.join(path.abspath(app.config['WORK_DIR']), self.workingDir(), "openvpn.sock") options = [ "openvpn", "--management", socketPath, "unix", "--lport", str(self.getFreePort()), "--config", self.configFileAbsPath() ] if "passwd-tls" == self.configuration()["auth"]: options.append("--management-query-passwords") options.append("2>&1 > %s & echo $!" % path.join(path.abspath(app.config['WORK_DIR']), self.workingDir(), "openvpn.out")) management = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) processEntity = Process() # try: process = subprocess.Popen(" ".join(options), cwd=os.path.dirname(configFile), shell=True, stdout=subprocess.PIPE, bufsize=1) processEntity.pid = int(process.stdout.readline()) processEntity.connectionId = self.id self.active = True db.session.add(self) db.session.add(processEntity) db.session.commit() connect_try = 1 while 1 == processEntity.status() and connect_try < 5: try: connect_try += 1 management.connect(socketPath) if "passwd-tls" == self.configuration()["auth"]: management.sendall("username 'Auth' '%s'\r\n" % self.configuration()["user"]) management.sendall("password 'Auth' '%s'\r\n" % self.configuration()["password"]) management.sendall("quit\r\n") break except socket.error, e: if e.errno in [111]: time.sleep(.5) else: raise e return processEntity.pid
class ContactEmail(GenericTable): __tablename__ = "contactemails" id = Column(Integer, primary_key=True) email_address = Column(String(128), nullable=False)
from sqlalchemy.sql.sqltypes import DateTime, Integer, String from models.team import Team class User: def __init__(self, name: str, age: int, team: Team) -> None: self.name = name self.age = age self.team = team self.created_at = datetime.now() user_table = Table( "users", metadata, Column("id", Integer, nullable=False, primary_key=True, autoincrement=True), Column("name", String(100), nullable=False), Column("age", Integer, nullable=False), Column("team_id", ForeignKey("teams.id"), nullable=False), Column("created_at", DateTime, nullable=False)) mapper(User, user_table, properties={ "id": user_table.c.id, "name": user_table.c.name, "age": user_table.c.age, "team": relationship(Team), "created_at": user_table.c.created_at }) User.__table__ = user_table
class Slums(TaskHasClinicianMixin, TaskHasPatientMixin, Task): """ Server implementation of the SLUMS task. """ __tablename__ = "slums" shortname = "SLUMS" longname = "St Louis University Mental Status" provides_trackers = True alert = CamcopsColumn("alert", Integer, permitted_value_checker=BIT_CHECKER, comment="Is the patient alert? (0 no, 1 yes)") highschooleducation = CamcopsColumn( "highschooleducation", Integer, permitted_value_checker=BIT_CHECKER, comment="Does that patient have at least a high-school level of " "education? (0 no, 1 yes)") q1 = CamcopsColumn("q1", Integer, permitted_value_checker=BIT_CHECKER, comment="Q1 (day) (0-1)") q2 = CamcopsColumn("q2", Integer, permitted_value_checker=BIT_CHECKER, comment="Q2 (year) (0-1)") q3 = CamcopsColumn("q3", Integer, permitted_value_checker=BIT_CHECKER, comment="Q3 (state) (0-1)") q5a = CamcopsColumn("q5a", Integer, permitted_value_checker=BIT_CHECKER, comment="Q5a (money spent) (0-1)") q5b = CamcopsColumn("q5b", Integer, permitted_value_checker=ZERO_OR_TWO_CHECKER, comment="Q5b (money left) (0 or 2)") # worth 2 points q6 = CamcopsColumn( "q6", Integer, permitted_value_checker=ZERO_TO_THREE_CHECKER, comment="Q6 (animal naming) (0-3)") # from 0 to 3 points q7a = CamcopsColumn("q7a", Integer, permitted_value_checker=BIT_CHECKER, comment="Q7a (recall apple) (0-1)") q7b = CamcopsColumn("q7b", Integer, permitted_value_checker=BIT_CHECKER, comment="Q7b (recall pen) (0-1)") q7c = CamcopsColumn("q7c", Integer, permitted_value_checker=BIT_CHECKER, comment="Q7c (recall tie) (0-1)") q7d = CamcopsColumn("q7d", Integer, permitted_value_checker=BIT_CHECKER, comment="Q7d (recall house) (0-1)") q7e = CamcopsColumn("q7e", Integer, permitted_value_checker=BIT_CHECKER, comment="Q7e (recall car) (0-1)") q8b = CamcopsColumn("q8b", Integer, permitted_value_checker=BIT_CHECKER, comment="Q8b (reverse 648) (0-1)") q8c = CamcopsColumn("q8c", Integer, permitted_value_checker=BIT_CHECKER, comment="Q8c (reverse 8537) (0-1)") q9a = CamcopsColumn( "q9a", Integer, permitted_value_checker=ZERO_OR_TWO_CHECKER, comment="Q9a (clock - hour markers) (0 or 2)") # worth 2 points q9b = CamcopsColumn( "q9b", Integer, permitted_value_checker=ZERO_OR_TWO_CHECKER, comment="Q9b (clock - time) (0 or 2)") # worth 2 points q10a = CamcopsColumn("q10a", Integer, permitted_value_checker=BIT_CHECKER, comment="Q10a (X in triangle) (0-1)") q10b = CamcopsColumn("q10b", Integer, permitted_value_checker=BIT_CHECKER, comment="Q10b (biggest figure) (0-1)") q11a = CamcopsColumn( "q11a", Integer, permitted_value_checker=ZERO_OR_TWO_CHECKER, comment="Q11a (story - name) (0 or 2)") # worth 2 points q11b = CamcopsColumn( "q11b", Integer, permitted_value_checker=ZERO_OR_TWO_CHECKER, comment="Q11b (story - occupation) (0 or 2)") # worth 2 points q11c = CamcopsColumn( "q11c", Integer, permitted_value_checker=ZERO_OR_TWO_CHECKER, comment="Q11c (story - back to work) (0 or 2)") # worth 2 points q11d = CamcopsColumn( "q11d", Integer, permitted_value_checker=ZERO_OR_TWO_CHECKER, comment="Q11d (story - state) (0 or 2)") # worth 2 points clockpicture_blobid = CamcopsColumn( "clockpicture_blobid", Integer, is_blob_id_field=True, blob_relationship_attr_name="clockpicture", comment="BLOB ID of clock picture") shapespicture_blobid = CamcopsColumn( "shapespicture_blobid", Integer, is_blob_id_field=True, blob_relationship_attr_name="shapespicture", comment="BLOB ID of shapes picture") comments = Column("comments", UnicodeText, comment="Clinician's comments") clockpicture = blob_relationship( "Slums", "clockpicture_blobid") # type: Optional[Blob] # noqa shapespicture = blob_relationship( "Slums", "shapespicture_blobid") # type: Optional[Blob] # noqa PREAMBLE_FIELDS = ["alert", "highschooleducation"] SCORED_FIELDS = [ "q1", "q2", "q3", "q5a", "q5b", "q6", "q7a", "q7b", "q7c", "q7d", "q7e", "q8b", "q8c", "q9a", "q9b", "q10a", "q10b", "q11a", "q11b", "q11c", "q11d" ] MAX_SCORE = 30 def get_trackers(self, req: CamcopsRequest) -> List[TrackerInfo]: if self.highschooleducation == 1: hlines = [26.5, 20.5] y_upper = 28.25 y_middle = 23.5 else: hlines = [24.5, 19.5] y_upper = 27.25 y_middle = 22 return [ TrackerInfo( value=self.total_score(), plot_label="SLUMS total score", axis_label="Total score (out of {})".format(self.MAX_SCORE), axis_min=-0.5, axis_max=self.MAX_SCORE + 0.5, horizontal_lines=hlines, horizontal_labels=[ TrackerLabel(y_upper, req.wappstring("normal")), TrackerLabel(y_middle, self.wxstring(req, "category_mci")), TrackerLabel(17, self.wxstring(req, "category_dementia")), ]) ] def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]: if not self.is_complete(): return CTV_INCOMPLETE return [ CtvInfo(content="SLUMS total score {}/{} ({})".format( self.total_score(), self.MAX_SCORE, self.category(req))) ] def get_summaries(self, req: CamcopsRequest) -> List[SummaryElement]: return self.standard_task_summary_fields() + [ SummaryElement(name="total", coltype=Integer(), value=self.total_score(), comment="Total score (/{})".format(self.MAX_SCORE)), SummaryElement(name="category", coltype=SummaryCategoryColType, value=self.category(req), comment="Category"), ] def is_complete(self) -> bool: return (self.are_all_fields_complete(self.PREAMBLE_FIELDS + self.SCORED_FIELDS) and self.field_contents_valid()) def total_score(self) -> int: return self.sum_fields(self.SCORED_FIELDS) def category(self, req: CamcopsRequest) -> str: score = self.total_score() if self.highschooleducation == 1: if score >= 27: return req.wappstring("normal") elif score >= 21: return self.wxstring(req, "category_mci") else: return self.wxstring(req, "category_dementia") else: if score >= 25: return req.wappstring("normal") elif score >= 20: return self.wxstring(req, "category_mci") else: return self.wxstring(req, "category_dementia") def get_task_html(self, req: CamcopsRequest) -> str: score = self.total_score() category = self.category(req) h = """ {clinician_comments} <div class="{CssClass.SUMMARY}"> <table class="{CssClass.SUMMARY}"> {tr_is_complete} {total_score} {category} </table> </div> <table class="{CssClass.TASKDETAIL}"> <tr> <th width="80%">Question</th> <th width="20%">Score</th> </tr> """.format( clinician_comments=self.get_standard_clinician_comments_block( req, self.comments), CssClass=CssClass, tr_is_complete=self.get_is_complete_tr(req), total_score=tr(req.wappstring("total_score"), answer(score) + " / {}".format(self.MAX_SCORE)), category=tr_qa( req.wappstring("category") + " <sup>[1]</sup>", category), ) h += tr_qa(self.wxstring(req, "alert_s"), get_yes_no_none(req, self.alert)) h += tr_qa(self.wxstring(req, "highschool_s"), get_yes_no_none(req, self.highschooleducation)) h += tr_qa(self.wxstring(req, "q1_s"), self.q1) h += tr_qa(self.wxstring(req, "q2_s"), self.q2) h += tr_qa(self.wxstring(req, "q3_s"), self.q3) h += tr( "Q5 <sup>[2]</sup> (money spent, money left " "[<i>scores 2</i>]", ", ".join([answer(x) for x in [self.q5a, self.q5b]])) h += tr_qa( "Q6 (animal fluency) [<i>≥15 scores 3, 10–14 scores 2, " "5–9 scores 1, 0–4 scores 0</i>]", self.q6) h += tr( "Q7 (recall: apple, pen, tie, house, car)", ", ".join([ answer(x) for x in [self.q7a, self.q7b, self.q7c, self.q7d, self.q7e] ])) h += tr("Q8 (backwards: 648, 8537)", ", ".join([answer(x) for x in [self.q8b, self.q8c]])) h += tr("Q9 (clock: hour markers, time [<i>score 2 each</i>]", ", ".join([answer(x) for x in [self.q9a, self.q9b]])) h += tr("Q10 (X in triangle; which is biggest?)", ", ".join([answer(x) for x in [self.q10a, self.q10b]])) h += tr( "Q11 (story: Female’s name? Job? When back to work? " "State she lived in? [<i>score 2 each</i>])", ", ".join([ answer(x) for x in [self.q11a, self.q11b, self.q11c, self.q11d] ])) h += """ </table> <table class="{CssClass.TASKDETAIL}"> """.format(CssClass=CssClass) h += subheading_spanning_two_columns("Images of tests: clock, shapes") # noinspection PyTypeChecker h += tr(td(get_blob_img_html(self.clockpicture), td_width="50%", td_class=CssClass.PHOTO), td(get_blob_img_html(self.shapespicture), td_width="50%", td_class=CssClass.PHOTO), literal=True) h += """ </table> <div class="{CssClass.FOOTNOTES}"> [1] With high school education: ≥27 normal, ≥21 MCI, ≤20 dementia. Without high school education: ≥25 normal, ≥20 MCI, ≤19 dementia. (Tariq et al. 2006, PubMed ID 17068312.) [2] Q4 (learning the five words) isn’t scored. </div> """.format(CssClass=CssClass) return h
class Problem(GenericTable): __tablename__ = "problems" id = Column(Integer, primary_key=True) first_occurrence = Column(DateTime) last_occurrence = Column(DateTime) #pylint:disable=E1101 # Class has no '__table__' member components = relationship(OpSysComponent, secondary=ProblemComponent.__table__, order_by=ProblemComponent.order) def to_json(self): return { "id": self.id, "components": self.unique_component_names, "crash_function": self.crash_function, "bugs": [bug.url for bug in self.bugs], "status": self.status, "type": self.type, "reports": self.reports, } @property def unique_component_names(self): return set(c.name for c in self.components) @property def bugs(self): my_bugs = set() for report in self.reports: for bug in report.bugs: my_bugs.add(bug) return my_bugs @property def status(self): bugs = self.bugs if not bugs: return 'NEW' s = sorted(bugs, key=lambda x: x.order())[0].status FIXED = ("NEXTRELEASE", "CURRENTRELEASE", "RAWHIDE", "ERRATA") if s == "CLOSED" and any( (b.status == "CLOSED" and b.resolution in FIXED for b in bugs)): return "FIXED" return s @property def crash_function(self): """ Return the most common crash function among all backtraces of this report """ return most_common_crash_function(self.backtraces) @property def type(self): report = self.reports[0] return report.type @property def reports_count(self): return sum([x.count for x in self.reports]) @property def quality(self): ''' Return quality metric for this problem which equals to the quality of its best report. ''' reps = self.sorted_reports if not reps: return -10000 return self.sorted_reports[0].quality @property def sorted_reports(self): ''' List of all reports assigned to this problem sorted by quality. ''' return sorted(self.reports, key=lambda r: r.quality, reverse=True) @property def active_reports(self): ''' List of all non archived reports ''' return [r for r in self.reports if not r.archived] @property def archived_reports(self): ''' List of archived reports ''' return [r for r in self.reports if r.archived] @property def backtraces(self): ''' List of all backtraces assigned to this problem. ''' return sum([x.backtraces for x in self.reports], []) @property def sorted_backtraces(self): ''' List of all backtraces assigned to this problem sorted by quality. ''' return sorted(self.backtraces, key=lambda bt: bt.quality, reverse=True) @property def comments(self): """ List of all comments assigned to this problem. As the webui only shows first N comments, sort the result so that comments from all reports are included. With 3 reports having 3, 1 and 2 comments, the result would be [reports[0].comment[0], reports[1].comment[0], reports[2].comment[0], reports[0].comment[1], reports[2].comment[1], reports[0].comment[2]] """ result = [] longest = max(len(r.comments) for r in self.reports) i = 0 while i < longest: i += 1 for report in self.reports: if len(report.comments) >= i: result.append(report.comments[i - 1]) return result @property def tainted(self): """ Return True if the problem has only tainted kernel oopses assigned. Only works for kernel oopses, other types are always not tainted. """ return all(report.tainted for report in self.reports) @property def probable_fixes(self): return [ "{0}: {1}".format(osr.opsysrelease, osr.probable_fix) for osr in self.opsysreleases if osr.probable_fix ] @property def probable_fixes_with_dates(self): return [ "{0}: {1}, {2}".format( osr.opsysrelease, osr.probable_fix, osr.probably_fixed_since.strftime("%Y-%m-%d")) for osr in self.opsysreleases if osr.probable_fix ] def probable_fix_for_opsysrelease_ids(self, osr_ids): if len(osr_ids) == 1: for posr in self.opsysreleases: if posr.opsysrelease_id in osr_ids: return posr.probable_fix or "" else: return ", ".join([ "{0}: {1}".format(osr.opsysrelease, osr.probable_fix) for osr in self.opsysreleases if osr.probable_fix and osr.opsysrelease_id in osr_ids ]) return "" @property def urls(self): """ List of list of all ReportURLs assigned to this problem. """ urls = [x for x in [x.urls for x in self.reports] if x] urls.sort(key=lambda x: x[0].saved, reverse=True) return urls
class ExcelData(Base): __tablename__ = 'excel_data' index = Column(Integer, primary_key=True) dato = Column(Date) døde = Column(Integer) skredtatte = Column(Integer) aktivitet = Column(String) utløst = Column(String) sted = Column(String) kommune = Column(String) fylke = Column(String) regobs_regid = Column(Integer) varsom_nyhet_eller_rapport = Column(String) beskrivelse = Column(String) involvert = Column(String) skadet_eller_omkommet = Column(String) totalt_begravd = Column(String) delvis_begravd = Column(String) tatt_men_ikke_begravd = Column(String) nære_på_men_ikke_tatt = Column(String) najonalitet = Column(String) alder = Column(String) skredutstyr = Column(String) middels_til_mye_erfaring = Column(String) type_skred = Column(String) skredstørrelse = Column(Integer) guide = Column(String)
class TaskFilter(Base): """ SQLAlchemy ORM object representing task filter criteria. """ __tablename__ = "_task_filters" # Lots of these could be changed into lists; for example, filtering to # multiple devices, multiple users, multiple text patterns. For # AND-joining, there is little clear benefit (one could always AND-join # multiple filters with SQL). For OR-joining, this is more useful. # - surname: use ID numbers instead; not very likely to have >1 surname # - forename: ditto # - DOB: ditto # - sex: just eliminate the filter if you don't care about sex # - task_types: needs a list # - device_id: might as well make it a list # - user_id: might as well make it a list # - group_id: might as well make it a list # - start_datetime: single only # - end_datetime: single only # - text_contents: might as well make it a list # - ID numbers: a list, joined with OR. id = Column("id", Integer, primary_key=True, autoincrement=True, index=True, comment="Task filter ID (arbitrary integer)") # Task type filters task_types = Column( "task_types", StringListType, comment="Task filter: task type(s), as CSV list of table names") tasks_offering_trackers_only = Column( "tasks_offering_trackers_only", Boolean, comment="Task filter: restrict to tasks offering trackers only?") tasks_with_patient_only = Column( "tasks_with_patient_only", Boolean, comment="Task filter: restrict to tasks with a patient (non-anonymous " "tasks) only?") # Patient-related filters surname = Column("surname", PatientNameColType, comment="Task filter: surname") forename = Column("forename", PatientNameColType, comment="Task filter: forename") dob = Column("dob", Date, comment="Task filter: DOB") sex = Column("sex", SexColType, comment="Task filter: sex") idnum_criteria = Column( # new in v2.0.1 "idnum_criteria", IdNumReferenceListColType, comment="ID filters as JSON; the ID number definitions are joined " "with OR") # Other filters device_ids = Column("device_ids", IntListType, comment="Task filter: source device ID(s), as CSV") adding_user_ids = Column( "user_ids", IntListType, comment="Task filter: adding (uploading) user ID(s), as CSV") group_ids = Column("group_ids", IntListType, comment="Task filter: group ID(s), as CSV") start_datetime = Column( "start_datetime_iso8601", PendulumDateTimeAsIsoTextColType, comment="Task filter: start date/time (UTC as ISO8601)") end_datetime = Column( "end_datetime_iso8601", PendulumDateTimeAsIsoTextColType, comment="Task filter: end date/time (UTC as ISO8601)") # Implemented on the Python side for indexed lookup: text_contents = Column( "text_contents", StringListType, comment="Task filter: filter text fields" ) # task must contain ALL the strings in AT LEAST ONE of its text columns # Implemented on the Python side for non-indexed lookup: complete_only = Column("complete_only", Boolean, comment="Task filter: task complete?") def __init__(self) -> None: # We need to initialize these explicitly, because if we create an # instance via "x = TaskFilter()", they will be initialized to None, # without any recourse to our database to-and-fro conversion code for # each fieldtype. # (If we load from a database, things will be fine.) self.idnum_criteria = [] # type: List[IdNumReference] self.device_ids = [] # type: List[int] self.adding_user_ids = [] # type: List[int] self.group_ids = [] # type: List[int] self.text_contents = [] # type: List[str] # ANYTHING YOU ADD BELOW HERE MUST ALSO BE IN init_on_load(). # Or call it, of course, but we like to keep on the happy side of the # PyCharm type checker. # Python-only filtering attributes (i.e. not saved to database) self.era = None # type: str self.finalized_only = False # used for exports self.must_have_idnum_type = None # type: int # Other Python-only attributes self.sort_method = TaskClassSortMethod.NONE self._task_classes = None # type: List[Type[Task]] @reconstructor def init_on_load(self): """ SQLAlchemy function to recreate after loading from the database. """ self.era = None # type: str self.finalized_only = False self.must_have_idnum_type = None # type: int self.sort_method = TaskClassSortMethod.NONE self._task_classes = None # type: List[Type[Task]] def __repr__(self) -> str: return auto_repr(self, with_addr=True) def set_sort_method(self, sort_method: TaskClassSortMethod) -> None: """ Sets the sorting method for task types. """ self.sort_method = sort_method @property def task_classes(self) -> List[Type[Task]]: """ Return a list of task classes permitted by the filter. Uses caching, since the filter will be called repeatedly. """ if self._task_classes is None: self._task_classes = [] # type: List[Type[Task]] if self.task_types: starting_classes = task_classes_from_table_names( self.task_types) else: starting_classes = Task.all_subclasses_by_shortname() skip_anonymous_tasks = self.skip_anonymous_tasks() for cls in starting_classes: if (self.tasks_offering_trackers_only and not cls.provides_trackers): # Class doesn't provide trackers; skip continue if skip_anonymous_tasks and not cls.has_patient: # Anonymous task; skip continue if self.text_contents and not cls.get_text_filter_columns(): # Text filter and task has no text columns; skip continue self._task_classes.append(cls) sort_task_classes_in_place(self._task_classes, self.sort_method) return self._task_classes def skip_anonymous_tasks(self) -> bool: """ Should we skip anonymous tasks? """ return self.tasks_with_patient_only or self.any_patient_filtering() def offers_all_task_types(self) -> bool: """ Does this filter offer every single task class? Used for efficiency when using indexes. (Since ignored.) """ if self.tasks_offering_trackers_only: return False if self.skip_anonymous_tasks(): return False if not self.task_types: return True return set(self.task_classes) == set(Task.all_subclasses_by_shortname) def offers_all_non_anonymous_task_types(self) -> bool: """ Does this filter offer every single non-anonymous task class? Used for efficiency when using indexes. """ offered_task_classes = self.task_classes for taskclass in Task.all_subclasses_by_shortname(): if taskclass.is_anonymous: continue if taskclass not in offered_task_classes: return False return True @property def task_tablename_list(self) -> List[str]: """ Returns the base table names for all task types permitted by the filter. """ return [cls.__tablename__ for cls in self.task_classes] def any_patient_filtering(self) -> bool: """ Is some sort of patient filtering being applied? """ return (bool(self.surname) or bool(self.forename) or (self.dob is not None) or bool(self.sex) or bool(self.idnum_criteria)) def any_specific_patient_filtering(self) -> bool: """ Are there filters that would restrict to one or a few patients? (Differs from :func:`any_patient_filtering` with respect to sex.) """ return (bool(self.surname) or bool(self.forename) or self.dob is not None or bool(self.idnum_criteria)) def get_only_iddef(self) -> Optional["IdNumReference"]: """ If a single ID number type/value restriction is being applied, return it, as an :class:`camcops_server.cc_modules.cc_simpleobjects.IdNumReference`. Otherwise, return ``None``. """ if len(self.idnum_criteria) != 1: return None return self.idnum_criteria[0] def get_group_names(self, req: "CamcopsRequest") -> List[str]: """ Get the names of any groups to which we are restricting. """ groups = (req.dbsession.query(Group).filter( Group.id.in_(self.group_ids)).all()) # type: List[Group] return [g.name if g and g.name else "" for g in groups] def get_user_names(self, req: "CamcopsRequest") -> List[str]: """ Get the usernames of any uploading users to which we are restricting. """ users = (req.dbsession.query(User).filter( User.id.in_(self.adding_user_ids)).all()) # type: List[User] return [u.username if u and u.username else "" for u in users] def get_device_names(self, req: "CamcopsRequest") -> List[str]: """ Get the names of any devices to which we are restricting. """ devices = (req.dbsession.query(Device).filter( Device.id.in_(self.device_ids)).all()) # type: List[Device] return [d.name if d and d.name else "" for d in devices] def clear(self) -> None: """ Clear all parts of the filter. """ self.task_types = [] # type: List[str] self.surname = None self.forename = None self.dob = None self.sex = None self.idnum_criteria = [] # type: List[IdNumReference] self.device_ids = [] # type: List[int] self.adding_user_ids = [] # type: List[int] self.group_ids = [] # type: List[int] self.start_datetime = None self.end_datetime = None self.text_contents = [] # type: List[str] self.complete_only = None def dates_inconsistent(self) -> bool: """ Are inconsistent dates specified, such that no tasks should be returned? """ return (self.start_datetime and self.end_datetime and self.end_datetime < self.start_datetime) def filter_query_by_patient(self, q: Query, via_index: bool) -> Query: """ Restricts an query that has *already been joined* to the :class:`camcops_server.cc_modules.cc_patient.Patient` class, according to the patient filtering criteria. Args: q: the starting SQLAlchemy ORM Query via_index: If ``True``, the query relates to a :class:`camcops_server.cc_modules.cc_taskindex.TaskIndexEntry` and we should restrict it according to the :class:`camcops_server.cc_modules.cc_taskindex.PatientIdNumIndexEntry` class. If ``False``, the query relates to a :class:`camcops_server.cc_modules.cc_taskindex.Task` and we should restrict according to :class:`camcops_server.cc_modules.cc_patientidnum.PatientIdNum`. Returns: a revised Query """ if self.surname: q = q.filter(func.upper(Patient.surname) == self.surname.upper()) if self.forename: q = q.filter(func.upper(Patient.forename) == self.forename.upper()) if self.dob is not None: q = q.filter(Patient.dob == self.dob) if self.sex: q = q.filter(func.upper(Patient.sex) == self.sex.upper()) if self.idnum_criteria: id_filter_parts = [] # type: List[ColumnElement] if via_index: q = q.join(PatientIdNumIndexEntry) # "Specify possible ID number values" for iddef in self.idnum_criteria: id_filter_parts.append( and_( PatientIdNumIndexEntry.which_idnum == iddef.which_idnum, # noqa PatientIdNumIndexEntry.idnum_value == iddef.idnum_value)) # Use OR (disjunction) of the specified values: q = q.filter(or_(*id_filter_parts)) # "Must have a value for a given ID number type" if self.must_have_idnum_type: # noinspection PyComparisonWithNone,PyPep8 q = q.filter( and_( PatientIdNumIndexEntry.which_idnum == self.must_have_idnum_type, # noqa PatientIdNumIndexEntry.idnum_value != None)) else: # q = q.join(PatientIdNum) # fails q = q.join(Patient.idnums) # "Specify possible ID number values" for iddef in self.idnum_criteria: id_filter_parts.append( and_(PatientIdNum.which_idnum == iddef.which_idnum, PatientIdNum.idnum_value == iddef.idnum_value)) # Use OR (disjunction) of the specified values: q = q.filter(or_(*id_filter_parts)) # "Must have a value for a given ID number type" if self.must_have_idnum_type: # noinspection PyComparisonWithNone,PyPep8 q = q.filter( and_( PatientIdNum.which_idnum == self.must_have_idnum_type, PatientIdNum.idnum_value != None)) return q @property def start_datetime_utc(self) -> Optional[Pendulum]: if not self.start_datetime: return None return convert_datetime_to_utc(self.start_datetime) @property def end_datetime_utc(self) -> Optional[Pendulum]: if not self.end_datetime: return None return convert_datetime_to_utc(self.end_datetime)
class Annotation(CocoBase): __tablename__ = 'annotations' id = Column(Integer, primary_key=True) image_id = Column(Integer, doc='', index=True, unique=False) category_id = Column(Integer, doc='', index=True, unique=False) track_id = Column(String, index=True, unique=False) segmentation = Column(JSON) keypoints = Column(JSON) foreign = Column(JSON) bbox = Column(JSON) bbox_x = Column(Float) bbox_y = Column(Float) bbox_w = Column(Float) bbox_h = Column(Float) weight = Column(Float) score = Column(Float) weight = Column(Float) prob = Column(JSON) iscrowd = Column(Integer) caption = Column(JSON)
class ReportBacktrace(GenericTable): __tablename__ = "reportbacktraces" id = Column(Integer, primary_key=True) report_id = Column(Integer, ForeignKey("{0}.id".format(Report.__tablename__), ondelete="CASCADE"), nullable=False, index=True) report = relationship(Report, backref="backtraces") crashfn = Column(String(1024), nullable=True) quality = Column(Integer, nullable=False) @property def crash_function(self): if self.crashfn: return self.crashfn return 'unknown function' @property def frames(self): # there should always be exactly one crashthread # but the DB schema allows multiple or none, so let's # be ready for such case crashthreads = [t for t in self.threads if t.crashthread] if not crashthreads: return [] return crashthreads[0].frames def normalized(self): result = self.btp_thread() if self.report.type == "KERNELOOPS": result.normalize_kerneloops() elif self.report.type == "USERSPACE": result.normalize_userspace() return result def as_named_tuples(self): ''' Return list of named tuples containing name, path, source and line fields for each frame of this backtrace. ''' result = [] for frame in self.frames: frame_t = namedtuple('Frame', ['name', 'path', 'source', 'line']) if frame.symbolsource.symbol: name = frame.symbolsource.symbol.name if frame.symbolsource.symbol.nice_name: name = frame.symbolsource.symbol.nice_name frame_t.name = name else: frame_t.name = '??' frame_t.path = frame.symbolsource.path frame_t.source_path = None frame_t.line_num = None if (frame.symbolsource.source_path and frame.symbolsource.line_number): frame_t.source_path = frame.symbolsource.source_path frame_t.line_num = frame.symbolsource.line_number result.append(frame_t) return result def compute_quality(self): ''' Compute backtrace quality (0=high quality, -100=lowest) Frames with missing information lower the backtrace quality. ''' quality = -len(self.taint_flags) # empty backtrace if not self.frames: quality -= 100 for frame in self.frames: if not frame.symbolsource.symbol: quality -= 1 elif frame.symbolsource.symbol.name == '??': quality -= 1 if not frame.symbolsource.source_path: quality -= 1 if not frame.symbolsource.line_number: quality -= 1 if not frame.reliable: quality -= 1 return quality @property def tainted(self): return any(flag.taintflag.character.upper() != 'G' for flag in self.taint_flags)
class Job(Base): __tablename__ = 'jobs' id = Column(GUID, primary_key=True, default=uuid.uuid4) type = Column(Integer, nullable=False) url = Column(String, nullable=False) plugin = Column(String, nullable=False) hash = Column(String, nullable=False) locked = Column(Boolean, nullable=False) crawler_id = Column(GUID, nullable=False) done_by = Column(GUID) date_added = Column(TIMESTAMP, nullable=False) date_done = Column(TIMESTAMP) repeat = Column(Integer, nullable=True) repeat_after = Column(TIMESTAMP) def __repr__(self): return "<Job(id='%s' type='%s', url='%s', hash='%s', " \ "locked='%s', crawler_id='%s', done_by='%s', date_done='%s', date_added='%s', repeat='%s')>" % ( self.id, self.type, self.url, self.hash, self.locked, self.crawler_id, self.done_by, self.date_done, self.date_added, self.repeat)
class ReportUnknownPackage(GenericTable): __tablename__ = "reportunknownpackages" __table_args__ = (UniqueConstraint('report_id', 'type', 'name', 'epoch', 'version', 'release', 'arch_id'), ) id = Column(Integer, primary_key=True) report_id = Column(Integer, ForeignKey("{0}.id".format(Report.__tablename__), ondelete="CASCADE"), nullable=False) type = Column( Enum("CRASHED", "RELATED", "SELINUX_POLICY", name="reportpackage_type")) name = Column(String(64), nullable=False, index=True) epoch = Column(Integer, nullable=False) version = Column(String(64), nullable=False) release = Column(String(64), nullable=False) arch_id = Column(Integer, ForeignKey("{0}.id".format(Arch.__tablename__)), nullable=False) count = Column(Integer, nullable=False) report = relationship(Report, backref="unknown_packages") arch = relationship(Arch, primaryjoin="Arch.id==ReportUnknownPackage.arch_id") semver = Column(Semver, nullable=False) # semantic version semrel = Column(Semver, nullable=False) # semantic release Index("ix_reportunknownpackages_semver_semrel", semver, semrel) def nvr(self): return "{0}-{1}-{2}".format(self.name, self.version, self.release) def nevr(self): if not self.epoch: return self.nvr() return "{0}-{1}:{2}-{3}".format(self.name, self.epoch, self.version, self.release) def evr(self): return "{0}:{1}-{2}".format(self.epoch, self.version, self.release)
class SlackMember(db.Model): __tablename__ = 'slack_members' id = Column(String(128), primary_key=True, comment='Primary Key({team_id}/{user_id})') local_id = Column(String(64), index=True, comment='Slack UserID') team_id = Column(String(64), ForeignKey('slack_workspaces.id'), nullable=False, comment='Team ID') name = Column(String(128), nullable=False, comment='User Name') deleted = Column(Boolean, nullable=False, comment='Delete Flag') color = Column(String(64), nullable=False, comment='Color') real_name = Column(String(128), nullable=False, comment='Real Name') tz = Column(String(64), nullable=True, comment='Timezone') tz_offset = Column(Integer, nullable=False, comment='Timezone Offset') image_24 = Column(Text, nullable=False, comment='Avatar Icon(24)') image_32 = Column(Text, nullable=False, comment='Avatar Icon(32)') image_48 = Column(Text, nullable=False, comment='Avatar Icon(48)') image_72 = Column(Text, nullable=False, comment='Avatar Icon(72)') image_192 = Column(Text, nullable=False, comment='Avatar Icon(192)') image_512 = Column(Text, nullable=False, comment='Avatar Icon(2512') is_bot = Column(Boolean, nullable=False, comment='Bot Flag') is_owner = Column(Boolean, nullable=False, comment='Owner Flag') is_admin = Column(Boolean, nullable=False, comment='Admin Flag') created_at = Column(DateTime, nullable=False, server_default=current_timestamp()) updated_at = Column( DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')) def setApiResponse(self, member, team_id): """ Slack APIのレスポンス結果をモデルにセット Arguments: * member * Slackのusers.listのmembersリストの1要素 """ self.id = f'{team_id}/{member["id"]}' self.local_id = member['id'] self.team_id = team_id self.name = member['name'] self.deleted = member['deleted'] self.color = member['color'] self.real_name = member['real_name'] self.tz = member['tz'] self.tz_offset = member['tz_offset'] self.image_24 = member['profile']['image_24'] self.image_32 = member['profile']['image_32'] self.image_48 = member['profile']['image_48'] self.image_72 = member['profile']['image_72'] self.image_192 = member['profile']['image_192'] self.image_512 = member['profile']['image_512'] self.is_bot = member['is_bot'] self.is_owner = member['is_owner'] self.is_admin = member['is_admin']
class Report(GenericTable): __tablename__ = "reports" __lobs__ = {"oops": 1 << 16} id = Column(Integer, primary_key=True) type = Column(String(64), nullable=False, index=True) first_occurrence = Column(DateTime) last_occurrence = Column(DateTime) # Watch out, there's a "set" event handler on count that can send out fedmsg # notifications. count = Column(Integer, nullable=False) errname = Column(String(256), nullable=True) component_id = Column(Integer, ForeignKey("{0}.id".format( OpSysComponent.__tablename__)), nullable=False, index=True) problem_id = Column(Integer, ForeignKey("{0}.id".format(Problem.__tablename__)), nullable=True, index=True) component = relationship(OpSysComponent) problem = relationship(Problem, backref="reports") max_certainty = Column(Integer, nullable=True) @property def bugs(self): # must be imported here to avoid dependency circle from pyfaf.bugtrackers import report_backref_names # pylint: disable=cyclic-import my_bugs = [] for br in report_backref_names: for reportbug in getattr(self, br): my_bugs.append(reportbug.bug) return my_bugs @property def oops(self): return self.get_lob('oops') @property def sorted_backtraces(self): ''' List of all backtraces assigned to this report sorted by quality. ''' return sorted(self.backtraces, key=lambda bt: bt.quality, reverse=True) @property def quality(self): ''' Return quality metric for this report which equals to the quality of its best backtrace. ''' bts = self.sorted_backtraces if not bts: return -1000 return self.sorted_backtraces[0].quality @property def tainted(self): if self.type.lower() != "kerneloops": return False return all(bt.tainted for bt in self.backtraces) @property def crash_function(self): """ Return the most common crash function among all backtraces of this report """ return most_common_crash_function(self.backtraces) @property def error_name(self): if self.type == "core": return signal2name(self.errname, with_number=True) if self.type == "python": if self.errname and (self.errname[0] in ascii_uppercase or "." in self.errname): # A lot of python reports contain "reason" or "error" as errname # so we only show the ones beginning with an uppercase letter or # containing a "." (lowercase module.Exception) return self.errname return None return self.errname @property def archived(self): if self.archive and self.archive.active: return True return False
class AssociatePeople(GenericTable): __tablename__ = "associatepeople" __table_args__ = (UniqueConstraint('name'), ) id = Column(Integer, primary_key=True) name = Column(String(64), nullable=False, index=True)
class ConsumableMixin(object): added_fat = Column(REAL, ColumnDefault(0.0), CheckConstraint("added_fat >= 0.0")) carbohydrates = Column(REAL, ColumnDefault(0.0), CheckConstraint("carbohydrates >= 0.0")) quantity = Column(REAL, CheckConstraint("quantity >= 0.0"), nullable=False)