card: add memos

This commit is contained in:
Hay1tsme 2024-07-06 23:13:41 -04:00
parent 15cf56ed9b
commit c65c71e89e
4 changed files with 85 additions and 8 deletions

View File

@ -0,0 +1,28 @@
"""card_add_memo
Revision ID: 5ea73f89d982
Revises: 745448d83696
Create Date: 2024-07-06 22:46:56.992152
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision = '5ea73f89d982'
down_revision = '745448d83696'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('aime_card', sa.Column('memo', sa.VARCHAR(length=16), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('aime_card', 'memo')
# ### end Alembic commands ###

View File

@ -1,6 +1,6 @@
from typing import Dict, List, Optional from typing import Dict, List, Optional
from sqlalchemy import Table, Column, UniqueConstraint from sqlalchemy import Table, Column, UniqueConstraint
from sqlalchemy.types import Integer, String, Boolean, TIMESTAMP, BIGINT from sqlalchemy.types import Integer, String, Boolean, TIMESTAMP, BIGINT, VARCHAR
from sqlalchemy.sql.schema import ForeignKey from sqlalchemy.sql.schema import ForeignKey
from sqlalchemy.sql import func from sqlalchemy.sql import func
from sqlalchemy.engine import Row from sqlalchemy.engine import Row
@ -19,6 +19,7 @@ aime_card = Table(
Column("last_login_date", TIMESTAMP, onupdate=func.now()), Column("last_login_date", TIMESTAMP, onupdate=func.now()),
Column("is_locked", Boolean, server_default="0"), Column("is_locked", Boolean, server_default="0"),
Column("is_banned", Boolean, server_default="0"), Column("is_banned", Boolean, server_default="0"),
Column("memo", VARCHAR(16)),
UniqueConstraint("user", "access_code", name="aime_card_uk"), UniqueConstraint("user", "access_code", name="aime_card_uk"),
mysql_charset="utf8mb4", mysql_charset="utf8mb4",
) )
@ -148,6 +149,11 @@ class CardData(BaseData):
if not result: if not result:
self.logger.error(f"Failed to change card access code from {old_ac} to {new_ac}") self.logger.error(f"Failed to change card access code from {old_ac} to {new_ac}")
async def set_memo_by_access_code(self, access_code: str, memo: str) -> None:
result = await self.execute(aime_card.update(aime_card.c.access_code == access_code).values(memo=memo))
if not result:
self.logger.error(f"Failed to add memo to card {access_code}")
def to_access_code(self, luid: str) -> str: def to_access_code(self, luid: str) -> str:
""" """
Given a felica cards internal 16 hex character luid, convert it to a 0-padded 20 digit access code as a string Given a felica cards internal 16 hex character luid, convert it to a 0-padded 20 digit access code as a string

View File

@ -476,10 +476,10 @@ class FE_User(FE_Base):
card_data.append({ card_data.append({
'access_code': ac, 'access_code': ac,
'status': status, 'status': status,
'chip_id': "", #None if c['chip_id'] is None else f"{c['chip_id']:X}", 'chip_id': c['chip_id'],
'idm': "", 'idm': c['idm'],
'type': c_type, 'type': c_type,
"memo": "" "memo": c['memo']
}) })
if "e" in request.query_params: if "e" in request.query_params:
@ -516,7 +516,42 @@ class FE_User(FE_Base):
return resp return resp
async def edit_card(self, request: Request) -> RedirectResponse: async def edit_card(self, request: Request) -> RedirectResponse:
return RedirectResponse("/user/", 303) frm = await request.form()
usr_sesh = self.validate_session(request)
if not usr_sesh or not self.test_perm(usr_sesh.permissions, PermissionOffset.USERMOD):
return RedirectResponse("/gate/", 303)
frm = await request.form()
ac = frm.get("add_access_code", None)
if not ac:
return RedirectResponse("/user/?e=999", 303)
card = await self.data.card.get_card_by_access_code(ac)
if not card:
return RedirectResponse("/user/?e=2", 303)
if card['user'] != usr_sesh.user_id and not self.test_perm_minimum(usr_sesh.permissions, PermissionOffset.USERMOD):
return RedirectResponse("/user/?e=11", 303)
if frm.get("add_memo", None):
memo = frm.get("add_memo")
if len(memo) > 16 or len(memo) == 0:
return RedirectResponse("/user/?e=4", 303)
await self.data.card.set_memo_by_access_code(ac, memo)
if frm.get("add_felica_idm", None):
idm = frm.get('add_felica_idm')
if not all(c in string.hexdigits for c in idm):
return RedirectResponse("/user/?e=4", 303)
await self.data.card.set_idm_by_access_code(ac, idm)
if frm.get("add_mifare_chip_id", None):
chip_id: str = frm.get('add_mifare_chip_id')
if not all(c in string.hexdigits for c in idm):
return RedirectResponse("/user/?e=4", 303)
await self.data.card.set_chip_id_by_access_code(ac, int(chip_id, 16))
return RedirectResponse("/user/?s=4", 303)
async def add_card(self, request: Request) -> RedirectResponse: async def add_card(self, request: Request) -> RedirectResponse:
return RedirectResponse("/user/", 303) return RedirectResponse("/user/", 303)

View File

@ -49,11 +49,14 @@ function prep_edit_form(access_code, chip_id, idm, card_type, u_memo) {
fidm.value = idm; fidm.value = idm;
memo.value = u_memo; memo.value = u_memo;
if (card_type == "AmusementIC") { if (access_code.startsWith("3") || access_code.startsWith("010")) {
cid.disabled = false;
fidm.disabled = true;
} else if (access_code.startsWith("5")) {
cid.disabled = true; cid.disabled = true;
fidm.disabled = false; fidm.disabled = false;
} else { } else {
cid.disabled = false; cid.disabled = true;
fidm.disabled = true; fidm.disabled = true;
} }
} }
@ -91,9 +94,14 @@ Card added successfully
</form> </form>
<br> <br>
</div> </div>
{% if success is defined and success == 4 %}
<div style="background-color: #00AA00; padding: 20px; margin-bottom: 10px; width: 15%;">
Update successful
</div>
{% endif %}
<ul style="font-size: 20px;"> <ul style="font-size: 20px;">
{% for c in cards %} {% for c in cards %}
<li>{{ c.access_code }} ({{ c.type}}): {{ c.status }}&nbsp;<button onclick="prep_edit_form('{{ c.access_code }}', '{{ c.chip_id}}', '{{ c.idm }}', '{{ c.type }}', '{{ c.memo }}')" data-bs-toggle="modal" data-bs-target="#card_edit" class="btn btn-secondary" id="btn_edit_card_{{ c.access_code }}">Edit</button>&nbsp;{% if c.status == 'Active'%}<button class="btn-warning btn">Lock</button>{% elif c.status == 'Locked' %}<button class="btn-warning btn">Unlock</button>{% endif %}&nbsp;<button class="btn-danger btn">Delete</button></li> <li>{{ c.access_code }} ({{ c.type if c.memo is none or not c.memo else c.memo }}): {{ c.status }}&nbsp;<button onclick="prep_edit_form('{{ c.access_code }}', '{{ c.chip_id}}', '{{ c.idm }}', '{{ c.type }}', '{{ c.memo }}')" data-bs-toggle="modal" data-bs-target="#card_edit" class="btn btn-secondary" id="btn_edit_card_{{ c.access_code }}">Edit</button>&nbsp;{% if c.status == 'Active'%}<button class="btn-warning btn">Lock</button>{% elif c.status == 'Locked' %}<button class="btn-warning btn">Unlock</button>{% endif %}&nbsp;<button class="btn-danger btn" {{ "disabled" if cards|length == 1 else ""}}>Delete</button></li>
{% endfor %} {% endfor %}
</ul> </ul>