def TitlePicker(): X, Y = C.SCR_X - 4, 5 # Clear Text Region G.screen.ClearTextArea() helpString = "Enter Title: " G.screen.Display(helpString, X, 5, color=C.SCR_COLOR_MAGENTA, bold=True) Y += len(helpString) while (1): inpTitle = G.screen.StringInput(X, Y) success = True if inpTitle == "": success = False if success: break DEBUG.Display(" Please enter a non-empty title string.") G.screen.ClearTextArea() G.screen.Display(helpString, X, 5, color=C.SCR_COLOR_MAGENTA, bold=True) DEBUG.Display("") return inpTitle
def Input(self): while (1): try: # Don't starve the book-keeping thread unnecessarily G.screen.Release() except: pass c = G.screen.GetCharacter() # Clear Notification Line DEBUG.Display(" ") if c == curses.KEY_UP or c == ord('k'): self.ScrollUp() elif c == curses.KEY_DOWN or c == ord('j'): self.ScrollDown() elif c == curses.KEY_LEFT or c == ord('h'): self.ScrollLeft() elif c == curses.KEY_RIGHT or c == ord('l'): self.ScrollRight() elif c == ord('m'): self.ToggleMark() elif c == ord('d'): self.ToggleDelete() elif c == ord('+'): self.ToggleMarkUp() elif c == ord('-'): self.ToggleMarkDown() elif c == ord('c'): self.Checklist() elif c == ord(':'): command = G.screen.Command() # Vim style exit if command == "q!": break if command == "wq": self.FlushChangesToQueue( ) #Write out things to the request queue G.reqManager.Flush() #Send the queue break if command == "q": self.FlushChangesToQueue() if (len(G.reqManager.MarkUpQueue) | len(G.reqManager.MarkDownQueue) | len(G.reqManager.MarkQueue) | len(G.reqManager.DeleteQueue) | len(G.reqManager.EditQueue)): DEBUG.Display( "No write since last change (add ! to override)") continue #Restart command loop break #exit G.screen.Display(" " * (C.SCR_Y - 1), C.SCR_X - 1, 0) self.Command(command)
def GetPartyData(self): DEBUG.Display("Please Wait...") resp = G.reqManager.FetchParty() DEBUG.Display(" ") partyObj = CT.Party(resp) partyObj.Display()
def __init__(self, party): self.party = party logger.debug("Party Object - \n %s" % str(party)) # Some Basic Details self.name = party['name'].encode('utf-8') #self.members = [str(i['profile']['name']) for i in party['members']] # V3 changes, members don't work no more :( self.members = ['(Member list not implemented)'] self.chat = party['chat'] chat_items = [] chatList = self.chat[:50] for i in chatList: timeElapsed = H.GetDifferenceTime(i['timestamp']) detailString = i.get('user', '') + " " + timeElapsed chat_items += [ M.SimpleTextItem(str(i['text'].encode("utf-8")), additional=str(detailString)) ] self.chatMenu = M.SimpleTextMenu(chat_items, C.SCR_TEXT_AREA_LENGTH) self.quest = party.get('quest', None) logger.debug("Current Quest: %s" % str(self.quest)) if self.quest != None: while (G.content == None): DEBUG.Display("Fetching Content...") time.sleep(5) DEBUG.Display(" ") self.questDetails = G.content.Quest( str(self.quest['key'].encode("utf-8"))) self.questText = str(self.questDetails['text'].encode("utf-8")) self.questType = "" self.progress = 0 if self.questDetails.has_key('boss'): self.questType = "boss" self.bossMaxHealth = self.questDetails['boss']['hp'] self.bossName = self.questDetails['boss']['name'] self.bossRage = self.questDetails['boss'].get('rage', None) self.bossStrength = self.questDetails['boss']['str'] if (party['quest']['active']): self.progress = int( round(party['quest']['progress']['hp'], 0)) elif self.questDetails.has_key('collect'): self.questType = "collect" self.questItems = self.questDetails['collect'] if (party['quest']['active']): self.progress = party['quest']['progress']['collect']
def FetchData(self): G.LastUpdate = datetime.datetime.now() #Get the user data from the API DEBUG.Display("Connecting...") user_json = self.FetchUserData() task_json = self.FetchUserTasks() DEBUG.Display("Connected") time.sleep(1) DEBUG.Display(" ") # Initialize User Stats G.user = U.User(user_json) # These will contain the menu items passed to create the Habit, Daily # and Todo menus habit_items = [] dailies_items = [] todos_items = [] logger.debug("Found %d tasks" % len(task_json)) for i in task_json: logger.debug("Processing a TODO: %s" % i['text'].encode("utf-8").strip()) if (i['type'] == "habit"): item = T.Habit(i) habit_items += [M.MenuItem(item, "habit", item.text)] elif (i['type'] == "daily"): item = T.Daily(i) dailies_items += [M.MenuItem(item, "daily", item.text)] elif (i['type'] == "todo"): if i['completed']: continue item = T.TODO(i) todos_items += [M.MenuItem(item, "todo", item.text)] elif (i['type'] == "reward"): logger.warn( "Custom Rewards aren't implemented yet, but the user has one: %s" % i['text']) else: logger.debug( "Weird task %s with type: %s" % (i['text'].encode("utf-8"), i['type'].encode("utf-8"))) raise ValueError("Unknown task type %s" % i['type'].encode("utf-8")) # Generate the menus for the display G.HabitMenu = M.Menu(habit_items, "Habits") G.DailyMenu = M.Menu(dailies_items, "Dailies") G.TODOMenu = M.Menu(todos_items, "TODOs")
def Input(self): DEBUG.Display("Press q to exit...") while (1): c = G.screen.GetCharacter() if c == curses.KEY_UP or c == ord('k'): self.ScrollUp() elif c == curses.KEY_DOWN or c == ord('j'): self.ScrollDown() elif c == 27 or c == ord('q'): break DEBUG.Display("Press q to exit...")
def Command(self, command): if command == "w": self.FlushChangesToQueue() #Write out things to the request queue G.reqManager.Flush() #Send the queue elif command == "r": self.FlushChangesToQueue() G.prevTask = None G.currentTask = None if (len(G.reqManager.MarkUpQueue) | len(G.reqManager.MarkDownQueue) | len(G.reqManager.MarkQueue) | len(G.reqManager.DeleteQueue) | len(G.reqManager.EditQueue)): DEBUG.Display( "Some writes are pending (add ! to ignore and reload anyway)" ) return self.Command("r!") elif command == "r!": G.prevTask = None G.currentTask = None self.FlushChangesToQueue() G.reqManager.ClearQueues() G.reqManager.FetchData() G.screen.Erase() self.Init() # User Stats while (G.content == None): DEBUG.Display("Fetching Content...") time.sleep(5) DEBUG.Display(" ") G.user.attrStats = H.GetUserStats(G.user.data) G.user.PrintUserStats() elif command == "party": G.screen.SaveInRegister(1) G.user.GetPartyData() G.screen.RestoreRegister(1) elif command == "data-display": CT.GetData() elif command == "help": H.HelpPage() else: self.Parser(command)
def Input(self): # This takes control away from Interface # Implemented specially for checklists and similar menus if self.menu_type == "checklist_menu": self.items[self.current].HighlightName() DEBUG.Display("(c) confirm; (q) cancel") self.backupItems = self.items[:-1] while (1): c = G.screen.GetCharacter() if c == curses.KEY_UP or c == ord('k'): self.ScrollUp() elif c == curses.KEY_DOWN or c == ord('j'): self.ScrollDown() elif c == ord('m'): if self.current != self.end - 1: self.items[self.current].ToggleMark() elif c == ord('d'): if self.current != self.end - 1: self.items[self.current].ToggleDelete() elif c == ord('\n'): self.items[self.current].EnterNewName() if self.current != self.end - 1: self.items[self.current].ToggleEdit() else: self.items[self.current].task.ChangeName() self.items[self.current].status.SetNewItem() self.items.append(T.DummyChecklistItem()) self.Reload() self.Init() self.items[self.current].HighlightName() elif c == ord('q') or c == 27: return 0 elif c == ord('c'): return 1
def ChangePriority(self, key): if self.task_type != "checklist" and self.task.isChallenge: # Cannot change the difficulty of a challenge task DEBUG.Display("Cannot change the diffifculty of a challenge task") return self.task.ChangePriority(key) self.status.ToggleEdit()
def DatePicker(): X, Y = C.SCR_X - 4, 5 # Clear Text Region G.screen.ClearTextArea() helpString = "Enter Date (dd/mm/yyyy): " G.screen.Display(helpString, X, 5, color=C.SCR_COLOR_MAGENTA, bold=True) Y += len(helpString) DEBUG.Display("Enter 'q' to exit.") while (1): inpDate = G.screen.StringInput(X, Y) if inpDate == "q": DEBUG.Display("") return finalDate = None success = False for dateFormat in C.DATEFORMATS: try: # Time will be the midnight of the previous day. So we need to add a day finalDate = (DateTime( datetime.strptime(inpDate, dateFormat) + timedelta(hours=23, minutes=59, seconds=59))) success = True if finalDate.date < DateTime(-1).date: success = False break except: pass if success: break DEBUG.Display("Invalid Date. Please try again. Enter 'q' to cancel.") G.screen.ClearTextArea() G.screen.Display(helpString, X, 5, color=C.SCR_COLOR_MAGENTA, bold=True) DEBUG.Display("") return finalDate
def CreateTask_orig(self, title, task_type): task = {} task['text'] = title.decode("utf-8") task['type'] = task_type task['priority'] = 1 if task_type == 'todo' or task_type == 'daily': task['checklist'] = [] if task_type == "daily": task['everyX'] = 1 task['frequency'] = 'weekly' task['repeat'] = { 'm': True, 't': True, 'w': True, 'th': True, 'f': True, 's': True, 'su': True } if task_type == "habit": task['up'] = True task['down'] = True DEBUG.Display("Creating Task...") ret_task = self.CreateTask(task) DEBUG.Display(" ") logger.debug(ret_task) if task_type == "habit": item = T.Habit(ret_task) menu_item = M.MenuItem(item, "habit", item.text) G.HabitMenu.Insert(menu_item) elif task_type == "daily": item = T.Daily(ret_task) menu_item = M.MenuItem(item, "daily", item.text) G.DailyMenu.Insert(menu_item) elif task_type == "todo": item = T.TODO(ret_task) menu_item = M.MenuItem(item, "todo", item.text) G.TODOMenu.Insert(menu_item)
def RemoveDueDate(self): if self.task_type != "todo": return if self.task_type != "checklist" and self.task.isChallenge: # Cannot change the due-date parameter of a challenge DEBUG.Display("Cannot change the due-date for a challenge TODO") return self.task.RemoveDueDate() self.status.SetDue("") self.status.ToggleEdit()
def Restore(self): # Stack cannot be empty if len(self.stack) == 0: return self.stackFile.seek(self.stack[-1]) self.screen = curses.getwin(self.stackFile) # Clear Notification Line DEBUG.Display(" ") self.Refresh()
def SetEvery(self, days): if self.task_type != "daily": return if self.task_type != "checklist" and self.task.isChallenge: # Cannot change the 'every x days' parameter of a challenge DEBUG.Display( "Cannot change the 'every x days' parameter of a challenge daily task" ) return self.task.SetEvery(days) self.status.ToggleEdit()
def SetWeekly(self, repeat): if self.task_type != "daily": return if self.task_type != "checklist" and self.task.isChallenge: # Cannot change the 'weekdays' parameter of a challenge DEBUG.Display( "Cannot change the 'weekdays' parameter of a challenge daily task" ) return self.task.SetWeekly(repeat) self.status.ToggleEdit()
def ChangeDueDate(self, date): if self.task_type != "todo": return if self.task_type != "checklist" and self.task.isChallenge: # Cannot change the due-date parameter of a challenge DEBUG.Display("Cannot change the due-date for a challenge TODO") return self.task.ChangeDueDate(date) self.status.SetDue(H.DateTime(date).DueDateFormat()) self.SetStatusXY() self.status.ToggleEdit()
def ToggleDelete(self): # Take care of challenge tasks if self.isChallenge: DEBUG.Display("Challenge tasks cannot be deleted from here") return # Nothing can be enabled along with delete for key in self.attributes: if key != C.SYMBOL_DELETE: self.attributes[key] = False if self.attributes[C.SYMBOL_DELETE]: self.attributes[C.SYMBOL_DELETE] = False else: self.attributes[C.SYMBOL_DELETE] = True
def RestoreRegister(self, register): # Should be between 0 and C.NUM_CONTEXT_REGISTERS-1 if register >= C.NUM_CONTEXT_REGISTERS: return # Register is empty if not self.active_registers[register]: return self.ctxts[register].seek(0) self.screen = curses.getwin(self.ctxts[register]) # Clear Notification Line DEBUG.Display(" ") self.Refresh()
def SetDirection(self, up=True, down=True): if self.task_type != "habit": return if self.task_type != "checklist" and self.task.isChallenge: # Cannot change direction of a challenge DEBUG.Display("Cannot change directions of a challenge habit") return self.task.SetDirection(up, down) if up and down: self.status = H.Status("habit", isChallenge=self.task.isChallenge) elif up: self.status = H.Status("habitpos", isChallenge=self.task.isChallenge) elif down: self.status = H.Status("habitneg", isChallenge=self.task.isChallenge) else: self.status = H.Status("unscoredhabit", isChallenge=self.task.isChallenge) self.SetStatusXY() self.status.ToggleEdit()
def Parser(self, command): parsed = shlex.split(command) if Idx(parsed, 0) == "set": if not Idx(parsed, 1) in C.SET_COMMANDS: DEBUG.Display("Invalid Set: " + command) return c = Idx(parsed, 1) # Change Difficulty if c == "d": if (not Idx(parsed, 2) in C.DIFFS) or (Idx(parsed, 3) != ""): DEBUG.Display("Invalid set d: " + Idx(parsed, 2)) return key = Idx(parsed, 2) G.currentTask.ChangePriority(key) self.Highlight() return # Change/Remove Due Date elif c == "due": if G.currentTask.task_type != "todo": DEBUG.Display("Cannot have due date for a non-TODO task") return # set due remove - Remove the current due date if any if Idx(parsed, 2) == "remove" or Idx(parsed, 2) == "delete": G.currentTask.RemoveDueDate() self.Highlight() return retDate = H.DatePicker() if retDate != None: G.currentTask.ChangeDueDate(retDate.ConvertUTC()) self.Highlight() return # Set weekly options for dailies elif c == "weekly": if G.currentTask.task_type != "daily": DEBUG.Display( "Cannot change 'weekly' parameter for a non-daily task" ) return repeat = H.RepeatPicker(G.currentTask.task.repeat) if repeat != None: G.currentTask.SetWeekly(repeat) self.Highlight() return # Set every X days option for dailies elif c == "every": if G.currentTask.task_type != "daily": DEBUG.Display( "Cannot change 'every' parameter for a non-daily task") return if not Idx(parsed, 2).isdigit(): DEBUG.Display( "Invalid number of days. Should be a valid integer") return G.currentTask.SetEvery(int(Idx(parsed, 2))) self.Highlight() return # Set Direction (Pos/Neg/Both/None) for habits elif c == "direction": if G.currentTask.task_type != "habit": DEBUG.Display( "Cannot change directions for a non-habit task") return direction = Idx(parsed, 2) if direction == "both": G.currentTask.SetDirection(up=True, down=True) elif direction == "pos": G.currentTask.SetDirection(up=True, down=False) elif direction == "neg": G.currentTask.SetDirection(up=False, down=True) elif direction == "none": G.currentTask.SetDirection(up=False, down=False) else: DEBUG.Display( "Invalid direction parameter. Should be one of [both, pos, neg, none]" ) return self.Highlight() return elif Idx(parsed, 0) == "et": # Create Todo c_title = Idx(parsed, 1) if c_title == "": title = H.TitlePicker() else: title = Idx(parsed, 1) G.reqManager.CreateTask_orig(title, "todo") self.trinity[self.currentMenu].InitialCurrentTask() self.Highlight() return elif Idx(parsed, 0) == "ed": # Create Daily c_title = Idx(parsed, 1) if c_title == "": title = H.TitlePicker() else: title = Idx(parsed, 1) G.reqManager.CreateTask_orig(title, "daily") self.trinity[self.currentMenu].InitialCurrentTask() self.Highlight() return elif Idx(parsed, 0) == "eh": # Create Habit c_title = Idx(parsed, 1) if c_title == "": title = H.TitlePicker() else: title = Idx(parsed, 1) G.reqManager.CreateTask_orig(title, "habit") self.trinity[self.currentMenu].InitialCurrentTask() self.Highlight() return if command != "": DEBUG.Display("Invalid: " + command)
def RepeatPicker(original=C.DEFAULT_REPEAT): newRepeat = original.copy() translate = { "m": "Mon", "t": "Tue", "w": "Wed", "th": "Thurs", "f": "Fri", "s": "Sat", "su": "Sun" } sequence = ["m", "t", "w", "th", "f", "s", "su"] X, Y = C.SCR_X - 4, 5 G.screen.ClearTextArea() DEBUG.Display( "Press arrow keys to navigate. (t) Toggle; (c) Confirm; (q) Cancel") current = 0 while (1): dY = Y G.screen.Display("Set Weekly: ", X - 1, Y, bold=True) for i in xrange(7): if i == current: if newRepeat[sequence[i]]: G.screen.Display(translate[sequence[i]], X, dY, color=C.SCR_COLOR_MAGENTA_GRAY_BGRD, bold=True) else: G.screen.Display(translate[sequence[i]], X, dY, color=C.SCR_COLOR_WHITE_GRAY_BGRD, bold=True) else: if newRepeat[sequence[i]]: G.screen.Display(translate[sequence[i]], X, dY, color=C.SCR_COLOR_MAGENTA, bold=True) else: G.screen.Display(translate[sequence[i]], X, dY, color=C.SCR_COLOR_NEUTRAL, bold=True) dY += len(translate[sequence[i]]) + 1 c = G.screen.GetCharacter() if c == ord('t'): newRepeat[sequence[current]] ^= True elif c == ord('q'): DEBUG.Display("") return None elif c == ord('c'): DEBUG.Display("") return newRepeat elif c == curses.KEY_LEFT or c == ord('h'): current = max(0, current - 1) elif c == curses.KEY_RIGHT or c == ord('l'): current = min(6, current + 1)
def Flush(self, flush_for_quit=False): #TODO: most of this should not happen in the request manager import content as CT DEBUG.Display("Please Wait...") Drops = list() # Difference obtained in user stats due to these operations origDict = { 'hp': G.user.hp, 'gp': G.user.gp, 'mp': G.user.mp, 'exp': G.user.exp, 'lvl': G.user.lvl } diffDict = origDict.copy() # # # # Habits marked as + for i in self.MarkUpQueue: logger.debug("Marking '%s' up" % str(i.taskname)) json = self.ScoreTask(i.task.taskID, 'up') for i in diffDict: diffDict[i] = json[i] # Check for drops tmpdrp = CT.CheckDrops(json['_tmp']) if (tmpdrp is not None): Drops.append(tmpdrp) # # # # Habits marked as - for i in self.MarkDownQueue: logger.debug("Marking '%s' down" % str(i)) json = self.ScoreTask(i.task.taskID, 'down') for i in diffDict: diffDict[i] = json[i] # # # # Dailies and TODOS marked as completed for i in self.MarkQueue: direction = None if i.task.task_type != "daily" or (not i.task.completed): direction = "up" else: direction = "down" if (direction is None): continue json = self.ScoreTask(i.task.taskID, direction) if i.task.task_type == "todo": G.TODOMenu.Remove(i.task.taskID) elif i.task.task_type == "daily": i.task.completed ^= True for i in diffDict: diffDict[i] = json[i] # Check for drops tmpdrp = CT.CheckDrops(json['_tmp']) if (tmpdrp is not None): Drops.append(tmpdrp) # # # for i in self.DeleteQueue: self.DeleteTask(i.task.taskID) if i.task.task_type == "habit": G.HabitMenu.Remove(i.task.taskID) elif i.task.task_type == "daily": G.DailyMenu.Remove(i.task.taskID) elif i.task.task_type == "todo": G.TODOMenu.Remove(i.task.taskID) # # # for i in self.EditQueue: self.UpdateTask(i.task.taskID, i.task.data) if (flush_for_quit): return # # # Update the Interface G.screen.Erase() G.user.PrintDiff(diffDict) G.intf.Init() G.user.PrintUserStats() # # # # Display Drop Messages if Drops: G.screen.SaveInRegister(1) drop_items = [] for i in Drops: DEBUG.Display("Processing Drop %s..." % i) drop_items += [M.SimpleTextItem(i)] dropMenu = M.SimpleTextMenu(drop_items, C.SCR_TEXT_AREA_LENGTH) dropMenu.SetXY(C.SCR_FIRST_HALF_LENGTH, 5) dropMenu.Display() dropMenu.Input() G.screen.RestoreRegister(1) self.ClearQueues()
def GetData(): DEBUG.Display("Please Wait...") data = G.reqManager.FetchUserData() DEBUG.Display(" ") # Calculate Damage to User while (G.content == None): DEBUG.Display("Fetching Content...") time.sleep(5) DEBUG.Display(" ") userStats = H.GetUserStats(data) stealth = data['stats']['buffs']['stealth'] conBonus = max(1 - (userStats['con'] * (1.0 / 250)), 0.1) userDamage = 0 partyDamage = 0 userDamageBoss = 0 party = data['party'] quest = party.get('quest', {}) if quest != {}: questDetails = G.content.Quest(quest['key']) userDamageBoss = math.floor(quest['progress']['up'] * 10) / 10 dailies = G.reqManager.FetchUserTasks("dailys") dailiesIncomplete = 0 for daily in dailies: logger.debug("Processing Daily: %s" % str(daily['text'].encode("utf-8"))) if not H.isDueDaily(daily) or daily['completed']: continue dailiesIncomplete += 1 if stealth > 0: stealth -= 1 continue checklist = daily['checklist'] done = len([i for i in checklist if i['completed']]) total = len(checklist) checklistProportionDone = 0.0 if total > 0: checklistProportionDone = (done * 1.0) / total damage = 0.9747**(EffectiveValueTask(daily['value'])) damage = damage * (1 - checklistProportionDone) # Due To Boss if quest != {}: bossDamage = damage if questDetails.has_key('boss'): if daily['priority'] < 1: bossDamage *= daily['priority'] partyDamage += bossDamage * questDetails['boss']['str'] userDamage += damage * conBonus * daily['priority'] * 2 userDamage += partyDamage userDamage = math.ceil(userDamage * 10) / 10 partyDamage = math.ceil(partyDamage * 10) / 10 data_items = [ "Current Health: " + str(G.user.hp), "Dailies Incomplete: " + str(dailiesIncomplete), "Est. Damage to You: " + str(userDamage), "Est. Damage to Party: " + str(partyDamage), "Est. Damage to Boss: " + str(userDamageBoss) ] # Collection statistics if it is a collect quest if questDetails.has_key('collect'): disp_string = "You have found " for (key, value) in quest['progress']['collect'].items(): disp_string += str( value) + " " + questDetails['collect'][key]['text'] + " " data_items += [disp_string] data_items = [M.SimpleTextItem(i) for i in data_items] G.screen.SaveInRegister(1) dataMenu = M.SimpleTextMenu(data_items, C.SCR_TEXT_AREA_LENGTH) dataMenu.SetXY(C.SCR_FIRST_HALF_LENGTH, 5) dataMenu.Display() dataMenu.Input() G.screen.RestoreRegister(1)