def get(self, d): # Run after admin user logs in u = User.query().get() if u: today = datetime.today() g = Goal.CreateMonthly(u, date=today) g.Update(text=["Get it done"]) g2 = Goal.Create(u, str(today.year)) g2.Update(text=["Make progress"]) ndb.put_multi([g, g2]) h = Habit.Create(u) h.Update(name="Run") h.put() p = Project.Create(u) p.Update(title="Blog post", subhead="How Flow works") p.put() Task.Create(u, "Get this done").put() t = Task.Create(u, "Think hard", due=datetime.today()) t2 = Task.Create(u, "Think even harder", due=datetime.today()) message = "OK" else: message = "No user" self.json_out({'message': message})
def _habit_or_task_report(self, item_name): ''' Mark a habit or a task as complete ''' handled = False speech = None if item_name: habits = Habit.Active(self.user) for h in habits: if item_name.lower() in h.name.lower(): # TODO: Timezone? done, hd = HabitDay.Toggle(h, datetime.today().date(), force_done=True) encourage = random.choice(HABIT_DONE_REPLIES) speech = "%s '%s' is marked as complete." % (encourage, h.name) handled = True break if not handled: # Check tasks tasks = Task.Recent(self.user) for t in tasks: if item_name.lower() in t.title.lower(): t.mark_done() t.put() speech = "Task '%s' is marked as complete." % (t.title) handled = True break if not handled: speech = "I'm not sure what you mean by '%s'." % item_name else: speech = "I couldn't tell what habit or task you completed." return speech
def _habit_status(self): habits = Habit.All(self.user) today = self.user.local_time().date() habitday_keys = [ ndb.Key('HabitDay', HabitDay.ID(h, today), parent=self.user.key) for h in habits ] habitdays = ndb.get_multi(habitday_keys) n_habits_done = 0 habits_committed_undone = [] habits_done = [] for hd in habitdays: if hd: habit = hd.habit.get() if hd.committed and not hd.done: if habit: habits_committed_undone.append(habit.name) if hd.done: habits_done.append(habit.name) n_habits_done += 1 if habits: if n_habits_done: text = "Good work on doing %d %s (%s)!" % ( n_habits_done, tools.pluralize('habit', n_habits_done), tools.english_list(habits_done)) else: text = "No habits done yet." if habits_committed_undone: text += " Don't forget you've committed to %s." % tools.english_list( habits_committed_undone) else: text = "You haven't added any habits yet. Try saying 'add habit run'" return text
def update(self, d): ''' Create or update ''' id = self.request.get_range('id') params = tools.gets(self, strings=['name', 'description', 'color', 'icon'], booleans=['archived'], integers=['tgt_weekly'], supportTextBooleans=True ) habit = None if id: habit = self.user.get(Habit, id=id) else: name = params.get('name') if not name: self.message = "Name required" else: habit = Habit.Create(self.user) if habit: habit.Update(**params) habit.put() self.success = True self.set_response({ 'habit': habit.json() if habit else None })
def habit_index(): pubs = [] habits = Habit.objects().order_by("-start_Date") for habit in habits: if habit.is_public == "true": pubs.append(habit.to_public_json()) return jsonify(pubs)
def delete(self, d): id = self.request.get_range('id') habit = self.user.get(Habit, id=id) if habit: habit = Habit.get_by_id(int(id), parent=self.user.key) habit.key.delete() self.success = True self.set_response()
def test_habit_calls(self): # List response = self.get_json("/api/habit", {}, headers=self.api_headers) h = response.get('habits')[0] self.assertEqual(h.get('name'), "Run") # Update response = self.post_json("/api/habit", { 'id': h.get('id'), 'name': 'Walk' }, headers=self.api_headers) h = response.get('habit') self.assertEqual(h.get('name'), 'Walk') # Actions today = datetime.now() DAY = tools.iso_date(today - timedelta(days=1)) hid = h.get('id') actions = [{ 'action': 'commit', 'expected_prop': 'committed' }, { 'action': 'toggle', 'expected_prop': 'done' }] for act in actions: params = {'habit_id': hid, 'date': DAY} response = self.post_json("/api/habit/%s" % act.get('action'), params, headers=self.api_headers) hd = response.get('habitday') prop = act.get('expected_prop') self.assertTrue(hd.get(prop)) # Recent response = self.get_json("/api/habit/recent", {'days': 3}, headers=self.api_headers) habitdays = response.get('habitdays') self.assertTrue(hd.get('id') in habitdays) # Recent params = { 'start_date': tools.iso_date(today - timedelta(days=2)), 'end_date': tools.iso_date(today) } response = self.get_json("/api/habit/range", params, headers=self.api_headers) habitdays = response.get('habitdays') self.assertTrue(hd.get('id') in habitdays) # Delete response = self.post_json("/api/habit/delete", {'id': h.get('id')}, headers=self.api_headers) h = Habit.get_by_id(h.get('id'), parent=self.u.key) self.assertIsNone(h) # Confirm deletion
def habits_user(username: str): try: user = User.objects(username=username).first() except ValidationError: return jsonify({"error": "User not found"}), 404 habits = Habit.objects(user=user).order_by("-start_Date") return jsonify([habit.to_public_json() for habit in habits])
def setUp(self): self.set_application(tst_app) self.setup_testbed() self.init_datastore_stub() self.init_memcache_stub() self.init_taskqueue_stub() self.init_mail_stub() self.init_app_basics() self.register_search_api_stub() u = self.users[0] habit_run = Habit.Create(u) habit_run.Update(name="Run") habit_run.put() self.habit_run = habit_run habit_read = Habit.Create(u) habit_read.Update(name="Read") habit_read.put() self.habit_read = habit_read
def habits_item(id: str): try: habit = Habit.objects(pk=id).first() # If habit has alreay been deleted if not habit: raise ValidationError except ValidationError: return jsonify({"error": "habit not found"}), 404 return jsonify(habit.to_public_json())
def habit_create(username: str): schema = Schema({ "name": And(str, len, error="Namr not specified"), "description": And(str, len, error="description not specified"), "num_Days": And(Use(int), error="Number of Days not specified"), "is_public": And(str, len, error="publicity not specified") }) form = { "name": request.form.get("name"), "description": request.form.get("description"), "num_Days": request.form.get("num_Days"), "is_public": request.form.get("is_public") } validated = schema.validate(form) temp_data = [] user = User.objects(username=username).first() for i in range(validated["num_Days"]): temp_data.append(["false", 0, 0]) habit = Habit( user=user, name=validated["name"], description=validated["description"], num_Days=validated["num_Days"], repeat=[], start_Date=datetime.now(), string_start=datetime.strftime( datetime.now(), "%B %m, %Y" ), #A list with the month in mm format and day in the dd format curr_Date=datetime.now(), end_Date=datetime.now() + timedelta(days=int(validated["num_Days"])), is_public=validated["is_public"], habit_data=temp_data).save() return jsonify(habit.to_public_json())
def habit_update(username: str, id: str): x = request.form.get("habit_data") y = "" habit_data = [] data = [] for i in x: if i == 't': y += 't' elif i == 'r': y += 'r' elif i == 'u': y += 'u' elif i == 'e': y += 'e' data.append(y) y = "" elif i == 'f': y += 'f' elif i == 'a': y += 'a' elif i == 'l': y += 'l' elif i == 's': y += 's' elif i == "0": if len(data) == 2: data.append(0) habit_data.append(data) data = [] else: data.append(0) schema = Schema({ #"habit_data": And(Use(list), error="habit_data not specified") }) form = { #"habit_data": request.form.get("habit_data"), } validated = schema.validate(form) try: habit = Habit.objects(pk=id).first() if not habit: raise ValidationError except ValidationError: return jsonify({"error": "Grid not found"}), 404 habit.habit_data = habit_data if username != habit.user.username: return jsonify({"error": "You are not the creator of the grid"}), 401 else: habit.save() return jsonify(habit.to_public_json())
def range(self, d): ''' Return recent days of all active habits ''' start = self.request.get('start_date') end = self.request.get('end_date') habits = Habit.Active(self.user) habitdays = HabitDay.Range(self.user, habits, tools.fromISODate(start), until_date=tools.fromISODate(end)) self.set_response({ 'habits': [habit.json() for habit in habits], 'habitdays': tools.lookupDict(habitdays, keyprop="key_id", valueTransform=lambda hd: hd.json()) }, success=True)
def test_habit_report(self): habit_run = Habit.Create(self.u) habit_run.Update(name="Run") habit_run.put() marked_done, hd = HabitDay.Toggle(habit_run, datetime.today()) self._test_report( {'type': REPORT.HABIT_REPORT}, [["Created", "Updated", "Date", "Habit", "Done", "Committed"], [ tools.sdatetime(hd.dt_created, fmt="%Y-%m-%d %H:%M:%S %Z"), tools.sdatetime(hd.dt_updated, fmt="%Y-%m-%d %H:%M:%S %Z"), tools.iso_date(datetime.now()), "Run", "1", "0" ]])
def recent(self, d): ''' Return recent days of all active habits ''' self.success = True days = self.request.get_range('days', default=5) habits = Habit.Active(self.user) start_date = datetime.today() - timedelta(days=days) habitdays = HabitDay.Range(self.user, habits, start_date) self.set_response({ 'habits': [habit.json() for habit in habits], 'habitdays': tools.lookupDict(habitdays, keyprop="key_id", valueTransform=lambda hd: hd.json()) })
def toggle(self, d): ''' Mark done/not-done for a habit day ''' from constants import HABIT_DONE_REPLIES habit_id = self.request.get_range('habit_id') day_iso = self.request.get('date') habit = Habit.get_by_id(habit_id, parent=self.user.key) hd = None if habit: marked_done, hd = HabitDay.Toggle(habit, tools.fromISODate(day_iso)) if marked_done: self.message = random.choice(HABIT_DONE_REPLIES) self.success = True self.set_response({'habitday': hd.json() if hd else None})
def test_habit_calls(self): # List response = self.get_json("/api/habit", {}, headers=self.api_headers) h = response.get('habits')[0] self.assertEqual(h.get('name'), "Run") # Update response = self.post_json("/api/habit", {'id': h.get('id'), 'name': 'Walk'}, headers=self.api_headers) h = response.get('habit') self.assertEqual(h.get('name'), 'Walk') # Actions today = datetime.now() DAY = tools.iso_date(today - timedelta(days=1)) hid = h.get('id') actions = [ {'action': 'commit', 'expected_prop': 'committed'}, {'action': 'toggle', 'expected_prop': 'done'} ] for act in actions: params = { 'habit_id': hid, 'date': DAY } response = self.post_json("/api/habit/%s" % act.get('action'), params, headers=self.api_headers) hd = response.get('habitday') prop = act.get('expected_prop') self.assertTrue(hd.get(prop)) # Recent response = self.get_json("/api/habit/recent", {'days': 3}, headers=self.api_headers) habitdays = response.get('habitdays') self.assertTrue(hd.get('id') in habitdays) # Recent params = { 'start_date': tools.iso_date(today - timedelta(days=2)), 'end_date': tools.iso_date(today) } response = self.get_json("/api/habit/range", params, headers=self.api_headers) habitdays = response.get('habitdays') self.assertTrue(hd.get('id') in habitdays) # Delete response = self.post_json("/api/habit/delete", {'id': h.get('id')}, headers=self.api_headers) h = Habit.get_by_id(h.get('id'), parent=self.u.key) self.assertIsNone(h) # Confirm deletion
def _habit_commit(self, habit_param_raw): handled = False speech = None if habit_param_raw: habits = Habit.Active(self.user) for h in habits: if habit_param_raw.lower() in h.name.lower(): # TODO: Timezone? hd = HabitDay.Commit(h, datetime.today().date()) encourage = random.choice(HABIT_COMMIT_REPLIES) speech = "You've committed to '%s' today. %s" % (h.name, encourage) handled = True break if not handled: speech = "I'm not sure what you mean by '%s'. You may need to create a habit before you can commit to it." % habit_param_raw else: speech = "I couldn't tell what habit you want to commit to." return speech
def habits_delete(username: str, id: str): try: habit = Habit.objects(pk=id).first() # If habit has alreay been deleted if not habit: raise ValidationError except ValidationError: return jsonify({"error": "Grid not found"}), 404 # Check whether action was called by creator of the habit if username != habit.user.username: return jsonify({"error": "You are not the creator of the grid"}), 401 habit_info = habit.to_public_json() habit.delete() return jsonify(habit_info)
def add_new_event_type(): event_type = request.form.get("eventType") label = request.form.get("label") unit = request.form.get("unit") user = get_user() invalid_message = validate_new_event_type(label) if invalid_message: return invalid_message if event_type == "habit": new_event_type = Habit(label=label, unit=unit, user_id=user.id) elif event_type == "influence": new_event_type = Influence(label=label, scale=unit, user_id=user.id) elif event_type == "symptom": new_event_type = Symptom(label=label, scale=unit, user_id=user.id) db.session.add(new_event_type) db.session.commit() if event_type == "habit": new_obj = Habit.query.filter(Habit.label == label, Habit.user == user).one() new_id = new_obj.id elif event_type == "influence": new_obj = Influence.query.filter(Influence.label == label, Influence.user == user).one() new_id = new_obj.id elif event_type == "symptom": new_obj = Symptom.query.filter(Symptom.label == label, Symptom.user == user).one() new_id = new_obj.id return json.dumps({ "new_id": new_id, "success": f"New {event_type} added successfully!" })
def setUp(self): self.set_application(tst_app) self.setup_testbed() self.init_datastore_stub() self.init_memcache_stub() self.init_taskqueue_stub() self.init_mail_stub() self.register_search_api_stub() self.init_app_basics() self.u = u = self.users[0] self.u.Update(name="George") self.u.put() h = Habit.Create(u) h.Update(name="Run") h.put() t = Task.Create(u, "Dont forget the milk") t.put() g = Goal.CreateMonthly(u, date=datetime.today().date()) g.Update(text=["Get it done", "Also get exercise"]) g.put()
def _habit_or_task_report(self, item_name): ''' Mark a habit or a task as complete ''' handled = False speech = None if item_name: habits = Habit.Active(self.user) for h in habits: if item_name.lower() in h.name.lower(): d = self.user.local_time().date() encourage = random.choice(HABIT_DONE_REPLIES) if h.has_daily_count(): done, hd = HabitDay.Increment(h, d) speech = "%s The count of '%s' has been increased to %d " % ( encourage, h.name, hd.count) remaining = h.tgt_daily - hd.count speech += "(habit complete!)" if not remaining else "(%d to go)" % remaining else: done, hd = HabitDay.Toggle(h, d, force_done=True) speech = "%s '%s' is marked as complete." % (encourage, h.name) handled = True break if not handled: # Check tasks tasks = Task.Recent(self.user) for t in tasks: if item_name.lower() in t.title.lower(): t.mark_done() t.put() speech = "Task '%s' is marked as complete." % (t.title) handled = True break if not handled: speech = "I'm not sure what you mean by '%s'." % item_name else: speech = "I couldn't tell what habit or task you completed." return speech
def get(self, d): # TODO: Async fetches with_habits = self.request.get_range('with_habits', default=0) == 1 with_tracking = self.request.get_range('with_tracking', default=1) == 1 with_goals = self.request.get_range('with_goals', default=1) == 1 with_tasks = self.request.get_range('with_tasks', default=1) == 1 date_start = self.request.get('date_start') date_end = self.request.get('date_end') dt_start, dt_end = tools.fromISODate(date_start), tools.fromISODate( date_end) iso_dates = [] habits = [] today = datetime.today() habitdays = [] goals = [] journals, iso_dates = MiniJournal.Fetch(self.user, dt_start, dt_end) if with_habits: habits = Habit.Active(self.user) habitdays = HabitDay.Range(self.user, habits, dt_start, dt_end) if with_tracking: tracking_days = TrackingDay.Range(self.user, dt_start, dt_end) if with_goals: goals = Goal.Year(self.user, today.year) if with_tasks: tasks = Task.DueInRange(self.user, dt_start, dt_end, limit=100) self.set_response( { 'dates': iso_dates, 'journals': [j.json() for j in journals if j], 'habits': [h.json() for h in habits], 'goals': [g.json() for g in goals], 'tasks': [t.json() for t in tasks], 'tracking_days': [p.json() for p in tracking_days], 'habitdays': tools.lookupDict(habitdays, keyprop="key_id", valueTransform=lambda hd: hd.json()) }, success=True)
def test_habit_calls(self): # List response = self.get_json("/api/habit", {}, headers=self.api_headers) h = response.get('habits')[0] self.assertEqual(h.get('name'), "Run") # Update response = self.post_json("/api/habit", { 'id': h.get('id'), 'name': 'Walk' }, headers=self.api_headers) h = response.get('habit') self.assertEqual(h.get('name'), 'Walk') # Actions DAY = '2017-01-02' hid = h.get('id') actions = [{ 'action': 'commit', 'expected_prop': 'committed' }, { 'action': 'toggle', 'expected_prop': 'done' }] for act in actions: params = {'habit_id': hid, 'date': DAY} response = self.post_json("/api/habit/%s" % act.get('action'), params, headers=self.api_headers) hd = response.get('habitday') prop = act.get('expected_prop') self.assertTrue(hd.get(prop)) # Delete response = self.post_json("/api/habit/delete", {'id': h.get('id')}, headers=self.api_headers) h = Habit.get_by_id(h.get('id'), parent=self.u.key) self.assertIsNone(h) # Confirm deletion
def _habit_add(self, habit): h = Habit.Create(self.user) h.Update(name=habit) h.put() return self._comply_banter() + ". Habit '%s' added." % h.name
def list(self, d): habits = Habit.All(self.user) self.set_response({ 'habits': [habit.json() for habit in habits] }, success=True)
def _maybe_get_habits(self): if self.habits is None: self.habits = tools.lookupDict(Habit.Active(self.user), "key_id")
def handle_habits(habit_id=None): """ handle habits for an authenticated user """ headers = {"Content-Type": "application/json"} # grab user auth_user = get_current_user() # check methods if request.method == "GET": # check if habit_id is not none if habit_id: # return specific habit details specific_habit = Habit.query.filter_by(id=habit_id).one_or_none() response_body = specific_habit.serialize() else: # return all user habits user_habits = Habit.query.filter_by(user_id=auth_user.id).all() response_body = [] for habit in user_habits: response_body.append(habit.serialize()) status_code = 200 elif request.method == "POST": # create habit, validate input... new_habit_data = request.json if set(("name", "personalMessage", "targetPeriod", "targetValue", "iconName", "toBeEnforced")).issubset(new_habit_data): # all data is present new_habit_name = new_habit_data["name"] new_habit_message = new_habit_data["personalMessage"] new_habit_period = new_habit_data["targetPeriod"] new_habit_value = new_habit_data["targetValue"] new_habit_icon = new_habit_data["iconName"] new_habit_enforcement = new_habit_data["toBeEnforced"] if (new_habit_name and new_habit_message and new_habit_period and 0 < new_habit_value < 100 and new_habit_icon): # all values valid new_habit = Habit(new_habit_name, new_habit_message, new_habit_enforcement, new_habit_period, new_habit_value, new_habit_icon, auth_user.id) db.session.add(new_habit) try: db.session.commit() status_code = 201 result = f"HTTP_201_CREATED. habit successfully created with id: {new_habit.id}" response_body = {"result": result} except: db.session.rollback() status_code = 500 response_body = {"result": "something went wrong in db"} else: # some value is empty or invalid status_code = 400 response_body = { "result": "HTTP_400_BAD_REQUEST. received invalid input values..." } else: # some key is missing status_code = 400 response_body = { "result": "HTTP_400_BAD_REQUEST. some key is missing in request..." } elif request.method == "PUT": # only allowed if habit_id is not None if habit_id: habit_to_edit = Habit.query.filter_by(id=habit_id).one_or_none() if habit_to_edit: # editing habit with input habit_data = request.json if set( ("name", "personalMessage", "targetPeriod", "targetValue", "iconName", "toBeEnforced")).issubset(habit_data): # all data is present habit_to_edit.update(habit_data) try: db.session.commit() status_code = 200 response_body = { "result": "HTTP_200_OK. habit successfully updated" } except IntegrityError: print("some error on db saving op") db.session.rollback() status_code = 400 response_body = { "result": "HTTP_400_BAD_REQUEST. same user can't have two habits named the same!" } else: status_code = 400 response_body = { "result": "HTTP_400_BAD_REQUEST. check inputs, some key is missing, this is PUT method, all keys required..." } else: # oh boy, no such habit... status_code = 404 response_body = { "result": "HTTP_404_NOT_FOUND. oh boy, no such habit here..." } else: # what? no habit_id shouldn't even get in here status_code = 500 response_body = { "result": "HTTP_666_WTF. this should not be able to happen..." } elif request.method == "DELETE": # check if habit_id and delete if habit_id: habit_to_delete = Habit.query.filter_by(id=habit_id).one_or_none() if habit_to_delete: try: db.session.delete(habit_to_delete) db.session.commit() status_code = 204 response_body = {} except: # something went wrong in db committing print("dunno...") status_code = 500 response_body = { "result": "HTTP_500_INTERNAL_SERVER_ERROR. something went wrong on db..." } else: # habit does not exist... status_code = 404 response_body = { "result": "HTTP_404_NOT_FOUND. oh boy, no such habit here..." } else: status_code = 500 response_body = { "result": "HTTP_666_WTF. you should not be here..." } return make_response(json.dumps(response_body), status_code, headers)