def create_task(): post_body = json.loads(request.data) task = Task(description=post_body.get('description'), done=bool(post_body.get('done'))) db.session.add(task) db.session.commit() return json.dumps({'success': True, 'data': task.serialize()}), 201
def scaner(): """ Main method to get data from queue. Get every 2 sec. :return: """ engine = sa.create_engine(dsn) conn = engine.connect() executor = ThreadPoolExecutor(max_workers=4) while True: tasks = conn.execute( sa.select([Task]).where( sa.and_(Task.c.iscomplete == False, Task.c.inprocess == False))) for task in tasks: try: conn.execute(Task.update().values(inprocess=True).where( Task.c.id == task.id)) executor.submit(scan, task, conn) except Exception as e: print(type(e), e) finally: conn.execute(Task.update().values( inprocess=False, iscomplete=True).where(Task.c.id == task.id)) gc.collect() sleep(2)
def taskHasWantedKeywordDict(task, wantedKeywordDict): """ @param task: task object @param wantedKeywordDict: dict of name/value of wanted keyword # a task is considered a subset of wantedKeywordDict if: # 1. All wantedKeywordDict keys are in task or project keywords # 2. All wantedKeywordDict valued keywords have the same value # in task or project keyword""" for wantedKeyword, wantedValue in wantedKeywordDict.items(): taskFilters=[Task.q.id==task.id, TaskKeyword.q.taskID==task.id, TaskKeyword.q.keywordID==Keyword.q.id, LIKE(Keyword.q.name, wantedKeyword)] projectFilters=[Project.q.id==task.projectID, ProjectKeyword.q.projectID==Project.q.id, ProjectKeyword.q.keyword==Keyword.q.id, LIKE(Keyword.q.name, wantedKeyword)] if wantedValue: taskFilters.append(TaskKeyword.q.value==wantedValue) projectFilters.append(ProjectKeyword.q.value==wantedValue) if Task.select(AND(*taskFilters)).count()==0 and Task.select(AND(*projectFilters)).count()==0: return False # All critera were met, return ok return True
def do_t_reorder(self, line): """Reorder tasks of a project. It works by starting an editor with the task list: you can then change the order of the lines and save the list. The urgency field will be updated to match the order. t_reorder <project_name>""" project = Project.byName(projectName) taskList = Task.select(AND(Task.q.projectID == project.id, Task.q.status != 'done'), orderBy=-Task.q.urgency) lines = [ "%d,%s" % (x.id, x.title) for x in taskList] text = tui.editText("\n".join(lines)) ids = [] for line in text.split("\n"): line = line.strip() if not "," in line: continue id = int(line.split(",")[0]) ids.append(id) ids.reverse() for urgency, id in enumerate(ids): task = Task.get(id) task.urgency = urgency
def test_deps_text(self): text = '' task1 = Task(chat=1, name='{}'.format(text), status='TODO', dependencies='', parents='', priority='') task2 = Task(chat=1, name='{}'.format(text), status='TODO', dependencies='1,2,', parents='', priority='') task3 = Task(chat=1, name='{}'.format(text), status='TODO', dependencies='2,', parents='', priority='') db.session.add(task1) db.session.add(task2) db.session.add(task3) db.session.commit() chat = 1 preceed = '' assert text == Services().deps_text(task1, chat, preceed)
def duplicate(self, message, chat, apiBot): """ Function description. :type message: string :type chat: int """ if message.isdigit(): task_id = int(message) try: task = self.find_task(task_id, chat) except sqlalchemy.orm.exc.NoResultFound: self.id_error_message(message, chat, apiBot) return duplicated_task = Task(chat=task.chat, name=task.name, status=task.status, dependencies=task.dependencies, parents=task.parents, priority=task.priority, duedate=task.duedate) db.session.add(duplicated_task) for dependent_task_id in task.dependencies.split(',')[:-1]: dependent_task = self.find_task(dependent_task_id, chat) dependent_task.parents += '{},'.format(duplicated_task.id) issue = repository.create_issue(duplicated_task.name) duplicated_task.issue_number = issue.number db.session.commit() apiBot.send_message( "New task *TODO* [[{}]] {}".format(duplicated_task.id, duplicated_task.name), chat) else: self.id_error_message(message, chat, apiBot)
def save_task(task_request, job_id): task = Task() task.name = task_request['name'] task.sequence = task_request['sequence'] task.job_id = job_id session.add(task) session.commit() save_taskqueue(task_request, task.id) return 'ok'
def create_task(name, description, date, budget, event_id): new_task = Task( name=name, description=description, date=date, budget=budget, event_id=event_id ) db.session.add(new_task) db.session.commit() return new_task.serialize()
def create_task(): body = json.loads(request.data) new_task = Task(description=body['description'], done=body.get('done', False) # 無法取得數值時,給予初始值避免出錯 ) db.session.add(new_task) db.session.commit() return success_response(new_task.serialize(), 201)
def testAdd(self): tui.addInputAnswers("y", "2", "4", "123") self.cmd.do_bug_add("x t1") tasks = list(Task.select()) result = [x.title for x in tasks] expected = [u"t1"] self.assertEqual(result, expected) kwDict = Task.get(1).getKeywordDict() self.assertEqual(kwDict, dict(_severity=2, _likelihood=4, _bug=123))
def api_feature(pid): user = get_user() project = Project.get(Project.id == pid) if user and request.method == 'POST' and project.can_validate: ref_and_audit = request.get_json() if ref_and_audit and len(ref_and_audit) == 2: skipped = ref_and_audit[1] is None feat = Feature.get(Feature.project == project, Feature.ref == ref_and_audit[0]) user_did_it = Task.select(Task.id).where( Task.user == user, Task.feature == feat).count() > 0 Task.create(user=user, feature=feat, skipped=skipped) if not skipped: if len(ref_and_audit[1]): new_audit = json.dumps(ref_and_audit[1], sort_keys=True, ensure_ascii=False) else: new_audit = None if feat.audit != new_audit: feat.audit = new_audit feat.validates_count = 1 elif not user_did_it: feat.validates_count += 1 feat.save() fref = request.args.get('ref') if fref: feature = Feature.get(Feature.project == project, Feature.ref == fref) elif not user or request.args.get('browse') == '1': feature = Feature.select().where(Feature.project == project).order_by(fn_Random()).get() else: try: # Maybe use a join: https://stackoverflow.com/a/35927141/1297601 task_query = Task.select(Task.id).where(Task.user == user, Task.feature == Feature.id) query = Feature.select().where( Feature.project == project, Feature.validates_count < 2).where( ~fn.EXISTS(task_query)).order_by(fn_Random()) if project.validate_modified: query = query.where(Feature.action == 'm') if user.bboxes: bboxes = BBoxes(user) feature = None for f in query: if bboxes.contains(f.lat/1e7, f.lon/1e7): feature = f break elif not feature: feature = f if not feature: raise Feature.DoesNotExist() else: feature = query.get() except Feature.DoesNotExist: return jsonify(feature={}, ref=None, audit=None) return jsonify(feature=json.loads(feature.feature), ref=feature.ref, audit=json.loads(feature.audit or 'null'))
def testAdd(self): tui.addInputAnswers("y") self.cmd.do_t_add("x t1") tui.addInputAnswers("y", "y") self.cmd.do_t_add("x @kw1 @kw2=12 t2") tasks = list(Task.select()) result = [x.title for x in tasks] expected = [u"t1", u"t2"] self.assertEqual(result, expected) kwDict = Task.get(2).getKeywordDict() self.assertEqual(kwDict, dict(kw1=None, kw2=12))
def setUp(self): with patch('db.datetime') as mock_datetime: mock_datetime.now.return_value = default_timestamp self.DB = Database(TEST_DB_URL) session = self.DB.sessionmaker() session.add( Task(assigner_id=user1, assignee_id=user2, description='order lunch')) session.add( Task(assigner_id=user1, assignee_id=user2, description='eat lunch')) session.commit()
def testLastTaskId(self): # Using "_" with no prior task activity should raise an exception self.assertRaises(YokadiException, self.cmd.getTaskFromId, "_") tui.addInputAnswers("y") self.cmd.do_t_add("x t1") task1 = Task.get(1) self.assertEqual(self.cmd.getTaskFromId("_"), task1) self.cmd.do_t_add("x t2") task2 = Task.get(2) self.assertEqual(self.cmd.getTaskFromId("_"), task2) self.cmd.do_t_mark_started("1") self.assertEqual(self.cmd.getTaskFromId("_"), task1)
def new_task(chat, msg): from datetime import datetime task = Task(chat=chat, name=msg, status='TODO', description='No description.', priority='None', duedate='') task.duedate = datetime.strptime(task.duedate, '') db.session.add(task) db.session.commit() send_message("New task *TODO* [[{}]] {}".format(task.id, task.name), chat)
def end(self): # Adjust idColumn maxId = Task.select().max(Task.q.id) self.idColumn.width = max(2, len(str(maxId))) # Adjust dueColumn shortDateFormat = self.termWidth < 100 if shortDateFormat: self.dueColumn.width = 8 else: self.dueColumn.width = 26 self.dueColumn.formater = DueDateFormater(self.today, shortDateFormat) # Adjust titleColumn self.titleColumn.width = self.maxTitleWidth totalWidth = sum([x.width for x in self.columns]) if totalWidth > self.termWidth: self.titleColumn.width -= (totalWidth - self.termWidth) + len(self.columns) self.titleColumn.formater = TitleFormater(self.titleColumn.width) # Print table for sectionName, taskList in self.taskLists: self._renderTaskListHeader(sectionName) for task in taskList: self._renderTaskListRow(task)
def setUp(self): self.task = Task(chat=1, name="teste", status='TODO', dependencies='', parents='2, 3', priority='')
def project(name): project = Project.get(Project.name == name) desc = project.description.replace('\n', '<br>') cnt = project.feature_count val1 = Feature.select(Feature.id).where(Feature.project == project, Feature.validates_count > 0) val2 = Feature.select(Feature.id).where(Feature.project == project, Feature.validates_count >= 2) if project.validate_modified: val1 = val1.where(Feature.action == 'm') val2 = val2.where(Feature.action == 'm') cnt = Feature.select(Feature.id).where(Feature.project == project, Feature.action == 'm').count() corrected = Feature.select(Feature.id).where( Feature.project == project, Feature.audit.is_null(False), Feature.audit != '').count() skipped = Feature.select(Feature.id).where( Feature.project == project, Feature.audit.contains('"skip": true')).count() user = get_user() if user: has_skipped = Task.select().join(Feature).where( Task.user == user, Task.skipped == True, Feature.project == project).count() > 0 else: has_skipped = False return render_template('project.html', project=project, admin=is_admin(user, project), count=cnt, desc=desc, val1=val1.count(), val2=val2.count(), corrected=corrected, skipped=skipped, has_skipped=has_skipped)
def get_or_create_task_for_user(user, date=None, ip=None): if not date: date = today() try: task_obj = Task.get(Task.user == user, Task.day == date) if task_obj.task not in get_tasks(user.level): task_obj.task = random_task_for_user(user) task_obj.save() except Task.DoesNotExist: if ip: task_name = random_task_for_ip(ip) else: task_name = random_task_for_user(user) task_obj = Task(user=user, day=date, task=task_name) task_obj.save() return task_obj
def startGeneratingTasks(self, message): _log.debug("sleeping some time") some_locations = [[2, 9], [3, 10], [3, 9], [3, 11], [4, 4], [4, 1.5], [2.5, 9], [4, 10], [4, 11]] number_of_locations = randint(1, 4) locations_to_visit = [] for _ in range(number_of_locations): loc = randint(0, len(some_locations) - 1) locations_to_visit.append(some_locations[loc]) locations = locations_to_visit user = "******" status = 'pending' locations = [Point(l) for l in locations] new_task = Task(username=user, locations=locations, status=status) try: self.session.add(new_task) self.session.commit() entry_id = new_task.id _log.debug("-------------------------sending new request") self.send_message(to=settings.SCHEDULER, directive="request",\ body = {'locations':locations, 'request_id':entry_id}) yield from asyncio.sleep(30) self.send_message(to="generator", directive="start") except Exception as e: self.session.rollback() self.set_status(400)
def todayWord(): if current_user.task is None: current_user.task=Task(user=current_user,wordNumPerDay=0) session.commit() if session.query(HistoryTask).filter(HistoryTask.user==current_user,HistoryTask.taskTime==date.today()).count()==0: history=HistoryTask(userId=current_user.id,taskTime=date.today(),plan=current_user.task.wordNumPerDay,complete=0) session.add(history) session.commit() else: history=session.query(HistoryTask).filter(HistoryTask.user==current_user,HistoryTask.taskTime==date.today()).first() need=history.plan-history.complete # print(need) count=session.query(Word).filter(Word.progresses.any(and_(Progress.progress<5,Progress.userId==current_user.id))).count() # print(count) try: if count<need: extendProgressCount=extendProgress(current_user, 1000) if count==0 and extendProgressCount.rowcount==0: return error({'message':'您已背完所有单词!'}) if need<=0: return success({'words':[]}) progresses=session.query(Progress).filter(Progress.userId==current_user.id,Progress.progress<5).order_by(Progress.progress).limit(need).all() # print(progresses) words=[progress.word.asDict() for progress in progresses] return success({'words':words}) except Exception as e: print(e) import traceback traceback.print_exc() session.rollback() return error({'message':"抱歉出现错误,请发送详细内容到[email protected]"})
def duplicate(self, bot, update, args): if args[0].isdigit(): task_id = int(args[0]) query = db.session.query(Task).filter_by( id=task_id, chat=update.message.chat_id) try: task = query.one() except sqlalchemy.orm.exc.NoResultFound: self.services.not_found_message(bot, update, task_id) return dtask = Task(chat=task.chat, name=task.name, status=task.status, dependencies=task.dependencies, parents=task.parents, priority=task.priority, duedate=task.duedate) db.session.add(dtask) for each_task in task.dependencies.split(',')[:-1]: each_query = db.session.query(Task).filter_by( id=int(each_task), chat=update.message.chat_id) each_task = each_query.one() each_task.parents += '{},'.format(dtask.id) db.session.commit() bot.send_message(chat_id=update.message.chat_id, text="New task *TODO* [[{}]] {}" .format(dtask.id, dtask.name)) else: bot.send_message(chat_id=update.message.chat_id, text="You must inform the task id")
def generateCal(): cal = icalendar.Calendar() cal.add("prodid", '-//Yokadi calendar //yokadi.github.com//') cal.add("version", "2.0") # Add projects for project in Project.select(Project.q.active == True): todo = icalendar.Todo() todo.add("summary", project.name) todo["uid"] = PROJECT_UID % project.id cal.add_component(todo) # Add tasks for task in Task.select(Task.q.status != "done"): todo = icalendar.Todo() todo["uid"] = TASK_UID % task.id todo["related-to"] = PROJECT_UID % task.project.id todo.add("dtstamp", task.creationDate) todo.add("priority", task.urgency) todo.add("summary", "%s (%s)" % (task.title, task.id)) todo.add("dtstart", task.creationDate) if task.dueDate: todo.add("due", task.dueDate) if task.description: todo.add("description", task.description) categories = [task.project, ] # Add project as a keyword if task.keywords: categories.extend([k.name for k in task.keywords]) todo.add("categories", categories) cal.add_component(todo) return cal
def duplicate(self, command, msg, chat): ''' Duplica uma task ''' msg = self.strip_message(msg) for i in range(len(msg)): if self.check_msg_not_exists(msg[i]): self.msg_no_task(chat) else: task_id = int(msg[i]) try: task = self.query_one(task_id, chat) except sqlalchemy.orm.exc.NoResultFound: self.task_not_found_msg(task_id, chat) continue dep_task = Task(chat=task.chat, name=task.name, status=task.status, dependencies=task.dependencies, parents=task.parents, priority=task.priority, duedate=task.duedate) db.session.add(dep_task) for t in task.dependencies.split(',')[:-1]: query_dep = db.session.query(Task).\ filter_by(id=int(t), chat=chat) t = query_dep.one() t.parents += '{},'.format(dep_task.id) db.session.commit() text_message = 'New task *TODO* [[{}]] {}' self.send_message(text_message.format(dep_task.id, dep_task.name), chat)
def testRecurs(self): tui.addInputAnswers("y") self.cmd.do_t_add("x t1") task = Task.get(1) self.cmd.do_t_recurs("1 daily 10:00") desc = str(task.recurrence) self.cmd.do_t_recurs("1 weekly FR 23:00") self.cmd.do_t_recurs("1 none") self.cmd.do_t_recurs("1 weekly fr 23:00") self.cmd.do_t_recurs("1 weekly Fr 23:00") self.cmd.do_t_recurs("1 weekly Friday 23:00") self.cmd.do_t_recurs("1 monthly 3 13:00") self.cmd.do_t_recurs("1 monthly second friday 13:00") self.cmd.do_t_recurs("1 yearly 3/07 11:20") self.cmd.do_t_recurs("1 quarterly 14 11:20") self.cmd.do_t_recurs("1 quarterly first monday 23:20") self.assertNotEqual(desc, str(task.recurrence)) self.assertEqual(task.status, "new") self.cmd.do_t_mark_done("1") self.assertEqual(task.status, "new") for bad_input in ("", # No task "1", # No recurence "1 foo", # Unknown recurrence "1 daily", # No time "1 weekly", # No day "1 weekly monday", # No time "1 monthly", # No day "1 monthly 10", # No time "1 quarterly", # No day "1 quarterly 10", # No time "1 monthly foo 12:00", # Bad date ): self.assertRaises(YokadiException, self.cmd.do_t_recurs, bad_input)
def new_task(msg, chat): task = Task(chat=chat, name=msg, status='TODO', dependencies='', parents='', priority='') db.session.add(task) db.session.commit() send_message("New task *TODO* [[{}]] {}".format(task.id, task.name), chat) create_issue(task.name, 'Task ID: [{}]\n\ Task Name: {}'.format(task.id, task.name))
def duplicate_assigment(msg, chat): if not msg.isdigit(): self.u.send_message("You must inform the task id", chat) else: task_id = int(msg) query = db.session.query(Task).filter_by(id=task_id, chat=chat) try: task = query.one() except sqlalchemy.orm.exc.NoResultFound: self.u.send_message( "_404_ Task {} not found x.x".format(task_id), chat) return dtask = Task(chat=task.chat, name=task.name, status=task.status, dependencies=task.dependencies, parents=task.parents, priority=task.priority, duedate=task.duedate) db.session.add(dtask) for t in task.dependencies.split(',')[:-1]: qy = db.session.query(Task).filter_by(id=int(t), chat=chat) t = qy.one() t.parents += '{},'.format(dtask.id) db.session.commit() self.u.send_message( "New task *TODO* [[{}]] {}".format(dtask.id, dtask.name), chat)
def duplicate_task(cls, msg, chat): """This function duplicates the task.""" if not msg.isdigit(): return "You must inform the task id" else: task_id = int(msg) query = db.session.query(Task).filter_by(id=task_id, chat=chat) try: task = query.one() except sqlalchemy.orm.exc.NoResultFound: return "_404_ Task {} not found x.x".format(task_id) dtask = Task(chat=task.chat, name=task.name, status=task.status, dependencies=task.dependencies, parents=task.parents, priority=task.priority, overdue=task.overdue, duedate=task.duedate) db.session.add(dtask) for dependency in task.dependencies.split(',')[:-1]: query = db.session.query(Task).filter_by(id=int(dependency), chat=chat) dependency = query.one() dependency.parents += '{},'.format(dtask.id) db.session.commit() return "New task *TODO* [[{}]] {}".format(dtask.id, dtask.name)
def handle_file(code, task, file): task_obj = Task.get(name=task) data = get_data_for_code(code) if task_obj is None: return {"error": "Report type not found: " + str(task)}, 404 committee = data["group"]["codeName"] year = str(data["year"]) lp = str(data["study_period"]) name = task + "_" + committee + "_" + year + "_" + lp + ".pdf" path = "./uploads/" + year + "/lp" + lp + "/" + str( data["meeting_no"]) + "/" + str(committee) if not os.path.exists(path): os.makedirs(path) save_loc = path + "/" + name print("Saving file " + str(file) + " in " + path) file.save(save_loc) code_file = CodeFile.get(code=code, task=task) if code_file is None: CodeFile(code=code, task=task, file_location=save_loc) return {"overwrite": False} else: print("OVERWRITE!") code_file.date = datetime.datetime.now() return {"overwrite": True}
def do_t_purge(self, line): parser = self.parser_t_purge() options, args = parser.parse_args(line) filters=[] filters.append(Task.q.status=="done") filters.append(Task.q.doneDate<(datetime.now()-timedelta(days=options.delay))) tasks=Task.select(AND(*filters)) if tasks.count()==0: print "No tasks need to be purged" return print "The following tasks will be removed:" print "\n".join(["%s: %s" % (task.id, task.title) for task in tasks]) if options.force or tui.confirm("Do you really want to remove those tasks (this action cannot be undone)?"): Task.deleteMany(AND(*filters)) print "Tasks deleted" else: print "Purge canceled"
def get_last_task_day(user): try: last_task = Task.select(Task.day).where( Task.user == user, Task.changeset.is_null(False)).order_by(Task.day.desc()).get() return last_task.day except Task.DoesNotExist: return None
def changeset(): if 'osm_token' not in session: redirect(url_for('login')) cs_data = request.args.get('changeset') if not cs_data.strip(): return redirect(url_for('front')) user = get_user() # TODO: call submit_changeset instead try: changeset = parse_changeset_id(cs_data) cs_date, conforms = validate_changeset(user, changeset, None, openstreetmap) except ValueError as e: flash(str(e)) return redirect(url_for('front')) if not cs_date or cs_date != today(): flash('Date of the changeset is wrong') return redirect(url_for('front')) task = Task.get(Task.user == user, Task.day == cs_date) try: last_task = Task.select(Task.day).where( Task.user == user, Task.changeset.is_null(False)).order_by(Task.day.desc()).get() is_streak = last_task.day == cs_date - cs_date.resolution except Task.DoesNotExist: is_streak = False task.changeset = changeset task.correct = conforms if is_streak: user.streak += 1 else: user.streak = 1 user.score += int(math.log(user.streak + 1, 2)) if conforms: flash('An extra point for completing the task') user.score += 1 if user.level < len(config.LEVELS) + 1: if user.score >= config.LEVELS[user.level - 1]: user.level += 1 flash('Congratulations on gaining a level!') with database.atomic(): task.save() user.save() flash('Changeset noted, thank you!') return redirect(url_for('front'))
def get_tasks(): arr = [] tasks = Task.select() for task in tasks: arr.append({"name": task.name, "display_name": task.display_name}) print("===SAVING {0} {1}===".format(len(arr), "Tasks")) return arr
def taskIdCompleter(cmd, text, line, begidx, endidx): #TODO: filter on parameter position #TODO: potential performance issue with lots of tasks, find a better way to do it tasks=[x for x in Task.select(Task.q.status!='done') if str(x.id).startswith(text)] print for task in tasks: # Move that in a renderer class ? print "%s: %s / %s" % (task.id, task.project.name, task.title) return [str(x.id) for x in tasks]
def random_task_for_user(user): tasks = set(get_tasks(user.level)) if not tasks: return None last_tasks = set([ x[0] for x in Task.select(Task.task).where(Task.user == user).order_by( Task.day.desc()).limit(int(len(tasks) * 0.7)).tuples() ]) return choice(list(tasks - last_tasks))
def testMark(self): tui.addInputAnswers("y") self.cmd.do_t_add("x t1") task = Task.get(1) self.assertEqual(task.status, "new") self.cmd.do_t_mark_started("1") self.assertEqual(task.status, "started") self.cmd.do_t_mark_done("1") self.assertEqual(task.status, "done")
def create_task(journal_id): journal = Journal.query.filter_by(id = journal_id).first() if journal is None: return failure_response("Journal not found") body = json.loads(request.data) description = body.get("description") if description is None: return failure_response("No description provided") new_task = Task( description = description, done = body.get("done", False), journal_id = journal_id ) db.session.add(new_task) db.session.commit() return success_response(new_task.serialize())
def new(self, message, chat, apiBot): """ Function description. :type message: string :type chat: int """ task = Task(chat=chat, name=message, status='TODO', dependencies='', parents='', priority='low', duedate=datetime.date(2100, 12, 12)) issue = repository.create_issue(message) task.issue_number = issue.number db.session.add(task) db.session.commit() apiBot.send_message( "New task *TODO* [[{}]] {}".format(task.id, task.name), chat)
def newTask(self, msg, chat): text, msg = self.checkMsg(msg) if text == '': task = Task(chat=chat, name=msg, status='TODO', dependencies='', parents='', priority='') db.session.add(task) db.session.commit() self.send_message( "New task *TODO* [[{}]] {}".format(task.id, task.name), chat) self.upload_github_issue( task.name, 'ID : [{}]\n\ Name : [{}]\n\ Priority : [None]\n\ Issue created from and with 404tasknotfoundbot tasks' .format(task.id, task.name)) else: if text.lower() not in ['high', 'medium', 'low']: self.send_message( "The priority *must be* one of the following: high, medium, low", chat) else: priority = text.lower() task = Task(chat=chat, name=msg, status='TODO', dependencies='', parents='', priority=priority) db.session.add(task) db.session.commit() self.send_message( "New task *TODO* [[{}]] {} with priority {}".format( task.id, task.name, task.priority), chat) self.upload_github_issue( task.name, 'ID : [{}]\n\ Name : [{}]\n\ Priority : [{}]\n\ Issue created from and with 404tasknotfoundbot tasks' .format(task.id, task.name, task.priority))
def new(chat, msg): task = Task(chat=chat, name=msg, status='TODO', dependencies='', parents='', priority='') db.session.add(task) db.session.commit() send_message("New task *TODO* [[{}]] {}".format(task.id, task.name), chat)
def clear_skipped(pid): project = Project.get(Project.id == pid) user = get_user() if user: features = Feature.select().where(Feature.project == project) query = Task.delete().where( Task.user == user, Task.skipped == True, Task.feature.in_(features)) query.execute() return redirect(url_for('project', name=project.name))
def testAddKeywords(self): tui.addInputAnswers("y") self.cmd.do_t_add("x t1") task = Task.get(1) tui.addInputAnswers("y", "y") self.cmd.do_t_add_keywords("1 @kw1 @kw2=12") kwDict = task.getKeywordDict() self.assertEqual(kwDict, dict(kw1=None, kw2=12))
def testAdd(self): tui.addInputAnswers("y", "2", "4", "123") self.cmd.do_bug_add("x t1") tui.addInputAnswers("n") self.cmd.do_bug_add("notExistingProject newBug") tasks = list(Task.select()) result = [x.title for x in tasks] expected = [u"t1"] self.assertEqual(result, expected) kwDict = Task.get(1).getKeywordDict() self.assertEqual(kwDict, dict(_severity=2, _likelihood=4, _bug=123)) for bad_input in ("", # No project "x", # No task name "x t1"): # Existing task self.assertRaises(YokadiException, self.cmd.do_bug_add, bad_input)
def eventLoop(): """Main event loop""" delta=timedelta(hours=float(Config.byName("ALARM_DELAY").value)) suspend=timedelta(hours=float(Config.byName("ALARM_SUSPEND").value)) cmdDelayTemplate=Config.byName("ALARM_DELAY_CMD").value cmdDueTemplate=Config.byName("ALARM_DUE_CMD").value # For the two following dict, task id is key, and value is (duedate, triggerdate) triggeredDelayTasks={} triggeredDueTasks={} activeTaskFilter=[Task.q.status!="done", Task.q.projectID == Project.q.id, Project.q.active == True] while event[0]: time.sleep(DELAY) now=datetime.today().replace(microsecond=0) delayTasks=Task.select(AND(Task.q.dueDate < now+delta, Task.q.dueDate > now, *activeTaskFilter)) dueTasks=Task.select(AND(Task.q.dueDate < now, *activeTaskFilter)) processTasks(delayTasks, triggeredDelayTasks, cmdDelayTemplate, suspend) processTasks(dueTasks, triggeredDueTasks, cmdDueTemplate, suspend)
def testAdd(self): tui.addInputAnswers("y") self.cmd.do_t_add("x t1") tui.addInputAnswers("y", "y") self.cmd.do_t_add("x @kw1 @kw2=12 t2") tui.addInputAnswers("n") self.cmd.do_t_add("notExistingProject newTask") tasks = list(Task.select()) result = [x.title for x in tasks] expected = [u"t1", u"t2"] self.assertEqual(result, expected) kwDict = Task.get(2).getKeywordDict() self.assertEqual(kwDict, dict(kw1=None, kw2=12)) for bad_input in ("", # No project "x", # No task name "x t1"): # Existing task self.assertRaises(YokadiException, self.cmd.do_t_add, bad_input)
def do_t_remove(self, line): parser = self.parser_t_remove() options, args = parser.parse_args(line) task=dbutils.getTaskFromId(' '.join(args)) if not options.force: if not tui.confirm("Remove task '%s'" % task.title): return projectId = task.project.id task.destroySelf() print "Task '%s' removed" % (task.title) # Delete project with no associated tasks if Task.select(Task.q.projectID == projectId).count() == 0: Project.delete(projectId)
def addTask(projectName, title, keywordDict): """Adds a task based on title and keywordDict. @param projectName: name of project as a string @param title: task title as a string @param keywordDict: dictionary of keywords (name : value) @returns : Task instance on success, None if cancelled.""" # Create missing keywords if not createMissingKeywords(keywordDict.keys()): return None # Create missing project project = getOrCreateProject(projectName) if not project: return None # Create task try: task = Task(creationDate=datetime.now(), project=project, title=title, description="", status="new") task.setKeywordDict(keywordDict) except DuplicateEntryError: raise YokadiException("A task named %s already exists in this project. Please find another name" % title) return task
def do_p_remove(self, line): parser = self.parser_p_remove() options, args = parser.parse_args(line) project = getProjectFromName(' '.join(args)) if not options.force: if not tui.confirm("Remove project '%s' and all its tasks" % project.name): return taskList = Task.select(Task.q.projectID == project.id) taskList = list(taskList) print "Removing project tasks:" for task in taskList: task.delete(task.id) print "- task %(id)-3s: %(title)-30s" % dict(id=str(task.id), title=str(task.title)) project.delete(project.id) print "Project removed"
def testAddKeywords(self): tui.addInputAnswers("y") self.cmd.do_t_add("x t1") task = Task.get(1) tui.addInputAnswers("y", "y") self.cmd.do_t_add_keywords("1 @kw1 @kw2=12") kwDict = task.getKeywordDict() self.assertEqual(kwDict, dict(kw1=None, kw2=12)) for bad_input in ("", # No task "1", # No keyword "1 kw1"): # No @ before kw1 self.assertRaises(YokadiException, self.cmd.do_t_add_keywords, bad_input)
def main(): #TODO: check that yokadid is not already running for this database ? Not very harmful... #TODO: change unix process name to "yokadid" # Make the event list global to allow communication with main event loop global event (options, args) = parseOptions() if options.kill: killYokadid(options.filename) sys.exit(0) signal(SIGTERM, sigTermHandler) signal(SIGHUP, sigHupHandler) if not options.foreground: doubleFork() if not options.filename: options.filename = os.path.join(os.path.expandvars("$HOME"), ".yokadi.db") print "Using default database (%s)" % options.filename connectDatabase(options.filename, createIfNeeded=False) # Basic tests : if not (Task.tableExists() and Config.tableExists()): print "Your database seems broken or not initialised properly. Start yokadi command line tool to do it" sys.exit(1) # Start ical http handler if options.icalserver: yokadiIcalServer = YokadiIcalServer(options.tcpPort, options.tcpListen) yokadiIcalServer.start() # Start the main event Loop try: while event[1] != "SIGTERM": eventLoop() event[0] = True except KeyboardInterrupt: print "\nExiting..."
def testRecurs(self): tui.addInputAnswers("y") self.cmd.do_t_add("x t1") task = Task.get(1) self.cmd.do_t_recurs("1 daily 10:00") desc = str(task.recurrence) self.cmd.do_t_recurs("1 weekly FR 23:00") self.cmd.do_t_recurs("1 weekly fr 23:00") self.cmd.do_t_recurs("1 weekly Fr 23:00") self.cmd.do_t_recurs("1 weekly Friday 23:00") self.cmd.do_t_recurs("1 monthly 3 13:00") self.cmd.do_t_recurs("1 monthly second friday 13:00") self.cmd.do_t_recurs("1 yearly 3/07 11:20") self.cmd.do_t_recurs("1 quarterly 14 11:20") self.cmd.do_t_recurs("1 quarterly first monday 23:20") self.assertNotEqual(desc, str(task.recurrence)) self.assertEqual(task.status, "new") self.cmd.do_t_mark_done("1") self.assertEqual(task.status, "new")
def getTaskFromId(line, parameterName="id"): """Returns a task given its id, or raise a YokadiException if it does not exist. @param line: taskId string @param parameterName: name of the parameter to mention in exception @return: Task instance or None if existingTask is False""" line = line.strip() if len(line) == 0: raise YokadiException("Missing <%s> parameter" % parameterName) # We do not use line.isdigit() because it returns True if line is '¹'! try: taskId = int(line) except ValueError: raise YokadiException("<%s> should be a number" % parameterName) try: return Task.get(taskId) except SQLObjectNotFound: raise YokadiException("Task %s does not exist. Use t_list to see all tasks" % taskId)
def do_t_list(self, line): def selectRendererClass(): if options.format != "auto": return gRendererClassDict[options.format] defaultRendererClass = TextListRenderer if not options.output: return defaultRendererClass ext = os.path.splitext(options.output)[1] if not ext: return defaultRendererClass return gRendererClassDict.get(ext[1:], defaultRendererClass) #BUG: completion based on parameter position is broken when parameter is given parser = self.parser_t_list() options, args = parser.parse_args(line) if len(args) > 0: projectName, keywordFilters = parseutils.extractKeywords(u" ".join(args)) else: projectName = "" keywordFilters = [] if self.kFilters: # Add keyword filter keywordFilters.extend(self.kFilters) if not projectName: if self.pFilter: # If a project filter is defined, use it as none was provided projectName = self.pFilter else: # Take all project if none provided projectName = "%" if projectName.startswith("!"): projectName = projectName[1:] projectList = Project.select(NOT(LIKE(Project.q.name, projectName))) else: projectList = Project.select(LIKE(Project.q.name, projectName)) if projectList.count() == 0: tui.error("Found no project matching '%s'" % projectName) return # Check keywords exist parseutils.warnIfKeywordDoesNotExist(keywordFilters) # Filtering and sorting according to parameters filters = [] # Filter on keywords for keywordFilter in keywordFilters: filters.append(keywordFilter.filter()) order = -Task.q.urgency, Task.q.creationDate limit = None if options.done: filters.append(Task.q.status == 'done') if options.done != "all": filters.append(parseutils.createFilterFromRange(options.done)) elif not options.all: filters.append(Task.q.status != 'done') if options.topUrgent: order = -Task.q.urgency limit = 5 if options.topDue: filters.append(Task.q.dueDate != None) order = Task.q.dueDate limit = 5 if options.overdue: filters.append(Task.q.dueDate < datetime.now()) order = Task.q.dueDate if options.search: for word in options.search: filters.append(OR(LIKE(Task.q.title, "%" + word + "%"), LIKE(Task.q.description, "%" + word + "%"))) # Define output if options.output: out = open(options.output, "w") else: out = tui.stdout # Instantiate renderer rendererClass = selectRendererClass() renderer = rendererClass(out) # Fill the renderer if options.keyword: if options.keyword.startswith("@"): options.keyword = options.keyword[1:] for keyword in Keyword.select(LIKE(Keyword.q.name, options.keyword)): if unicode(keyword.name).startswith("_") and not options.keyword.startswith("_"): #BUG: cannot filter on db side because sqlobject does not understand ESCAPE needed whith _ continue taskList = Task.select(AND(TaskKeyword.q.keywordID == keyword.id, *filters), orderBy=order, limit=limit, distinct=True, join=LEFTJOINOn(Task, TaskKeyword, Task.q.id == TaskKeyword.q.taskID)) taskList = list(taskList) if projectList: taskList = [x for x in taskList if x.project in projectList] if len(taskList) == 0: continue renderer.addTaskList(unicode(keyword), taskList) # Call renderer renderer.end() else: hiddenProjectNames = [] for project in projectList: if not project.active: hiddenProjectNames.append(project.name) continue taskList = Task.select(AND(Task.q.projectID == project.id, *filters), orderBy=order, limit=limit, distinct=True, join=LEFTJOINOn(Task, TaskKeyword, Task.q.id == TaskKeyword.q.taskID)) taskList = list(taskList) if len(taskList) == 0: continue renderer.addTaskList(unicode(project), taskList) renderer.end() if len(hiddenProjectNames) > 0: tui.info("hidden projects: %s" % ", ".join(hiddenProjectNames))
osc = changes_to_osc(changes, changeset_id) resp = requests.post('{0}/api/0.6/changeset/{1}/upload'.format(API_ENDPOINT, changeset_id), osc, auth=oauth) if resp.status_code == 200: task.status = 'done' task.error = str(changeset_id) else: # We don't want to exit before closing the changeset task.status = 'error' task.error = 'Server rejected the changeset with code {0}: {1}'.format(resp.code, resp.text) task.save() finally: resp = requests.put('{0}/api/0.6/changeset/{1}/close'.format(API_ENDPOINT, changeset_id), auth=oauth) if __name__ == '__main__': if not lock(): sys.exit(0) database.connect() database.create_tables([Task], safe=True) try: task = Task.get(Task.pending) except Task.DoesNotExist: # Yay, no jobs for us. sys.exit(0) try: process(task) except Exception as e: update_status_exit_on_error(task, 'system error', str(e))
def do_t_list(self, line): doneRangeList= ["today", "thisweek", "thismonth"] def keywordDictIsSubsetOf(taskKeywordDict, wantedKeywordDict): # Returns true if taskKeywordDict is a subset of wantedKeywordDict # taskKeywordDict is considered a subset of wantedKeywordDict if: # 1. All wantedKeywordDict keys are in taskKeywordDict # 2. All wantedKeywordDict valued keywords have the same value # in taskKeywordDict for wantedKeyword, wantedValue in wantedKeywordDict.items(): if not wantedKeyword in taskKeywordDict: return False if wantedValue and taskKeywordDict[wantedKeyword] != wantedValue: return False return True def taskHasWantedKeywordDict(task, wantedKeywordDict): """ @param task: task object @param wantedKeywordDict: dict of name/value of wanted keyword # a task is considered a subset of wantedKeywordDict if: # 1. All wantedKeywordDict keys are in task or project keywords # 2. All wantedKeywordDict valued keywords have the same value # in task or project keyword""" for wantedKeyword, wantedValue in wantedKeywordDict.items(): taskFilters=[Task.q.id==task.id, TaskKeyword.q.taskID==task.id, TaskKeyword.q.keywordID==Keyword.q.id, LIKE(Keyword.q.name, wantedKeyword)] projectFilters=[Project.q.id==task.projectID, ProjectKeyword.q.projectID==Project.q.id, ProjectKeyword.q.keyword==Keyword.q.id, LIKE(Keyword.q.name, wantedKeyword)] if wantedValue: taskFilters.append(TaskKeyword.q.value==wantedValue) projectFilters.append(ProjectKeyword.q.value==wantedValue) if Task.select(AND(*taskFilters)).count()==0 and Task.select(AND(*projectFilters)).count()==0: return False # All critera were met, return ok return True def createFilterFromRange(_range): # Parse the _range string and return an SQLObject filter minDate = date.today() if _range == "today": pass elif _range == "thisweek": minDate -= timedelta(minDate.weekday()) elif _range == "thismonth": minDate = minDate.replace(day = 1) else: raise YokadiException("Invalid range value '%s'" % _range) return Task.q.doneDate>=minDate def selectRendererClass(): if options.format != "auto": return gRendererClassDict[options.format] defaultRendererClass = TextListRenderer if not options.output: return defaultRendererClass ext = os.path.splitext(options.output)[1] if not ext: return defaultRendererClass return gRendererClassDict.get(ext[1:], defaultRendererClass) #BUG: completion based on parameter position is broken when parameter is given parser = self.parser_t_list() options, args = parser.parse_args(line) if len(args) > 0: projectName, keywordDict = parseutils.extractKeywords(u" ".join(args)) else: projectName = "" keywordDict = {} if not projectName: # Take all project if none provided projectName="%" projectList = Project.select(LIKE(Project.q.name, projectName)) if projectList.count()==0: tui.error("Found no project matching '%s'" % projectName) return # Check keywords exist for keyword in keywordDict.keys(): if Keyword.select(LIKE(Keyword.q.name, keyword)).count()==0: tui.error("Keyword %s is unknown." % keyword) # Filtering and sorting according to parameters filters=[] order=-Task.q.urgency, Task.q.creationDate limit=None if options.done: filters.append(Task.q.status=='done') if options.done != "all": filters.append(createFilterFromRange(options.done)) elif not options.all: filters.append(Task.q.status!='done') if options.topUrgent: order=-Task.q.urgency limit=5 if options.topDue: filters.append(Task.q.dueDate!=None) order=Task.q.dueDate limit=5 if options.search: for word in options.search: filters.append(OR(LIKE(Task.q.title, "%"+word+"%"), LIKE(Task.q.description, "%"+word+"%"))) # Define output if options.output: out = open(options.output, "w") else: out = tui.stdout # Instantiate renderer rendererClass = selectRendererClass() renderer = rendererClass(out) # Fill the renderer if options.keyword: if options.keyword.startswith("@"): options.keyword = options.keyword[1:] for keyword in Keyword.select(LIKE(Keyword.q.name, options.keyword)): if unicode(keyword.name).startswith("_") and not options.keyword.startswith("_"): #BUG: cannot filter on db side because sqlobject does not understand ESCAPE needed whith _ continue taskList = Task.select(AND(TaskKeyword.q.taskID == Task.q.id, TaskKeyword.q.keywordID == keyword.id, *filters), orderBy=order, limit=limit) taskList = list(taskList) if keywordDict: # FIXME: factorize (see project oriented rendering below) taskList = [x for x in taskList if taskHasWantedKeywordDict(x, keywordDict)] if projectList: taskList = [x for x in taskList if x.project in projectList] if len(taskList) == 0: continue renderer.addTaskList(unicode(keyword), taskList) # Call renderer renderer.end() else: hiddenProjectNames = [] for project in projectList: if not project.active: hiddenProjectNames.append(project.name) continue taskList = Task.select(AND(Task.q.projectID == project.id, *filters), orderBy=order, limit=limit) if keywordDict: taskList = [x for x in taskList if taskHasWantedKeywordDict(x, keywordDict)] else: taskList = list(taskList) if len(taskList) == 0: continue renderer.addTaskList(unicode(project), taskList) renderer.end() if len(hiddenProjectNames) > 0: tui.info("hidden projects: %s" % ", ".join(hiddenProjectNames))