def display_open_tickets(self): """Display tickets based on commandline options""" open_tickets = Ticket.objects.select_related('queue').filter( queue__in=self.queues_from_args).exclude( status=Ticket.CLOSED_STATUS, ) if "low" in self.switches: open_tickets = open_tickets.filter(priority__gt=5) else: open_tickets = open_tickets.filter(priority__lte=5) if "mine" in self.switches: open_tickets = open_tickets.filter(assigned_to=self.caller) elif "all" not in self.switches: open_tickets = open_tickets.filter(assigned_to__isnull=True) joblist = open_tickets if not joblist: self.msg("No open tickets.") return table = prettytable.PrettyTable( ["{w#", "{wPlayer", "{wRequest", "{wPriority", "{wQueue"]) for ticket in joblist: if ticket.priority == 1: prio = "{r%s{n" % ticket.priority else: prio = "{w%s{n" % ticket.priority q = Queue.objects.get(id=ticket.queue_id) table.add_row([ str(ticket.id), str(ticket.submitting_player.key), str(ticket.title)[:20], prio, q.slug ]) self.msg("{wOpen Tickets:{n\n%s" % table)
def list_bboards(caller, old=False): """ Helper function for listing all boards a player is subscribed to in some pretty format. """ bb_list = get_boards(caller) if not bb_list: return my_subs = [bb for bb in bb_list if bb.has_subscriber(caller)] # just display the subscribed bboards with no extra info if old: caller.msg("{cDisplaying only archived posts.{n") bbtable = prettytable.PrettyTable( ["{wbb #", "{wName", "{wPosts{n", "{wSubscribed{n"]) for bboard in bb_list: bb_number = bb_list.index(bboard) bb_name = bboard.key unread_num = bboard.num_of_unread_posts(caller, old) subbed = bboard in my_subs posts = bboard.archived_posts if old else bboard.posts if unread_num: unread_str = " {w(%s new){n" % unread_num else: unread_str = "" bbtable.add_row( [bb_number, bb_name, "%s%s" % (len(posts), unread_str), subbed]) caller.msg("\n{w" + "=" * 60 + "{n\n%s" % bbtable)
def display_open_tickets(self): """Display tickets based on commandline options""" open_tickets = (Ticket.objects.select_related("queue").filter( queue__in=self.queues_from_args).exclude( status=Ticket.CLOSED_STATUS, )) if "low" in self.switches: open_tickets = open_tickets.filter(priority__gt=5) else: open_tickets = open_tickets.filter(priority__lte=5) if "mine" in self.switches: open_tickets = open_tickets.filter(assigned_to=self.caller) elif "all" not in self.switches: open_tickets = open_tickets.filter(assigned_to__isnull=True) joblist = open_tickets if not joblist: self.msg("No open tickets.") return table = prettytable.PrettyTable( ["{w#", "{wPlayer", "{wRequest", "{wPriority/Q"]) for ticket in joblist: color = "|r" if ticket.priority == 1 else "" q_category = "%s%s %s|n" % (color, ticket.priority, ticket.queue.slug) table.add_row([ str(ticket.id), str(ticket.submitting_player.key), str(ticket.title)[:20], q_category, ]) self.msg("{wOpen Tickets:{n\n%s" % table)
def list_messages(caller, board, board_num, old=False): """ Helper function for printing all the posts on board to caller. """ if not board: caller.msg("No bulletin board found.") return caller.msg("{w" + "=" * 60 + "\n{n") title = "{w**** %s ****{n" % board.key.capitalize() title = "{:^80}".format(title) caller.msg(title) posts = board.get_all_posts(old=old) msgnum = 0 msgtable = prettytable.PrettyTable( ["{wbb/msg", "{wSubject", "{wPostDate", "{wPosted By"] ) from world.msgs.models import Post read_posts = Post.objects.all_read_by(caller) for post in posts: unread = post not in read_posts msgnum += 1 if str(board_num).isdigit(): bbmsgnum = str(board_num) + "/" + str(msgnum) else: bbmsgnum = board.name.capitalize() + "/" + str(msgnum) # if unread message, make the message white-bold if unread: bbmsgnum = "{w" + "{0}".format(bbmsgnum) subject = post.db_header[:35] date = post.db_date_created.strftime("%x") poster = board.get_poster(post)[:10] # turn off white-bold color if unread message if unread: poster = "{0}".format(poster) + "{n" msgtable.add_row([bbmsgnum, subject, date, poster]) caller.msg(str(msgtable)) pass
def func(self): """Implement the command""" caller = self.caller args = self.args switches = self.switches apps = get_apps_manager(caller) if not apps: caller.msg( "Apps manager not found! Please inform the administrators.") return if not args and not switches: # '@app' # List all pending applications all_apps = apps.view_all_apps() if not all_apps: caller.msg("No applications found.") return # application[9] field is 'True' if pending/open pend_list = [app for app in all_apps.values() if app[9]] if not pend_list: caller.msg("No pending applications found.") return # app = [app_num, char_ob, email, date_submit, application_string, # gm_ob, date_answer, gm_notes, approval, pending] table = prettytable.PrettyTable( ["{w#", "{wCharacter", "{wEmail", "{wDate"]) for app in pend_list: table.add_row( [app[0], app[1].key.capitalize(), app[2], app[3]]) caller.msg("{wApplications for Characters pending approval:\n%s" % table) caller.msg("To view a particular application, @app <app number>") caller.msg("To view closed applications, use @app/old") return if args and not switches and not args.isdigit(): # '@app <character>' # List all pending apps for a particular character apps_for_char = apps.view_all_apps_for_char(args) if not apps_for_char: caller.msg("No applications found.") return pend_list = [ob for ob in apps_for_char if ob[9]] if not pend_list: caller.msg("No pending applications found.") return # app = [app_num, char_ob, email, date_submit, application_string, gm_ob, # date_answer, gm_notes, approval, pending] table = prettytable.PrettyTable( ["{w#", "{wCharacter", "{wEmail", "{wDate"]) for app in pend_list: table.add_row( [app[0], app[1].key.capitalize(), app[2], app[3]]) caller.msg("{wPending applications for %s:\n%s" % (args, table)) caller.msg("To view a specific application, @app <app number>") return if args and args.isdigit() and (not switches or 'old' in switches): # '@app <#> # List a given ticket by app = apps.view_app(int(args)) if not app: caller.msg("No application by that number for that character.") return email = app[2] alts = RosterEntry.objects.filter(current_account__email=email) caller.msg("{wCharacter:{n %s" % app[1].key.capitalize()) caller.msg("{wApp Email:{n %s" % email) if alts: caller.msg("{wCurrent characters:{n %s" % ", ".join(str(ob) for ob in alts)) caller.msg("{wDate Submitted:{n %s" % app[3]) caller.msg("{wApplication:{n %s" % app[4]) if not app[9]: caller.msg("{wGM:{n %s" % app[5]) caller.msg("{wDate Answered:{n %s" % app[6]) caller.msg("{wGM Notes:{n %s" % app[7]) caller.msg("{wApproved:{n %s" % app[8]) return if 'approve' in switches: # @app/approve <#>=<notes> # mark a character as approved, then send an email to the player if not self.lhs or not self.rhs or not self.lhs.isdigit(): caller.msg("Usage: @app/approve <#>=<notes>") return app = apps.view_app(int(self.lhs)) if apps.close_app(int(self.lhs), caller, self.rhs, True): caller.msg("Application successfully approved.") if app and app[1]: inform_staff( "{w%s has approved %s's application.{n" % (caller.key.capitalize(), app[1].key.capitalize())) try: entry = RosterEntry.objects.get( character__id=app[1].id, player__id=app[1].player_ob.id) active_roster = Roster.objects.get(name="Active") entry.roster = active_roster try: account = PlayerAccount.objects.get(email=app[2]) except PlayerAccount.DoesNotExist: account = PlayerAccount.objects.create(email=app[2]) entry.current_account = account entry.save() # clear cache so the character is moved correctly entry.character.flush_from_cache(force=True) entry.player.flush_from_cache(force=True) from datetime import datetime date = datetime.now() if not AccountHistory.objects.filter( entry=entry, account=account, end_date__isnull=True).exists(): AccountHistory.objects.create(entry=entry, account=account, start_date=date) # make sure all their Attributes are clean for new player from server.utils.arx_utils import post_roster_cleanup, reset_to_default_channels post_roster_cleanup(entry) reset_to_default_channels(entry.player) try: from commands.cmdsets.starting_gear import setup_gear_for_char if not entry.character: raise ValueError( "No character found for setup gear") setup_gear_for_char(entry.character) except ValueError: traceback.print_exc() except (RosterEntry.DoesNotExist, RosterEntry.MultipleObjectsReturned, Roster.DoesNotExist, Roster.MultipleObjectsReturned, AttributeError, ValueError, TypeError): print( "Error when attempting to mark closed application as active." ) traceback.print_exc() try: from world.dominion.setup_utils import setup_dom_for_char setup_dom_for_char(app[1]) except (ValueError, TypeError): # will throw an exception if Dominion already set up pass try: bb = BBoard.objects.get(db_key__iexact="Roster Changes") msg = "%s now has a new player and is on the active roster." % app[ 1] url = "http://play.arxmush.org" + app[1].get_absolute_url() msg += "\nCharacter page: %s" % url subject = "%s now active" % app[1] bb.bb_post(self.caller, msg, subject=subject, poster_name="Roster") except BBoard.DoesNotExist: self.msg("Board not found for posting announcement") return else: caller.msg("Application closure failed.") return if 'delete' in switches or 'del' in switches: try: apps.delete_app(caller, int(self.args)) return except (ValueError, TypeError): caller.msg("Could not delete an app for value of %s." % self.args) return if 'deny' in switches: # @app/deny <#>=<notes> # mark a character as declined, then send an email to the player if not self.lhs or not self.rhs or not self.lhs.isdigit(): caller.msg("Usage: @app/deny <#>=<notes>") return if apps.close_app(int(self.lhs), caller, self.rhs, False): caller.msg("Application successfully declined.") app = apps.view_app(int(self.lhs)) if app and app[1]: inform_staff( "{w%s has declined %s's application.{n" % (caller.key.capitalize(), app[1].key.capitalize())) return else: caller.msg("Application closure failed.") return if 'old' in switches: # List all non-pending applications all_apps = apps.view_all_apps() if not all_apps: caller.msg("No applications found.") return # application[9] field is 'True' if pending/open pend_list = [_app for _app in all_apps.values() if not _app[9]] pend_list.sort(key=lambda appl: appl[0]) if not pend_list: caller.msg("No closed applications found.") return if not self.args: pend_list = pend_list[-20:] else: try: pend_list = pend_list[-int(self.args):] except (TypeError, ValueError): caller.msg("Could not display entries for that range.") return # app = [app_num, char_ob, email, date_submit, application_string, gm_ob, # date_answer, gm_notes, approval, pending] table = prettytable.PrettyTable( ["{w#", "{wCharacter", "{wEmail", "{wDate", "{wApproved"]) for app in pend_list: table.add_row([ app[0], app[1].key.capitalize(), app[2], app[3][:9], str(app[8]) ]) caller.msg("{wOld/Closed applications for characters:\n%s" % table) caller.msg("To view a particular application, @app <app number>") return pass if 'oldchar' in switches: apps_for_char = apps.view_all_apps_for_char(args) if not apps_for_char: caller.msg("No applications found.") return pend_list = [ob for ob in apps_for_char if not ob[9]] if not pend_list: caller.msg("No closed applications found.") return # app = [app_num, char_ob, email, date_submit, application_string, gm_ob, # date_answer, gm_notes, approval, pending] table = prettytable.PrettyTable([ "{w#", "{wCharacter", "{wEmail", "{wDate", "{wGM", "{wApproved" ]) for app in pend_list: table.add_row([ app[0], app[1].key.capitalize(), app[2], app[3][:9], app[5].key, str(app[8]) ]) caller.msg("{wOld/Closed applications for %s:\n%s" % (args, table)) caller.msg("To view a particular application, @app <app number>") return if 'email' in switches: apps_for_email = apps.view_apps_for_email(args) if not apps_for_email: caller.msg("No applications found.") return table = prettytable.PrettyTable( ["{w#", "{wCharacter", "{wEmail", "{wDate"]) for app in apps_for_email: table.add_row( [app[0], app[1].key.capitalize(), app[2], app[3]]) caller.msg("{wApplications for %s:\n%s" % (args, table)) caller.msg("To view a particular application, @app <app number>") return if 'fixemail' in switches: try: if apps.fix_email(int(self.lhs), caller, self.rhs): caller.msg("App email changed to %s." % self.rhs) return except (TypeError, ValueError, AttributeError): caller.msg("Must provide an app # and an email address.") return if 'resend' in switches: try: apps.resend(int(self.lhs), caller) return except (ValueError, TypeError, AttributeError): caller.msg("Must provide a valid app #.") return caller.msg("Invalid switch for @app.")
def func(self): """Implement the command""" caller = self.caller args = self.args switches = self.switches if not args and not switches or (set(switches) & set(self.query_open_switches)): # list all open tickets self.display_open_tickets() return if args and (not switches or 'old' in switches): # list individual ticket specified by args # ticket = [ticket_id, playob, request_string, date_submit, gm_ob, gm_notes, date_answer, optional_title] try: ticknum = int(args) except ValueError: self.display_open_tickets() caller.msg("Usage: Argument must be a ticket number.") return try: ticket = Ticket.objects.get(id=ticknum) except Ticket.DoesNotExist: self.display_open_tickets() caller.msg("No ticket found by that number.") return caller.msg(ticket.display()) return if 'old' in switches and not args: # list closed tickets # closed & resolved tickets, assigned to current user tickets_closed_resolved = Ticket.objects.select_related( 'queue').filter( status__in=[Ticket.CLOSED_STATUS, Ticket.RESOLVED_STATUS ]).filter(queue__in=self.queues_from_args) joblist = list(tickets_closed_resolved) if not joblist: caller.msg("No closed tickets.") return # get 20 most recent joblist = joblist[-20:] table = prettytable.PrettyTable( ["{w#", "{wPlayer", "{wRequest", "{wQueue"]) for ticket in joblist: table.add_row([ str(ticket.id), str(ticket.submitting_player), str(ticket.title)[:20], ticket.queue.slug ]) caller.msg("{wClosed Tickets:{n\n%s" % table) return if 'moreold' in switches: # list closed tickets tickets_closed_resolved = Ticket.objects.select_related( 'queue').filter( status__in=[Ticket.CLOSED_STATUS, Ticket.RESOLVED_STATUS] ).filter(queue__in=self.queues_from_args).filter( id__gte=self.lhslist[0], id__lte=self.lhslist[1]) joblist = list(tickets_closed_resolved) if not joblist: caller.msg("No closed tickets.") return table = prettytable.PrettyTable( ["{w#", "{wPlayer", "{wRequest", "{wQueue"]) for ticket in joblist: table.add_row([ str(ticket.id), str(ticket.submitting_player), str(ticket.title)[:20], ticket.queue.slug ]) caller.msg("{wClosed Tickets:{n\n%s" % table) return try: ticket = Ticket.objects.get(id=self.lhs) except (ValueError, Ticket.DoesNotExist): self.msg("No ticket found by that number.") return if 'close' in switches: # Closing a ticket. Check formatting first lhs = self.lhs rhs = self.rhs if not args or not lhs or not rhs: caller.msg("Usage: @job/close <#>=<GM Notes>") return try: numticket = int(lhs) except ValueError: caller.msg("Must give a number for the open ticket.") return if helpdesk_api.resolve_ticket(caller, numticket, rhs): caller.msg("Ticket successfully closed.") return else: caller.msg("Ticket closure failed for unknown reason.") return if 'assign' in switches: player = self.caller.search(self.rhs) if not player: return ticket.assigned_to = player ticket.save() inform_staff("{w%s has assigned ticket %s to %s." % (caller, ticket.id, player)) return if 'followup' in switches or 'update' in switches or "follow" in switches: lhs = self.lhs rhs = self.rhs if not lhs or not rhs: caller.msg("Usage: @job/followup <#>=<msg>") return if helpdesk_api.add_followup(caller, ticket, rhs): caller.msg("Followup added.") return caller.msg("Error in followup.") return if 'move' in switches: if not self.lhs or not self.rhs: self.msg("Usage: @job/move <#>=<msg>") return try: queue = Queue.objects.get(slug__iexact=self.rhs) except Queue.DoesNotExist: self.msg("Queue must be one of the following: %s" % ", ".join(ob.slug for ob in Queue.objects.all())) return ticket.queue = queue ticket.save() self.msg("Ticket %s is now in queue %s." % (ticket.id, queue)) return if 'delete' in switches or 'del' in switches: if ticket.queue.slug == "Story": self.msg( "Cannot delete a storyaction. Please move it to a different queue first." ) return ticket.delete() self.msg("Ticket #%s deleted." % self.lhs) return if 'priority' in switches: try: ticket.priority = int(self.rhs) except (TypeError, ValueError): self.msg("Must be a number.") ticket.save() self.msg("Ticket new priority is %s." % self.rhs) return if 'approve' in switches: pass if 'deny' in switches: pass caller.msg("Invalid switch for @job.")
def func(self): """Execute command.""" caller = self.caller usemats = True material = None if self.cmdstring == "buy" and not ("economic" in self.switches or "social" in self.switches or "military" in self.switches): # allow for buy/economic, etc. buy switch precludes that, so we # only add it if we don't have the above switches self.switches.append("buy") if self.cmdstring == "sell": # having other switches is misleading. They could think they can sell # other things. if self.switches: caller.msg("Use market/sell or just 'sell' as the command.") return self.switches.append("sell") materials = CraftingMaterialType.objects.filter( value__gte=0).order_by("value") if not caller.check_permstring("builders"): materials = materials.exclude(contraband=True) if not self.args: mult = get_cost_multipler() mtable = prettytable.PrettyTable( ["{wMaterial", "{wCategory", "{wCost"]) for mat in materials: mtable.add_row([mat.name, mat.category, str(mat.value * mult)]) # add other items by hand for mat in other_items: mtable.add_row([mat, other_items[mat][1], other_items[mat][0]]) caller.msg("\n{w" + "=" * 60 + "{n\n%s" % mtable) pmats = OwnedMaterial.objects.filter( owner__player__player=caller.player) if pmats: caller.msg("\n{wYour materials:{n %s" % ", ".join(str(ob) for ob in pmats)) return if not ("economic" in self.switches or "buyeconomic" in self.switches or "social" in self.switches or "military" in self.switches): try: material = materials.get(name__icontains=self.lhs) except CraftingMaterialType.DoesNotExist: if self.lhs not in other_items: caller.msg("No material found for name %s." % self.lhs) return material = OtherMaterial(self.lhs) usemats = False except CraftingMaterialType.MultipleObjectsReturned: try: material = materials.get(name__iexact=self.lhs) except ( CraftingMaterialType.DoesNotExist, CraftingMaterialType.MultipleObjectsReturned, ): caller.msg("Unable to get a unique match for that.") return if "buy" in self.switches: if not usemats: amt = 1 else: try: amt = int(self.rhs) except (ValueError, TypeError): caller.msg("Amount must be a number.") return if amt < 1: caller.msg("Amount must be a positive number") return cost = material.value * amt * get_cost_multipler() try: dompc = caller.player_ob.Dominion except AttributeError: dompc = setup_utils.setup_dom_for_char(caller) # use silver if cost > caller.db.currency: caller.msg( "That would cost %s silver coins, and you only have %s." % (cost, caller.db.currency)) return caller.pay_money(cost) paystr = "%s silver" % cost if usemats: try: mat = dompc.assets.owned_materials.get(type=material) mat.amount += amt mat.save() except OwnedMaterial.DoesNotExist: dompc.assets.owned_materials.create(type=material, amount=amt) else: material.create(caller) caller.msg("You buy %s %s for %s." % (amt, material, paystr)) return if "sell" in self.switches: try: amt = int(self.rhs) except (ValueError, TypeError): caller.msg("Amount must be a number.") return if amt < 1: caller.msg("Must be a positive number.") return if not usemats: caller.msg("The market will only buy raw materials.") return try: dompc = PlayerOrNpc.objects.get(player=caller.player) except PlayerOrNpc.DoesNotExist: dompc = setup_utils.setup_dom_for_char(caller) try: mat = dompc.assets.owned_materials.get(type=material) except OwnedMaterial.DoesNotExist: caller.msg("You don't have any of %s." % material.name) return if mat.amount < amt: caller.msg("You want to sell %s %s, but only have %s." % (amt, material, mat.amount)) return mat.amount -= amt mat.save() money = caller.db.currency or 0.0 sale = amt * material.value / 20 money += sale caller.db.currency = money caller.msg("You have sold %s %s for %s silver coins." % (amt, material.name, sale)) return if "info" in self.switches: msg = "{wInformation on %s:{n %s\n" % (material.name, material.desc) price = material.value * get_cost_multipler() msg += "{wPrice in silver: {c%s{n\n" % price cost = price / 250 if price % 250: cost += 1 msg += "{wPrice in economic resources: {c%s{n" % cost caller.msg(msg) return if ("economic" in self.switches or "military" in self.switches or "social" in self.switches): try: assets = caller.player_ob.Dominion.assets amt = int(self.args) if amt <= 0: raise ValueError except (TypeError, ValueError): caller.msg("Must specify a positive number.") return cost = 500 * amt * get_cost_multipler() if cost > caller.db.currency: caller.msg("That would cost %s and you have %s." % (cost, caller.db.currency)) return caller.pay_money(cost) if "economic" in self.switches: assets.economic += amt elif "social" in self.switches: assets.social += amt elif "military" in self.switches: assets.military += amt assets.save() caller.msg("You have bought %s resources for %s." % (amt, cost)) return caller.msg("Invalid switch.") return