Commit 4c9aaeab authored by Geovanny's avatar Geovanny

House implementation for discord

parent 085eb6da
......@@ -2,14 +2,17 @@ import asyncio
import discord
import discord
from requests import Session
from discord.ext import commands
from unit.manager import UnitManager
from user.manager import UserManager
from requests import Session
from discord.ext import commands
from unit.manager import UnitManager
from user.manager import UserManager
from house.manager import HouseManager
from house.membership.manager import MembershipManager
from house.war.manager import WarManager
from util.command_error_handler import CommandErrorHandler
from util.help import EditedMinimalHelpCommand, PaginatedHelpCommand
from util.api_requests import Api
from settings import DISCORD_TOKEN
from util.help import EditedMinimalHelpCommand, PaginatedHelpCommand
from util.api_requests import Api
from settings import DISCORD_TOKEN
class ConqBot(commands.Bot):
......@@ -45,6 +48,9 @@ bot = ConqBot(command_prefix='>')
bot.add_cog(CommandErrorHandler(bot))
bot.add_cog(UserManager(bot))
bot.add_cog(UnitManager(bot))
bot.add_cog(HouseManager(bot))
bot.add_cog(MembershipManager(bot))
bot.add_cog(WarManager(bot))
@bot.event
async def on_ready():
......
from discord_argparse import *
create_params = ArgumentConverter(
name = RequiredArgument(
str,
doc='House Name',
),
level = OptionalArgument(
int,
doc='House Level',
),
camp_location = OptionalArgument(
str,
doc='Camp Location'
)
)
mod_params = ArgumentConverter(
name = OptionalArgument(
str,
doc='House Name',
),
level = OptionalArgument(
int,
doc='House Level',
),
camp_location = OptionalArgument(
str,
doc='Camp Location'
)
)
\ No newline at end of file
import discord
from discord.ext import commands
from util.pager import Pager
class HousesPager(Pager):
commands_per_page = 8
indent = 3
def add_page(self, cog_name, cog_desc, cmds):
'''Will split into several pages to accomodate the per_page limit.'''
# will obviously not run if no commands are in the page
for cmds_slice in [cmds[i:i + self.commands_per_page] for i in range(0, len(cmds), self.commands_per_page)]:
self.entries.append((cog_name, cog_desc, cmds_slice))
async def craft_page(self, e, page, entries):
cog_name, cog_desc, commands = entries[0]
name = 'Houses'
self.embed.set_author(name=name, icon_url=self.bot.user.avatar_url)
self.embed.description = cog_desc
for name, value in commands:
self.embed.add_field(name=name, value=value, inline=False)
async def craft_page_detail(self, cog_name, cog_desc, command):
name = f'{cog_name} Commands'
embed = discord.Embed()
embed.set_author(name=name, icon_url=self.bot.user.avatar_url)
embed.description = cog_desc
embed.add_field(name=command.name, value=command.help, inline=False)
for name, param in command.clean_params.items():
if isinstance(param.annotation, da.ArgumentConverter):
arguments = param.annotation.arguments
if not arguments:
continue
max_size = max(len(name) for name in arguments)
params_text = ''
for name, argument in arguments.items():
entry = "{0}{1:<{width}} |\t {2}".format(self.indent * " ", name, argument.doc, width=max_size)
params_text += "{0}\n".format(entry)
embed.add_field(name="Arguments", value=params_text)
return embed
async def help_embed(self, e):
e.set_author(name='How do I use the bot?', icon_url=self.bot.user.avatar_url)
e.description = (
'Invoke a command by sending the prefix followed by a command name.\n\n'
'For example, the command signature `track <query>` can be invoked by doing `track yellow`\n\n'
'The different argument brackets mean:'
)
e.add_field(name='<argument>', value='the argument is required.', inline=False)
e.add_field(name='[argument]', value='the argument is optional.\n\u200b', inline=False)
class PaginatedHelpCommand(commands.HelpCommand):
'''Cog that implements the help command and help pager.'''
async def add_command(self, cmds, command, force=False):
if command.hidden:
return
if force is False:
try:
if not await command.can_run(self.context):
return
except commands.CheckFailure:
return
help_message = command.brief or command.help
if help_message is None:
help_message = 'No description available.'
else:
help_message = help_message.split('\n')[0]
cmds.append((self.context.prefix + get_signature(command), help_message))
async def prepare_help_command(self, ctx, command=None):
self.context = ctx
self.pager = HelpPager(ctx, list(), per_page=1)
async def add_cog(self, cog):
cog_name = cog.__class__.__name__
cog_desc = cog.__doc__
cmds = []
added = []
for command in cog.walk_commands():
if command in added:
continue
await self.add_command(cmds, command)
added.append(command)
self.pager.add_page(cog_name, cog_desc, cmds)
async def send_bot_help(self, mapping):
for cog in mapping:
if cog is not None:
await self.add_cog(cog)
await self.pager.go()
async def send_cog_help(self, cog):
await self.add_cog(cog)
await self.pager.go()
async def send_group_help(self, group):
if group.cog_name.lower() == group.name.lower():
await self.send_cog_help(group.cog)
return
added = []
cmds = []
for command in group.walk_commands():
if command in added:
continue
await self.add_command(cmds, command)
added.append(command)
self.pager.add_page(group.cog_name, group.cog.__doc__, cmds)
await self.pager.go()
async def send_command_help(self, command):
cog_name = command.cog_name
if cog_name is not None and cog_name.lower() == command.name:
await self.send_cog_help(command.cog)
return
cog_desc = command.cog.__doc__
embed = await self.pager.craft_page_detail(cog_name, cog_desc, command)
return await self.context.send(embed=embed)
async def command_not_found(self, string):
return commands.CommandNotFound(string)
async def send_error_message(self, error):
if not isinstance(error, commands.CommandNotFound):
return
cmd = str(error)
for cog in self.context.bot.cogs:
if cmd == cog.lower():
await self.send_cog_help(self.context.bot.get_cog(cog))
return
await self.context.send('Command \'{}\' not found.'.format(cmd))
class EditedMinimalHelpCommand(commands.MinimalHelpCommand):
def get_ending_note(self):
return (
'The interactive help menu did not get sent because the bot is missing '
'the following permissions: ' + ', '.join(self.missing_perms)
)
async def send_error_message(self, error):
return
# rip is just the signature command ripped from the lib, but with alias support removed.
def get_signature(command):
"""Returns a POSIX-like signature useful for help command output."""
result = []
parent = command.full_parent_name
name = command.name if not parent else parent + ' ' + command.name
result.append(name)
if command.usage:
result.append(command.usage)
return ' '.join(result)
params = command.clean_params
if not params:
return ' '.join(result)
for name, param in params.items():
if param.default is not param.empty:
# We don't want None or '' to trigger the [name=value] case and instead it should
# do [name] since [name=None] or [name=] are not exactly useful for the user.
should_print = param.default if isinstance(param.default, str) else param.default is not None
if should_print:
result.append('[%s=%s]' % (name, param.default))
else:
result.append('[%s]' % name)
elif param.kind == param.VAR_POSITIONAL:
result.append('[%s...]' % name)
else:
result.append('<%s>' % name)
return ' '.join(result)
\ No newline at end of file
import asyncio
import discord
import json
from discord.ext import commands
from house.model import HouseModel
from util.api_requests import Api, ApiError
from util.embed_style import EmbedStyle
from .h_params import *
class HouseManager(commands.Cog):
def __init__(self, bot, loop=None):
self.bot = bot
self.loop = loop or asyncio.get_event_loop()
def createModels(self, data):
models = []
for item in data:
models.append(HouseModel(**item))
return models
@commands.command()
async def allHouses(self, ctx):
"""Get all Houses"""
try:
data = await Api.get('/house/all');
house_models = self.createModels(data)
return await EmbedStyle.createPages(self.bot, ctx, house_models, 10, self.craftHousesPage);
except ApiError as error:
ctx.send(error.message)
def craftHousesPage(self, data, minI, maxI):
embed = discord.Embed(color=0x19212d)
embed.set_author(name='Conquy')
houses_str = '';
for i in range(minI, maxI):
if i < len(data):
house = data[i]
houses_str+= '[{0}] {1}\t| {2}\t| {3}\t| {4}\n'.format(house.id, house.name, house.level, house.camp_location, house.liege)
embed.add_field(name='id\t| Name\t| Level\t| Camp Location\t| Liege', value=houses_str)
return embed
@commands.command()
async def createHouse(self, ctx, *, params:create_params=create_params.defaults()):
"""Create a house"""
try:
body = params
body['house_name'] = params['name']
body['house_level'] = params.get('level')
session = await self.bot.getUserSession(ctx.message.author)
await Api.postSession('/house', body, session)
await ctx.send('House created')
except ApiError as error:
await ctx.send(error.message)
@commands.command()
async def modHouse(self, ctx, *, params:mod_params=mod_params.defaults()):
"""Modify your house"""
try:
body = params
body['house_name'] = params.get('name')
body['house_level'] = params.get('level')
session = await self.bot.getUserSession(ctx.message.author)
await Api.putSession('/house', body, session)
await ctx.send('House modified')
except ApiError as error:
await ctx.send(error.message)
@commands.command()
async def deleteHouse(self, ctx):
"""Delete your house"""
try:
session = await self.bot.getUserSession(ctx.message.author)
await Api.deleteSession('/house', session)
await ctx.send('House deleted')
except ApiError as error:
await ctx.send(error.message)
\ No newline at end of file
import asyncio
import discord
import json
from discord.ext import commands
from util.api_requests import Api, ApiError
from util.embed_style import EmbedStyle
class MembershipManager(commands.Cog):
def __init__(self, bot, loop=None):
self.bot = bot
self.loop = loop or asyncio.get_event_loop()
@commands.command()
async def sendRequest(self, ctx, house_id:int):
"""Send member request to house id"""
try:
session = await self.bot.getUserSession(ctx.message.author)
await Api.postSession('/house/request', {"house_id": house_id}, session)
await ctx.send('Request sent');
except ApiError as error:
await ctx.send(error.message)
@commands.command()
async def cancelRequest(self, ctx):
"""Cancel member request"""
try:
session = await self.bot.getUserSession(ctx.message.author)
await Api.deleteSession('/house/request', session)
await ctx.send('Request cancelled');
except ApiError as error:
await ctx.send(error.message)
@commands.command()
async def allRequests(self, ctx):
"""All requests to house"""
try:
session = await self.bot.getUserSession(ctx.message.author)
data = await Api.getSession('/house/requests', session)
if(len(data) == 0):
await ctx.send('No requests')
else:
await EmbedStyle.createPages(self.bot, ctx, data, 10, self.craftRequestsPage)
except ApiError as error:
await ctx.send(error.message)
def craftRequestsPage(self, data, minI, maxI):
embed = discord.Embed(color=0x19212d)
embed.set_author(name='Conquy')
requests_str = '';
for i in range(minI, maxI):
if i < len(data):
request = data[i]
requests_str+= '[{0}] {1}'.format(request.get('id'), request.get('username'))
embed.add_field(name='id\t| Name', value=requests_str)
return embed
@commands.command()
async def acceptRequest(self, ctx, user_id:int):
"""Accept membership request"""
try:
session = await self.bot.getUserSession(ctx.message.author)
data = await Api.postSession('/house/accept-request',{"user_id": user_id} , session)
await ctx.send('Membership accepted')
except ApiError as error:
await ctx.send(error.message)
@commands.command()
async def rejectRequest(self, ctx, user_id:int):
"""Refuse membership request"""
try:
session = await self.bot.getUserSession(ctx.message.author)
data = await Api.deleteSession('/house/reject-request/{0}'.format(user_id), session)
await ctx.send('Membership rejected')
except ApiError as error:
await ctx.send(error.message)
\ No newline at end of file
class HouseModel(object):
def __init__(self, id, house_name, house_level, camp_location, liege_id, liege_username):
self.id = id
self.name = house_name
self.level = house_level
self.camp_location = camp_location
self.liege_id = liege_id
self.liege = liege_username
import asyncio
import discord
import json
from tabulate import tabulate
from datetime import datetime
from dateutil import parser
from discord.ext import commands
from util.api_requests import Api, ApiError
from util.embed_style import EmbedStyle
class WarManager(commands.Cog):
def __init__(self, bot, loop=None):
self.bot = bot
self.loop = loop or asyncio.get_event_loop()
@commands.command()
async def currentWar(self, ctx):
"""Get current war information"""
try:
data = await Api.get('/house/current-war');
date = parser.parse(data.get('day'))
await ctx.send('Current War Date: {0}/{1}/{2}'.format(date.year, date.month, date.day))
except ApiError as error:
await ctx.send(error.message)
async def warParticipation(self, ctx, decision):
try:
session = await self.bot.getUserSession(ctx.message.author)
await Api.postSession('/house/participation', {"decision": decision}, session)
await ctx.send('Participation updated')
except ApiError as error:
await ctx.send(error.message)
@commands.command(aliases=["si"])
async def warYes(self, ctx):
"""Yes confirmation to current war"""
await self.warParticipation(ctx, "Yes")
@commands.command(aliases=["no"])
async def warNo(self, ctx):
"""No confirmation to current war"""
await self.warParticipation(ctx, "No")
@commands.command(aliases=["idk"])
async def warIdk(self, ctx):
"""Maybe confirmation to current war"""
await self.warParticipation(ctx, "Maybe")
@commands.command()
async def houseParticipation(self, ctx):
try:
session = await self.bot.getUserSession(ctx.message.author)
data = await Api.getSession('/house/participation', session)
date = parser.parse(data['war'].get('day'))
await ctx.send('Participation for War: {0}/{1}/{2}'.format(date.year, date.month, date.day))
await EmbedStyle.createPages(self.bot, ctx, data.get('participation'), 10, self.craftParticipationPage)
except ApiError as error:
await ctx.send(error.message)
def craftParticipationPage(self, data, minI, maxI):
embed = discord.Embed(color=0x19212d)
embed.set_author(name='Conquy')
table = []
for i in range(minI, maxI):
if i < len(data):
part = data[i]
item = part.values()
table.append(item)
headers = ["Name", "Decision"]
max_lens = [len(str(max(i, key=lambda x: len(str(x))))) for i in zip(headers, *table)]
participation_str = '```';
for row in (headers, *table):
participation_str += (' | '.join('{0:{width}}'.format(x, width=y) for x, y in zip(row, max_lens))) + '\n'
participation_str +='```'
embed.add_field(name='Participation', value=participation_str)
return embed
\ No newline at end of file
......@@ -2,4 +2,6 @@ discord.py
python-dotenv
requests
pycryptodome
discord-argparse==1.0.0
\ No newline at end of file
discord-argparse==1.0.0
python-dateutil
tabulate
\ No newline at end of file
......@@ -119,11 +119,11 @@ class UnitManager(commands.Cog):
"""Gets all units"""
data = await Api.get('/unit/all')
if(data==None or len(data['units'])==0):
if(data==None or len(data)==0):
return await ctx.send('No units found')
units_data = []
for item in data['units']:
for item in data:
units_data.append(Unit(**item))
await self.createUnitTable(ctx, units_data)
......
import asyncio
import discord
import json
from discord.ext import commands
from discord.user import User
from unit.model import Unit
from util.api_requests import Api, ApiError
from util.embed_style import EmbedStyle
from .uu_parameters import *
import random
import string
from discord.ext import commands
from discord.user import User
from unit.model import Unit
from util.api_requests import Api, ApiError
from util.embed_style import EmbedStyle
from .uu_parameters import *
class UserManager(commands.Cog):
......@@ -18,14 +20,26 @@ class UserManager(commands.Cog):
async def handleApiError(self, ctx, error):
return await ctx.send(error.message)
def randomPassword(self, stringLength=10):
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(stringLength))
@commands.command()
async def registerUser(self, ctx):
"""Register user. Only done once per user. Can't access user related content otherwise"""
req_body = {'discordId': ctx.message.author.id}
async def registerUser(self, ctx, *, params:register_params=register_params.defaults()):
"""Register user. Only done once per user. Can't access user related content otherwise.
Username is optional and the discord username is default. Password is random if not specified"""
username = params.get('username')
user = ctx.message.author;
if(username==None):
username = user.name
password = params.get('password')
if(password==None):
password = self.randomPassword(random.randint(8, 16))
req_body = {'discordId': ctx.message.author.id, 'username': username, 'password': password}
try:
await Api.post('/user/discord-register', req_body)
await ctx.send('Register succesful')
await user.send('Register succesful\nUsername: {0}\nPassword: {1}'.format(username, password))
except ApiError as error:
return await self.handleApiError(ctx, error)
......@@ -126,7 +140,7 @@ class UserManager(commands.Cog):
session = await self.bot.getUserSession(ctx.message.author)
data = await Api.getSession('/user/units', session)
units_data = []
for item in data['units']:
for item in data:
units_data.append(Unit(**item))
return await EmbedStyle.createPages(self.bot, ctx, units_data, 5, self.createUnitPage)
except ApiError as error:
......
......@@ -9,4 +9,15 @@ param_converter = ArgumentConverter(
bool,
doc='Is Unit Elite',
)
)
register_params = ArgumentConverter(
username = OptionalArgument(
str,
doc='Username for web app',
),
password = OptionalArgument(
str,
doc='Password for web app',
)
)
\ No newline at end of file
......@@ -5,6 +5,8 @@ class EmbedStyle:
@staticmethod
async def createPages(bot, ctx, data, max_rows, createRowsFunc):
if(len(data) == 0):
return await ctx.send('No data')
max_pages = len(data) // max_rows
rem = len(data) % max_rows
cur_page = 0;
......@@ -16,7 +18,6 @@ class EmbedStyle:
while True:
if first_run:
embed = createRowsFunc(data, max_rows*cur_page, max_rows*cur_page + max_rows)
first_run = False
msg = await ctx.send(embed=embed)
......@@ -45,19 +46,34 @@ class EmbedStyle:
try:
res, user = await bot.wait_for('reaction_add', timeout=30.0, check=check_react)
except TimeoutError:
return await msg.clear_reactions()
return await EmbedStyle.pagesTimeout(msg)
if '⏪' in str(res.emoji):
cur_page-= 1
embed = createRowsFunc(data, max_rows*cur_page, max_rows*cur_page + max_rows)
await msg.clear_reactions()
await msg.edit(embed=embed)
msg = await EmbedStyle.changePage(ctx, msg, embed)
if '⏩' in str(res.emoji):
cur_page+= 1
embed = createRowsFunc(data, max_rows*cur_page, max_rows*cur_page + max_rows)
await msg.clear_reactions()
await msg.edit(embed=embed)
\ No newline at end of file
msg = await EmbedStyle.changePage(ctx, msg, embed)
@staticmethod
async def pagesTimeout(msg):
if isinstance(msg.channel, discord.channel.DMChannel):
return await msg.delete();
else:
return await msg.clear_reactions();
@staticmethod
async def changePage(ctx, msg, embed):
if isinstance(msg.channel, discord.channel.DMChannel):
await msg.delete();
return await ctx.send(embed=embed)
else:
await msg.clear_reactions();
await msg.edit(embed=embed)
return msg
......@@ -4,6 +4,14 @@ const model = {};
const h_columns = ['house_name', 'house_level', 'camp_location'];
async function checkHouseRequest(house_id, user_id){
const sql_exists = 'SELECT EXISTS(SELECT * FROM house_requests WHERE house_id = ? AND user_id = ?) as result;'
const exists = await db.con.query(sql_exists, [house_id , user_id]);
if(exists[0] && exists[0].result===0){
throw Error("Membership request not send for user's house")
}
}
model.getAll = async () => {
const sql_text = `SELECT h.*, u.username as liege_username
FROM houses as h
......@@ -30,7 +38,7 @@ model.insertHouse = async(body, liege_id) => {
if(body){
for (let i = 0; i < h_columns.length; i++) {
const element = h_columns[i];
if(body[element]!==undefined){
if(body[element]!==undefined && body[element]!==null){
column_text += ', ' + element;
value_text += ', ' + db.con.escape(body[element]);
}
......@@ -59,7 +67,7 @@ model.modifyHouse = async(house_id, body) => {
for (let i = 0; i < h_columns.length; i++) {
const element = h_columns[i];
if(body[element]!==undefined){
if(body[element]!==undefined && body[element]!==null){
if(set_text===''){
set_text += `${element} = ${db.con.escape(body[element])}`;
}else{
......@@ -116,6 +124,7 @@ model.getHouseRequests = async(house_id) => {
}
model.acceptRequest = async(user_id, house_id) => {
checkHouseRequest(house_id, user_id);
const sql_text = 'DELETE FROM house_requests WHERE user_id = ?;';
const sql_text2 = 'UPDATE users SET house_id = ?, lk_house_role = \'kng\' WHERE id = ?;';
......@@ -127,7 +136,9 @@ model.acceptRequest = async(user_id, house_id) => {
await db.con.query('COMMIT;');
}
model.rejectRequest = async(user_id) => {
model.rejectRequest = async(user_id, house_id) => {
checkHouseRequest(house_id, user_id);
const sql_text = 'DELETE FROM house_requests WHERE user_id = ?;';
await db.con.query(sql_text, [user_id]);
......
......@@ -182,14 +182,12 @@ authRouter.get('/requests', async (context, next) => {
});
authRouter.post('/accept-request', async (context, next) => {
checkHouse(context);
checkPermissions(context, HOUSE_ROLES.sen);
try{
const body = context.request.body;
if(!body || !body.user_id){
throw Error("No user to accept");
}
console.log(body.user_id);
await houseModel.acceptRequest(body.user_id, context.user.house_id);
context.response.status = 204;
}catch(error){
......@@ -199,14 +197,13 @@ authRouter.post('/accept-request', async (context, next) => {
});
authRouter.delete('/reject-request/:user_id', async (context, next) => {
checkHouse(context);
checkPermissions(context, HOUSE_ROLES.sen);
try{
const body = context.request.body;
if(!context.params.user_id){
throw Error("No user to refuse");
}
await houseModel.rejectRequest(context.params.user_id);
await houseModel.rejectRequest(context.params.user_id, context.user.house_id);
context.response.status = 204;
}catch(error){
console.log(error);
......@@ -288,17 +285,13 @@ authRouter.post('/', async (context, next) => {
}
});
authRouter.put('/:house_id', async (context, next) => {
console.log('asd')
checkHouse(context);
authRouter.put('/', async (context, next) => {
checkPermissions(context, HOUSE_ROLES.LIEGE)
try{
console.log('dsa')
const body = context.request.body;
if(!body){
throw Error('No params')
}
console.log(body)
await houseModel.modifyHouse(context.user.house_id, body);
context.response.status = 204;
}catch(error){
......@@ -307,11 +300,10 @@ authRouter.put('/:house_id', async (context, next) => {
}
});
authRouter.delete('/:house_id', async (context, next) => {
checkHouse(context);
authRouter.delete('/', async (context, next) => {
checkPermissions(context, HOUSE_ROLES.LIEGE);
try{
await houseModel.deleteHouse(context.params.house_id, context.user.id);
await houseModel.deleteHouse(context.user.house_id, context.user.id);
context.response.status = 204;
}catch(error){
console.log(error);
......@@ -322,9 +314,13 @@ authRouter.delete('/:house_id', async (context, next) => {
authRouter.get('/participation', async (context, next) => {
hasHouse(context);
try{
const data = await houseModel.getParticipation(context.user.house_id);
const war = await houseModel.getCurrentWar();
if(!war){
throw Error('Failed to get Current War');
}
const participation = await houseModel.getParticipation(context.user.house_id);
context.response.status = 200;
context.response.body = data;
context.response.body = {war: war, participation: participation};
}catch(error){
console.log(error);
context.throw('Failed to get Participation');
......
......@@ -59,7 +59,7 @@ async function main(){
app.use(authRouter.routes()).use(authRouter.allowedMethods());
app.listen(3000, () => console.log('Server Started'));
app.listen(process.env.SEV_PORT ? process.env.SEV_PORT : 3000, () => console.log('Server Started'));
}
......
require('dotenv').config()
env_path = process.cwd() + '/.env'
require('dotenv').config(env_path)
SETTINGS = process.env;
module.exports = SETTINGS;
\ No newline at end of file
......@@ -59,7 +59,7 @@ unitModel.modifyUnit = async (id, body) => {
for (let i = 0; i < unit_columns.length; i++) {
const element = unit_columns[i];
if(body[element]!==undefined){
if(body[element]!==undefined && body[element]!==null){
if(set_text===''){
set_text += `${element} = ${db.con.escape(body[element])}`;
}else{
......
......@@ -6,10 +6,9 @@ const Router = require('@koa/router');
const router = new Router();
const unitModel = require('./model');
router.get('/all', async (context, next) =>{
const sql_text = 'SELECT * FROM units ORDER BY name ASC;';
try{
const data = await unitModel.getAll();
context.response.body = {units: data};
context.response.body = data;
}catch(error){
console.log(error);
context.throw(500, 'Server Error');
......
......@@ -104,7 +104,7 @@ userModel.assignUserUnit = async(id, unit_id, body) =>{
if(body){
for (let i = 0; i < uu_columns.length; i++) {
const element = uu_columns[i];
if(body[element]!==undefined){
if(body[element]!==undefined && body[element]!==null){
column_text += ', ' + element;
value_text += ', ' + db.con.escape(body[element]);
}
......@@ -120,7 +120,7 @@ userModel.modifyUserUnit = async(id, unit_id, body) =>{
for (let i = 0; i < uu_columns.length; i++) {
const element = uu_columns[i];
if(body[element]!==undefined){
if(body[element]!==undefined && body[element]!==null){
if(set_text===''){
set_text += `${element} = ${db.con.escape(body[element])}`;
}else{
......@@ -147,14 +147,14 @@ userModel.addDiscordIdToUser = async (user_id, discord_id) =>{
const data = await db.con.query(sql_text, [discordId, user_id])
}
userModel.createUserWithDiscord = async (discord_id) =>{
const sql_text = 'INSERT INTO users (discord_id) VALUES (?);';
await db.con.query(sql_text, [discord_id]);
userModel.createUserWithDiscord = async (discord_id, username, password) =>{
const hashPassword = await crypto.hash(password);
const sql_text = 'INSERT INTO users (discord_id, username, password) VALUES (?, ?, ?);';
await db.con.query(sql_text, [discord_id, username, hashPassword]);
}
userModel.registerUser = async (username, password) =>{
const hashPassword = await crypto.hash(password);
console.log(username, hashPassword)
const sql_text = 'INSERT INTO users (username, password) VALUES (?, ?)';
await db.con.query(sql_text, [username, hashPassword])
......
......@@ -77,6 +77,7 @@ router.post('/discord-register', async(context, next) =>{
try{
await userModel.addDiscordIdToUser(context.user.id, discord_id);
context.status = 204;
return;
}catch(error){
console.log(error);
context.throw(422, 'Invalid Discord Id')
......@@ -91,8 +92,11 @@ router.post('/discord-register', async(context, next) =>{
context.throw(422, 'Invalid Discord Id')
}
if(!user){
if(!body.username || !body.password){
context.throw(422, 'Missing parameters')
}
try{
await userModel.createUserWithDiscord(discord_id);
await userModel.createUserWithDiscord(discord_id, body.username, body.password);
context.status = 204;
}catch(error){
context.throw(422, 'Failed to create user with Discord Id')
......@@ -108,7 +112,7 @@ authRouter.get('/units', async (context, next) => {
if(data.length===1 && data[0].id===null){
throw Error('No Units Found')
}
context.response.body = {units: data};
context.response.body = data;
context.status = 200;
}catch(error){
console.log(error)
......@@ -122,7 +126,7 @@ authRouter.get('/units-inverse', async (context, next) => {
if(data.length===1 && data[0].id===null){
throw Error('No Units Found')
}
context.response.body = {units: data};
context.response.body = data;
context.status = 200;
}catch(error){
console.log(error)
......
......@@ -5,7 +5,7 @@ class HouseView extends EventTarget{
this.element = element;
this.is_editing = false;
this.modify_btn = this.element.querySelector('#modify_btn');
this.modify_btn = this.element.querySelector('#modify_btn');
this.create_btn = this.element.querySelector('#create_btn')
this.edit_btn = this.element.querySelector('#edit_btn');
this.title = this.element.querySelector('#title');
......@@ -34,7 +34,7 @@ class HouseView extends EventTarget{
});
this.create_btn.addEventListener("click", () => {
this.dispatchEvent(new CustomEvent("create_house", {detail: {
house_name: this.edit_fields.name.value,
house_name: this.edit_fields.name.value,
house_level: this.edit_fields.house_level.value,
camp_location: this.edit_fields.camp_location.value,
}}))
......@@ -42,7 +42,7 @@ class HouseView extends EventTarget{
this.modify_btn.addEventListener("click", () => {
this.dispatchEvent(new CustomEvent("modify_house", {detail: {
house_id: this.house.id,
house_name: this.edit_fields.name.value ? this.edit_fields.name.value : this.house.name,
house_name: this.edit_fields.name.value ? this.edit_fields.name.value : this.house.name,
house_level: this.edit_fields.house_level.value ? this.edit_fields.house_level.value : this.house.house_level,
camp_location: this.edit_fields.camp_location.value ? this.edit_fields.camp_location.name.value : this.house.camp_location,
}}))
......
......@@ -25,7 +25,7 @@ class Sync{
}
async modifyHouse(house){
const response = await fetch(`/api/house/${house.id}`, {
const response = await fetch(`/api/house`, {
method: "PUT",
body: JSON.stringify(house),
headers: {
......
......@@ -57,7 +57,7 @@ class MyUnitsController{
async getMyUnits(){
this.data = [];
try{
this.data = (await this.sync.getMyUnits()).units;
this.data = await this.sync.getMyUnits();
}catch(error){
console.log(error);
// alert('Failed to get units')
......@@ -68,7 +68,7 @@ class MyUnitsController{
async getUnitsToAdd(){
this.data = [];
try{
this.data = (await this.sync.getUnitsToAdd()).units;
this.data = await this.sync.getUnitsToAdd();
}catch(error){
console.log(error);
// alert('Failed to get units')
......
......@@ -8,7 +8,7 @@ class UnitTableController{
async getAllUnits(){
try{
const units_response = await fetch('/api/unit/all');
this.view.drawTable((await units_response.json()).units);
this.view.drawTable(await units_response.json());
}catch(error){
console.log(error);
alert('Failed to get units')
......
......@@ -11,9 +11,9 @@ class TableView extends EventTarget{
throw Error('Columns are needed');
}
this.$element = $(element);
this.columns = columns;
this.columns = columns;
this.$table = this.$element.find('#data_table');
this.datatable = this.$table.DataTable({
this.datatable = this.$table.DataTable({
columns: this.columns
});
if(overflow){
......@@ -36,7 +36,7 @@ class TableView extends EventTarget{
const data_set = data.map((ele) => {
var d = [];
this.columns.forEach((col) =>{
const t = ele[col.term] !== undefined ? ele[col.term] : '-'
const t = ele[col.term] !== undefined ? ele[col.term] : '-';
d.push(t);
})
return d;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment