add ota update channels
This commit is contained in:
@ -435,7 +435,7 @@ class AllnetServlet:
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
machine = await self.data.arcade.get_machine(req.serial)
|
machine = await self.data.arcade.get_machine(req.serial)
|
||||||
if not machine or not machine['ota_enable'] or not machine['is_cab']:
|
if not machine or not machine['ota_channel'] or not machine['is_cab']:
|
||||||
resp = urllib.parse.unquote(urllib.parse.urlencode(vars(resp))) + "\n"
|
resp = urllib.parse.unquote(urllib.parse.urlencode(vars(resp))) + "\n"
|
||||||
if is_dfi:
|
if is_dfi:
|
||||||
return PlainTextResponse(
|
return PlainTextResponse(
|
||||||
@ -446,15 +446,13 @@ class AllnetServlet:
|
|||||||
return PlainTextResponse(content=self.enc_lite(litekey, iv, resp))
|
return PlainTextResponse(content=self.enc_lite(litekey, iv, resp))
|
||||||
return PlainTextResponse(resp)
|
return PlainTextResponse(resp)
|
||||||
|
|
||||||
if path.exists(
|
update = await self.data.arcade.get_ota_update(req.game_id, req.ver, machine['ota_channel'])
|
||||||
f"{self.config.allnet.update_cfg_folder}/{req.game_id}-{req.ver.replace('.', '')}-app.ini"
|
if update:
|
||||||
):
|
if update['app_ini'] and path.exists(f"{self.config.allnet.update_cfg_folder}/{update['app_ini']}"):
|
||||||
resp.uri = f"http://{self.config.server.hostname}:{self.config.server.port}/dl/ini/{req.game_id}-{req.ver.replace('.', '')}-app.ini"
|
resp.uri = f"http://{self.config.server.hostname}:{self.config.server.port}/dl/ini/{update['app_ini']}"
|
||||||
|
|
||||||
if path.exists(
|
if update['opt_ini'] and path.exists(f"{self.config.allnet.update_cfg_folder}/{update['opt_ini']}"):
|
||||||
f"{self.config.allnet.update_cfg_folder}/{req.game_id}-{req.ver.replace('.', '')}-opt.ini"
|
resp.uri += f"|http://{self.config.server.hostname}:{self.config.server.port}/dl/ini/{update['opt_ini']}"
|
||||||
):
|
|
||||||
resp.uri += f"|http://{self.config.server.hostname}:{self.config.server.port}/dl/ini/{req.game_id}-{req.ver.replace('.', '')}-opt.ini"
|
|
||||||
|
|
||||||
if resp.uri:
|
if resp.uri:
|
||||||
self.logger.info(f"Sending download uri {resp.uri}")
|
self.logger.info(f"Sending download uri {resp.uri}")
|
||||||
@ -496,7 +494,7 @@ class AllnetServlet:
|
|||||||
f"{self.config.allnet.update_cfg_folder}/{req_file}", "r", encoding="utf-8"
|
f"{self.config.allnet.update_cfg_folder}/{req_file}", "r", encoding="utf-8"
|
||||||
).read())
|
).read())
|
||||||
|
|
||||||
self.logger.info(f"DL INI File {req_file} not found")
|
self.logger.warning(f"DL INI File {req_file} not found")
|
||||||
return PlainTextResponse()
|
return PlainTextResponse()
|
||||||
|
|
||||||
async def handle_dlorder_report(self, request: Request) -> bytes:
|
async def handle_dlorder_report(self, request: Request) -> bytes:
|
||||||
|
42
core/data/alembic/versions/7070a6fa8cdc_update_channels.py
Normal file
42
core/data/alembic/versions/7070a6fa8cdc_update_channels.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
"""update_channels
|
||||||
|
|
||||||
|
Revision ID: 7070a6fa8cdc
|
||||||
|
Revises: f6007bbf057d
|
||||||
|
Create Date: 2025-09-27 16:09:55.853051
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '7070a6fa8cdc'
|
||||||
|
down_revision = 'f6007bbf057d'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('machine_update',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('game', sa.CHAR(length=4), nullable=False),
|
||||||
|
sa.Column('version', sa.VARCHAR(length=15), nullable=False),
|
||||||
|
sa.Column('channel', sa.VARCHAR(length=260), nullable=False),
|
||||||
|
sa.Column('app_ini', sa.VARCHAR(length=260), nullable=True),
|
||||||
|
sa.Column('opt_ini', sa.VARCHAR(length=260), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('game', 'version', 'channel', name='machine_update_uk'),
|
||||||
|
mysql_charset='utf8mb4'
|
||||||
|
)
|
||||||
|
op.add_column('machine', sa.Column('ota_channel', sa.VARCHAR(length=260), nullable=True))
|
||||||
|
op.drop_column('machine', 'ota_enable')
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('machine', sa.Column('ota_enable', mysql.TINYINT(display_width=1), autoincrement=False, nullable=True))
|
||||||
|
op.drop_column('machine', 'ota_channel')
|
||||||
|
op.drop_table('machine_update')
|
||||||
|
# ### end Alembic commands ###
|
@ -7,7 +7,7 @@ from sqlalchemy.dialects.mysql import insert
|
|||||||
from sqlalchemy.engine import Row
|
from sqlalchemy.engine import Row
|
||||||
from sqlalchemy.sql import func, select
|
from sqlalchemy.sql import func, select
|
||||||
from sqlalchemy.sql.schema import ForeignKey, PrimaryKeyConstraint
|
from sqlalchemy.sql.schema import ForeignKey, PrimaryKeyConstraint
|
||||||
from sqlalchemy.types import JSON, Boolean, Integer, String, BIGINT, INTEGER, CHAR, FLOAT
|
from sqlalchemy.types import JSON, Boolean, Integer, String, BIGINT, INTEGER, CHAR, FLOAT, VARCHAR
|
||||||
|
|
||||||
from core.data.schema.base import BaseData, metadata
|
from core.data.schema.base import BaseData, metadata
|
||||||
|
|
||||||
@ -41,13 +41,26 @@ machine: Table = Table(
|
|||||||
Column("game", String(4)),
|
Column("game", String(4)),
|
||||||
Column("country", String(3)), # overwrites if not null
|
Column("country", String(3)), # overwrites if not null
|
||||||
Column("timezone", String(255)),
|
Column("timezone", String(255)),
|
||||||
Column("ota_enable", Boolean),
|
|
||||||
Column("memo", String(255)),
|
Column("memo", String(255)),
|
||||||
Column("is_cab", Boolean),
|
Column("is_cab", Boolean),
|
||||||
|
Column("ota_channel", VARCHAR(260)),
|
||||||
Column("data", JSON),
|
Column("data", JSON),
|
||||||
mysql_charset="utf8mb4",
|
mysql_charset="utf8mb4",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
update: Table = Table(
|
||||||
|
"machine_update",
|
||||||
|
metadata,
|
||||||
|
Column("id", Integer, primary_key=True, nullable=False),
|
||||||
|
Column("game", CHAR(4), nullable=False),
|
||||||
|
Column("version", VARCHAR(15), nullable=False),
|
||||||
|
Column("channel", VARCHAR(260), nullable=False),
|
||||||
|
Column("app_ini", VARCHAR(260)),
|
||||||
|
Column("opt_ini", VARCHAR(260)),
|
||||||
|
UniqueConstraint("game", "version", "channel", name="machine_update_uk"),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
arcade_owner: Table = Table(
|
arcade_owner: Table = Table(
|
||||||
"arcade_owner",
|
"arcade_owner",
|
||||||
metadata,
|
metadata,
|
||||||
@ -250,12 +263,12 @@ class ArcadeData(BaseData):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def set_machine_can_ota(self, machine_id: int, can_ota: bool = False) -> bool:
|
async def set_machine_ota_channel(self, machine_id: int, channel_name: Optional[str] = None) -> bool:
|
||||||
sql = machine.update(machine.c.id == machine_id).values(ota_enable = can_ota)
|
sql = machine.update(machine.c.id == machine_id).values(ota_channel = channel_name)
|
||||||
|
|
||||||
result = await self.execute(sql)
|
result = await self.execute(sql)
|
||||||
if result is None:
|
if result is None:
|
||||||
self.logger.error(f"Failed to update machine {machine_id} ota_enable to {can_ota}")
|
self.logger.error(f"Failed to update machine {machine_id} ota channel to {channel_name}")
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -530,6 +543,29 @@ class ArcadeData(BaseData):
|
|||||||
if result is not None:
|
if result is not None:
|
||||||
return result.fetchone()
|
return result.fetchone()
|
||||||
|
|
||||||
|
async def create_ota_update(self, game_id: str, ver: str, channel: str, app: Optional[str], opt: Optional[str] = None) -> Optional[int]:
|
||||||
|
result = await self.execute(insert(update).values(
|
||||||
|
game = game_id,
|
||||||
|
version = ver,
|
||||||
|
channel = channel,
|
||||||
|
app_ini = app,
|
||||||
|
opt_ini = opt
|
||||||
|
))
|
||||||
|
|
||||||
|
if result is None:
|
||||||
|
self.logger.error(f"Failed to create {game_id} v{ver} update on channel {channel}")
|
||||||
|
return result.lastrowid
|
||||||
|
|
||||||
|
async def get_ota_update(self, game_id: str, ver: str, channel: str) -> Optional[Row]:
|
||||||
|
result = await self.execute(update.select(and_(
|
||||||
|
and_(update.c.game == game_id, update.c.version == ver),
|
||||||
|
update.c.channel == channel
|
||||||
|
)))
|
||||||
|
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchone()
|
||||||
|
|
||||||
def format_serial(
|
def format_serial(
|
||||||
self, platform_code: str, platform_rev: int, serial_letter: str, serial_num: int, append: int, dash: bool = False
|
self, platform_code: str, platform_rev: int, serial_letter: str, serial_num: int, append: int, dash: bool = False
|
||||||
) -> str:
|
) -> str:
|
||||||
|
@ -1146,7 +1146,7 @@ class FE_Machine(FE_Base):
|
|||||||
new_country = frm.get('country', None)
|
new_country = frm.get('country', None)
|
||||||
new_tz = frm.get('tz', None)
|
new_tz = frm.get('tz', None)
|
||||||
new_is_cab = frm.get('is_cab', False) == 'on'
|
new_is_cab = frm.get('is_cab', False) == 'on'
|
||||||
new_is_ota = frm.get('is_ota', False) == 'on'
|
new_ota_channel = frm.get('ota_channel', None)
|
||||||
new_memo = frm.get('memo', None)
|
new_memo = frm.get('memo', None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -1158,7 +1158,7 @@ class FE_Machine(FE_Base):
|
|||||||
did_country = await self.data.arcade.set_machine_country(cab['id'], new_country if new_country else None)
|
did_country = await self.data.arcade.set_machine_country(cab['id'], new_country if new_country else None)
|
||||||
did_timezone = await self.data.arcade.set_machine_timezone(cab['id'], new_tz if new_tz else None)
|
did_timezone = await self.data.arcade.set_machine_timezone(cab['id'], new_tz if new_tz else None)
|
||||||
did_real_cab = await self.data.arcade.set_machine_real_cabinet(cab['id'], new_is_cab)
|
did_real_cab = await self.data.arcade.set_machine_real_cabinet(cab['id'], new_is_cab)
|
||||||
did_ota = await self.data.arcade.set_machine_can_ota(cab['id'], new_is_ota)
|
did_ota = await self.data.arcade.set_machine_ota_channel(cab['id'], new_ota_channel if new_is_cab else None)
|
||||||
did_memo = await self.data.arcade.set_machine_memo(cab['id'], new_memo if new_memo else None)
|
did_memo = await self.data.arcade.set_machine_memo(cab['id'], new_memo if new_memo else None)
|
||||||
|
|
||||||
if not did_game or not did_country or not did_timezone or not did_real_cab or not did_ota or not did_memo:
|
if not did_game or not did_country or not did_timezone or not did_real_cab or not did_ota or not did_memo:
|
||||||
|
@ -3,13 +3,9 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function swap_ota() {
|
function swap_ota() {
|
||||||
let is_cab = document.getElementById("is_cab").checked;
|
let is_cab = document.getElementById("is_cab").checked;
|
||||||
let cbx_ota = document.getElementById("is_ota");
|
let txt_ota = document.getElementById("ota_channel");
|
||||||
|
|
||||||
cbx_ota.disabled = !is_cab;
|
cbx_ota.disabled = !is_cab;
|
||||||
|
|
||||||
if (cbx_ota.disabled) {
|
|
||||||
cbx_ota.checked = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<h1>Machine: {{machine.serial}}</h1>
|
<h1>Machine: {{machine.serial}}</h1>
|
||||||
@ -64,8 +60,8 @@ Info
|
|||||||
<label for="is_cab" class="form-label">Real Cabinet</label>
|
<label for="is_cab" class="form-label">Real Cabinet</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col mb-3">
|
<div class="col mb-3">
|
||||||
<input type="checkbox" class="form-control-check" id="is_ota" name="is_ota" {{ 'checked' if machine.ota_enable else ''}}>
|
<input type="text" class="form-control-check" id="ota_channel" name="ota_channel" value={{ machine.ota_channel }} {{ 'disabled' if not machine.is_cab else '' }}>
|
||||||
<label for="is_ota" class="form-label">Allow OTA updates</label>
|
<label for="ota_channel" class="form-label">OTA Update Channel</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col mb-3">
|
<div class="col mb-3">
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user