237 lines
10 KiB
Python
237 lines
10 KiB
Python
from core.chat_blob import ChatBlob
|
|
from core.command_param_types import Any, Int, NamedParameters
|
|
from core.decorators import instance, command
|
|
|
|
|
|
# noinspection SqlCaseVsIf,SqlAggregates
|
|
@instance()
|
|
class NanoController:
|
|
def inject(self, registry):
|
|
self.db = registry.get_instance("db")
|
|
self.util = registry.get_instance("util")
|
|
self.text = registry.get_instance("text")
|
|
self.command_alias_service = registry.get_instance("command_alias_service")
|
|
|
|
def pre_start(self):
|
|
self.db.load_sql_file(self.module_dir + "/" + "nanos.sql", pre_optimized=True)
|
|
self.db.create_view("nanos")
|
|
|
|
def start(self):
|
|
self.command_alias_service.add_alias("nl", "nanolines")
|
|
self.command_alias_service.add_alias("nanoline", "nanolines")
|
|
|
|
@command(command="nano", params=[Any("search"), NamedParameters(["page"])], access_level="member",
|
|
description="Search for a nano")
|
|
def nano_cmd(self, _, search, named_params):
|
|
page = int(named_params.page or "1")
|
|
page_size = 30
|
|
offset = (page - 1) * page_size
|
|
|
|
sql = "SELECT n.* " \
|
|
"FROM nanos n " \
|
|
"WHERE n.nano_name <EXTENDED_LIKE=0> ? group by nano_id " \
|
|
"ORDER BY n.profession, n.strain, n.ql DESC, n.crystal_name"
|
|
data = self.db.query(sql, [search], extended_like=True)
|
|
count = len(data)
|
|
paged_data = data[offset:offset + page_size]
|
|
|
|
blob = ""
|
|
if count == 0:
|
|
return "No nanos found matching <highlight>%s</highlight>." % search
|
|
elif count == 1:
|
|
row = data[0]
|
|
nano = self.make_nano(row)
|
|
if nano:
|
|
return f"{nano} <highlight>{row.strain.replace('_', ' ')}</highlight>"
|
|
return f"No nanos found matching <highlight>{search}</highlight>."
|
|
elif count > page_size:
|
|
if page > 1 and len(paged_data) > 0:
|
|
blob += " " + self.text.make_chatcmd(f"<< Page {page - 1:d}",
|
|
self.get_chat_command(search, page - 1))
|
|
if offset + page_size < len(data):
|
|
blob += " Page " + str(page)
|
|
blob += " " + self.text.make_chatcmd(f"Page {page + 1:d} >>",
|
|
self.get_chat_command(search, page + 1))
|
|
blob += "\n\n"
|
|
|
|
current_nanoline = []
|
|
for row in paged_data:
|
|
if current_nanoline != [row.strain_id, row.profession]:
|
|
if row.strain:
|
|
nano = self.text.make_tellcmd(row.strain, f"nanolines {row.profession} {row.strain}")
|
|
blob += f"<pagebreak>\n<header2>{row.profession}</header2> - {nano}\n" if nano else ""
|
|
else:
|
|
blob += "\n<header2>Unknown/General</header2>\n"
|
|
current_nanoline = [row.strain_id, row.profession]
|
|
nano = self.make_nano(row)
|
|
blob += nano + "\n" if nano else ""
|
|
blob += self.get_footer()
|
|
|
|
return ChatBlob(
|
|
f"Nano Search Results for '{search}' ({offset + 1:d} - "
|
|
f"{min(offset + page_size, count):d} of {count:d})",
|
|
blob)
|
|
|
|
def format_single_nano(self, row):
|
|
if str(row.crystal_name).startswith("Nano") \
|
|
or str(row.crystal_name).startswith("Shadow") \
|
|
or str(row.crystal_name).startswith("Alien") \
|
|
or str(row.location).startswith("Arete"):
|
|
item = self.text.make_item(row.crystal_id, row.crystal_id, row.ql, str(row.crystal_name).replace('_', ' '))
|
|
return f"QL {row.ql: >3} {item} {row.location}"
|
|
return ""
|
|
|
|
@command(command="nanoloc", params=[], access_level="member",
|
|
description="Show all nano locations")
|
|
def nanoloc_list_cmd(self, _):
|
|
data = self.db.query(
|
|
"SELECT location, COUNT(location) AS cnt "
|
|
"FROM (SELECT * FROM nanos group by nano_id order by crystal_name) a "
|
|
"GROUP BY location "
|
|
"ORDER BY location")
|
|
|
|
blob = ""
|
|
for row in data:
|
|
blob += "%s (%d)\n" % (self.text.make_tellcmd(row.location, "nanoloc %s" % row.location), row.cnt)
|
|
blob += self.get_footer()
|
|
|
|
return ChatBlob("Nano Locations", blob)
|
|
|
|
@command(command="nanoloc", params=[Any("location")], access_level="member",
|
|
description="Show nanos by location")
|
|
def nanoloc_show_cmd(self, _, location):
|
|
sql = "SELECT * " \
|
|
"FROM nanos n " \
|
|
"WHERE n.location LIKE ? " \
|
|
"group by n.nano_id ORDER BY n.profession, n.crystal_name"
|
|
data = self.db.query(sql, [location])
|
|
cnt = len(data)
|
|
|
|
blob = ""
|
|
prof = ""
|
|
|
|
for row in data:
|
|
if prof != row.profession:
|
|
if row.profession:
|
|
blob += f"<pagebreak>\n<header2>{row.profession.replace('_', ' ')}</header2>\n"
|
|
else:
|
|
blob += "\n<header2>Unknown/General</header2>\n"
|
|
prof = row.profession
|
|
|
|
blob += "<tab>QL %d %s\n" % (row.ql, self.make_nano(row))
|
|
return ChatBlob("Nanos for Location '%s' (%d)" % (location, cnt), blob)
|
|
|
|
@command(command="nanolines", params=[], access_level="member",
|
|
description="Show nanos by nanoline")
|
|
def nanolines_list_cmd(self, _):
|
|
data = self.db.query("SELECT DISTINCT profession FROM nanos ORDER BY profession")
|
|
|
|
blob = ""
|
|
for row in data:
|
|
blob += self.text.make_tellcmd(row.profession, f"nanolines {row.profession}") + "\n"
|
|
blob += self.get_footer()
|
|
|
|
return ChatBlob("Nanolines", blob)
|
|
|
|
@command(command="nanolines", params=[Int("nanoline_id")], access_level="member",
|
|
description="Show nanos by nanoline id")
|
|
def nanolines_id_cmd(self, _, nanoline_id):
|
|
nanoline = self.db.query_single("SELECT * FROM nanos WHERE strain_id = ? LIMIT 1", [nanoline_id])
|
|
|
|
if not nanoline or nanoline_id == 0:
|
|
return f"Could not find nanoline with ID <highlight>{nanoline_id:d}</highlight>."
|
|
|
|
data = self.db.query(
|
|
"SELECT n.crystal_id, n.ql, n.strain, n.crystal_name, n.location "
|
|
"FROM nanos n "
|
|
"where n.strain_id=? "
|
|
"group by n.nano_id "
|
|
"ORDER BY n.ql DESC, n.nano_name",
|
|
[nanoline_id])
|
|
blob = ""
|
|
for row in data:
|
|
item = self.make_nano(row)
|
|
blob += item + "\n" if item else ""
|
|
blob += self.get_footer()
|
|
|
|
return ChatBlob(f"{str(nanoline.strain).replace('_', ' ')} Nanos", blob)
|
|
|
|
@command(command="nanolines", params=[Any("profession"), Any("nanoline")], access_level="member",
|
|
description="Show nanos by nanoline profession and line name")
|
|
def nanolines_prof_strain(self, _, prof: str, strain: str):
|
|
profession = self.util.get_profession(prof)
|
|
if strain.startswith("Artist"):
|
|
profession = "Martial Artist"
|
|
strain = strain[7:]
|
|
nanoline = self.db.query_single(
|
|
"SELECT * FROM nanos n WHERE n.strain LIKE ? AND profession =? and type in ('Crystal', 'Misc') LIMIT 1",
|
|
[strain, profession])
|
|
|
|
if not nanoline:
|
|
return f"Could not find nanoline with name <highlight>{strain}</highlight>."
|
|
|
|
data = self.db.query(
|
|
"SELECT n.* FROM nanos n "
|
|
"where n.strain LIKE ? "
|
|
"and n.profession = ? "
|
|
"and type in ('Crystal', 'Misc') "
|
|
"group by nano_id "
|
|
"ORDER BY n.strain, n.ql DESC, n.nano_name",
|
|
["%" + strain.replace(" ", "%") + "%", profession])
|
|
blob = ""
|
|
strain = ""
|
|
for row in data:
|
|
if strain != row.strain:
|
|
if row.strain:
|
|
blob += f"<pagebreak>\n<header2>{row.strain.replace('_', ' ')}</header2>\n"
|
|
else:
|
|
blob += "\n<header2>Unknown/General</header2>\n"
|
|
strain = row.strain
|
|
item = self.make_nano(row)
|
|
blob += item + "\n" if item else ""
|
|
blob += self.get_footer()
|
|
|
|
return ChatBlob("%s %s Nanos" % (nanoline.profession, str(nanoline.strain).replace("_", " ")), blob)
|
|
|
|
# @command(command='disc', params=[Any("search")], access_level="member",
|
|
# description="Search for the disc to a Crystal, or the other way around.")
|
|
# def disc_search_command(self, req, search):
|
|
# pass
|
|
@command(command="nanolines", params=[Any("profession")], access_level="member",
|
|
description="Show nanolines by profession")
|
|
def nanolines_profession_cmd(self, _, prof_name):
|
|
profession = self.util.get_profession(prof_name)
|
|
if not profession:
|
|
return "Could not find profession <highlight>%s</highlight>." % prof_name
|
|
|
|
data = self.db.query(
|
|
"SELECT CASE WHEN strain = 'Composite' THEN 'Composite' ELSE school END as school, strain, profession "
|
|
"FROM nanos WHERE Profession = ? "
|
|
"and location not like 'No%longer%drops' "
|
|
"and type not in ('Tainted') "
|
|
"GROUP by strain ORDER BY school, strain='Composite', strain", [profession])
|
|
|
|
blob = ""
|
|
school = ""
|
|
for row in data:
|
|
if school != row.school:
|
|
if row.strain:
|
|
blob += f"<pagebreak>\n<header2>{row.school.replace('_', ' ')}</header2>\n"
|
|
else:
|
|
blob += "\n<header2>Unknown/General</header2>\n"
|
|
school = row.school
|
|
|
|
blob += "<tab>" + self.text.make_tellcmd(row.strain, f"nanolines {row.profession} {row.strain}") + "\n"
|
|
blob += self.get_footer()
|
|
|
|
return ChatBlob("%s Nanolines" % profession, blob)
|
|
|
|
def get_footer(self):
|
|
return "\n\nNano-DB provided by AOIA+ 2019"
|
|
|
|
def get_chat_command(self, search, page):
|
|
return "/tell <myname> nano %s --page=%d" % (search, page)
|
|
|
|
def make_nano(self, row):
|
|
return f"QL {row.ql: >3} <a href='itemid://53019/{row.nano_id}'>{row.crystal_name}</a> {row.location}"
|