def action_execute(self, ids): from gengine.metadata import DBSession from gengine.app.model import t_tasks, t_taskexecutions from gengine.app.registries import get_task_registry tasks = DBSession.execute( t_tasks.select().where(t_tasks.c.id.in_(*ids)) ).fetchall() for task in tasks: result = get_task_registry().execute( name=task["task_name"], config=task["config"] ) logged = result.get("log", None) success = result.get("success", True) DBSession.bind.execute( t_taskexecutions.insert().values({ 'task_id': task["id"], 'planned_at': dt_now(), 'finished_at': dt_now(), 'log': logged, 'success': success }) ) flash("Executed")
def forward(cls, subjecttype_id, context_subject_id, from_date, to_date, whole_time_required=False): # We are comparing all subjects of type subject_type which have been part of context_subject_id between from_date and to_date # By default, they don't have to be member all the time (whole_time_required). #print("Looking for descendents of %s of type %s" % (context_subject_id, subjecttype_id)) #print("From Date: %s, To Date: %s, whole_time_required: %s" % (from_date, to_date, whole_time_required)) ancestor_subjects = Subject.get_descendent_subjects( subject_id=context_subject_id, of_type_id=subjecttype_id, from_date=from_date if from_date else dt_now(), to_date=to_date if to_date else dt_now(), whole_time_required=whole_time_required ) subjects = [x for x in ancestor_subjects.keys()] return subjects
def get_user(request): if not asbool(settings.get("enable_user_authentication", False)): return None token = request.headers.get('X-Auth-Token') if (not token) and request.cookies.get("X-Auth-Token"): token = request.cookies.get("X-Auth-Token") if token is not None: from gengine.app.model import DBSession, AuthUser, AuthToken tokenObj = DBSession.query(AuthToken).filter(AuthToken.token.like(token)).first() user = None if tokenObj and tokenObj.valid_until < dt_now(): tokenObj.extend() if tokenObj: user = tokenObj.user if not user: raise APIError(401, "invalid_token", "Invalid token provided.") if not user.active: raise APIError(404, "user_is_not_activated", "Your user is not activated.") return user return None
def increase_value(request): """increase a value for the subject""" subject_id = int(request.matchdict["subject_id"]) try: value = float(request.POST["value"]) except: try: doc = request.json_body value = doc["value"] except: raise APIError(400, "invalid_value", "Invalid value provided") key = request.matchdict["key"] if ( "key" in request.matchdict and request.matchdict["key"] is not None) else "" variable_name = request.matchdict["variable_name"] subject = Subject.get_subject(subject_id) if not subject: raise APIError(404, "subject_not_found", "subject not found") variable = Variable.get_variable_by_name(variable_name) if not variable: raise APIError(404, "variable_not_found", "variable not found") if asbool(get_settings().get("enable_user_authentication", False)): if not AuthUser.may_increase(variable, request, subject_id): raise APIError( 403, "forbidden", "You may not increase the variable for this subject.") Value.increase_value(variable_name, subject["id"], value, key, at_datetime=dt_now()) try: achievement_history = int(request.GET["achievement_history"]) except: achievement_history = 2 output = _get_progress(achievements_for_subject=subject, requesting_subject=request.subject, achievement_history=achievement_history) output = copy.deepcopy(output) to_delete = list() for i in range(len(output["achievements"])): if len(output["achievements"][i]["new_levels"]) > 0: if "levels" in output["achievements"][i]: del output["achievements"][i]["levels"] if "priority" in output["achievements"][i]: del output["achievements"][i]["priority"] if "goals" in output["achievements"][i]: del output["achievements"][i]["goals"] else: to_delete.append(i) for i in sorted(to_delete, reverse=True): del output["achievements"][i] return output
def main(argv=sys.argv): if len(argv) < 2: usage(argv) config_uri = argv[1] options = parse_vars(argv[2:]) setup_logging(config_uri) settings = get_appsettings(config_uri, options=options) import gengine gengine.main({}, **settings) from gengine.metadata import (DBSession) sess = DBSession() import gengine.app.model as m import crontab from gengine.app.registries import get_task_registry enginetasks = get_task_registry().registrations with transaction.manager: mark_changed(sess, transaction.manager, True) tasks = sess.execute(m.t_tasks.select()).fetchall() for task in tasks: cron = task["cron"] if not cron: cron = enginetasks.get(task["task_name"]).get( "default_cron", None) if cron: now = dt_now().replace(second=0) item = crontab.CronItem(line=cron) s = item.schedule(date_from=now) prev = s.get_next().replace(second=0) next = s.get_next().replace(second=0) execs = sess.execute(m.t_taskexecutions.select().where( and_( m.t_taskexecutions.c.task_id == task["id"], m.t_taskexecutions.c.canceled_at == None, m.t_taskexecutions.c.finished_at == None, )).order_by( m.t_taskexecutions.c.planned_at.desc())).fetchall() found = False for exec in execs: if exec["planned_at"] >= next: # The next execution is already planned found = True if exec["planned_at"] <= prev and prev < dt_ago( minutes=10) and not exec["locked_at"]: # The execution is more than 10 minutes in the past and not yet locked (worker not running / overloaded) if next - datetime.timedelta(minutes=10) < dt_now(): # The next execution is planned in less than 10 minutes, cancel the other one sess.execute(m.t_taskexecutions.update().values({ 'canceled_at': dt_now() }).where({'id': exec["id"]})) if exec["locked_at"] and exec["locked_at"] < dt_ago( hours=24): # this task is running for more than 24 hours. probably crashed.... set it to canceled sess.execute(m.t_taskexecutions.update().values({ 'canceled_at': dt_now() }).where({'id': exec["id"]})) if not found: # Plan next execution sess.execute(m.t_taskexecutions.insert().values({ 'task_id': task["id"], 'planned_at': next })) sess.flush() sess.commit()