Skip to content

Commit

Permalink
Use the same track.data.json encoding as the editor
Browse files Browse the repository at this point in the history
I found timestamp, extra bytes and indent first, but chaning that didn't help.
Only using this weird encoding fixed HTTP 500 errors when uploading.
  • Loading branch information
adosikas committed Dec 8, 2024
1 parent 59f0444 commit 280b30b
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ dependencies = [
"matplotlib==3.9.3",
"plotly==5.24.1",
"pyperclip==1.9.0",
"watchdog==5.0.3",
"watchdog==6.0.0",
"requests==2.32.3",
"nicegui==2.7.0",
"nicegui==2.8.1",
"librosa==0.10.2.post1",
"soundfile==0.12.1",
"pywin32==308; sys_platform=='win32'",
Expand Down
2 changes: 1 addition & 1 deletion src/synth_mapping_helper/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.5.8"
__version__ = "1.5.9"

from . import movement
from . import pattern_generation
Expand Down
30 changes: 23 additions & 7 deletions src/synth_mapping_helper/synth_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
import re
import time
from typing import Any, Generator, Literal, Union
import zipfile
import struct
import sys
import zipfile

import numpy as np
import pyperclip
Expand Down Expand Up @@ -568,6 +569,21 @@ def encode(self, encoding: str = "utf-8", errors: str = "strict") -> bytes:
raise UnicodeEncodeError(encoding, self, 0, 0, "dummy error to trick ZipFile._open_to_write")
return super().encode(encoding=encoding, errors=errors)

def encode_extra_pkware_win32(timestamp: datetime.datetime) -> bytes:
# https://mdfs.net/Docs/Comp/Archiving/Zip/ExtraField -> 0x000A
# encode NTFS timestamp
ntfs_epoch = datetime.datetime(1601,1,1, 0,0,0,0, tzinfo=datetime.timezone.utc)
ts_bytes = int((timestamp - ntfs_epoch).total_seconds()*1e7).to_bytes(8, "little")

return struct.pack(
"<HHIHH",
0x000a, # PKWARE Win95/WinNT Extra Field
32, # extra len: 4+2+2+24
0, # reserved
1, # Tag 1
24, # 3*8
) + (ts_bytes * 3)

@dataclasses.dataclass
class SynthFileMeta:
name: str
Expand Down Expand Up @@ -789,7 +805,7 @@ def save_as(self, output_file: Union[Path, BytesIO]) -> None:
"Tags": [], # ?
"BeatConverted": False, # ?
"BeatModified": False, # ?
"ModifiedTime": now.timestamp(),
"ModifiedTime": int(now.timestamp()),
"Explicit": self.meta.explicit,
}

Expand Down Expand Up @@ -829,15 +845,15 @@ def save_as(self, output_file: Union[Path, BytesIO]) -> None:
meta_json = json.dumps({
"name": self.meta.name,
"artist": self.meta.artist,
"duration": f"{self.audio.duration//60:.0f}:{self.audio.duration%60:02.0f}",
"duration": f"{self.audio.duration//60:02.0f}:{self.audio.duration%60:02.0f}",
"coverImage": self.meta.cover_name,
"audioFile": safe_audio_name,
"supportedDifficulties": [
d if self.difficulties.get(d, False) else "" for d in DIFFICULTIES
],
"bpm": self.bpm,
"mapper": self.meta.mapper,
}, indent=2, allow_nan=False)
}, indent=4, allow_nan=False)

with zipfile.ZipFile(out_buffer, "w") as outzip:
def make_fileinfo(filename: str) -> zipfile.ZipInfo:
Expand All @@ -846,8 +862,8 @@ def make_fileinfo(filename: str) -> zipfile.ZipInfo:
# fake various file headers
info.create_system = 0
info.create_version = zipfile.ZIP64_VERSION
# editor files also contain NTFS timestamps, see "PKWARE Win95/WinNT Extra Field (0x000a)"" at
# https://mdfs.net/Docs/Comp/Archiving/Zip/ExtraField
# editor files also contain NTFS timestamps
info.extra = encode_extra_pkware_win32(now)

# trick header encoder
info.external_attr = _TrueInt(0)
Expand All @@ -857,7 +873,7 @@ def make_fileinfo(filename: str) -> zipfile.ZipInfo:
outzip.writestr(make_fileinfo(BEATMAP_JSON_FILE), codecs.BOM_UTF8 + beatmap_json.encode("utf-8").replace(b"\n", b"\r\n"))
outzip.writestr(make_fileinfo(safe_audio_name), self.audio.raw_data)
outzip.writestr(make_fileinfo(self.meta.cover_name), self.meta.cover_data)
outzip.writestr(make_fileinfo(METADATA_JSON_FILE), codecs.BOM_UTF8 + meta_json.encode("utf-8").replace(b"\n", b"\r\n"))
outzip.writestr(make_fileinfo(METADATA_JSON_FILE), codecs.BOM_UTF16_LE + meta_json.encode("utf-16-le"))
# write output zip
if isinstance(output_file, BytesIO):
output_file.seek(0)
Expand Down

0 comments on commit 280b30b

Please sign in to comment.