Skip to content

INTEGRITY: Continue with user.dat #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 47 commits into
base: integrity
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
0216907
INTEGRITY: Only skip processing for entries with the same status when…
ShivangNagta Jul 21, 2025
90be689
INTEGRITY: Logging dropped candidates missed earlier.
ShivangNagta Jul 21, 2025
d6f17b5
INTEGRITY: Add fileset creation details in log when new fileset is no…
ShivangNagta Jul 21, 2025
404898e
INTEGRITY: Fix placeholder for widetable query.
ShivangNagta Jul 22, 2025
97961a7
INTEGRITY: Redirect fileset url if id exceeds the bounds.
ShivangNagta Jul 23, 2025
ab293d9
INTEGRITY: Fix the issue for filesets with null field not being filte…
ShivangNagta Jul 23, 2025
6d8c4bf
INTEGRITY: Join game table before engine table.
ShivangNagta Jul 23, 2025
78cbabc
INTEGRITY: Add max and min pages in dashboard.
ShivangNagta Jul 23, 2025
28d83ba
INTEGRITY: Improve merge workflow.
ShivangNagta Jul 25, 2025
1e79185
INTEGRITY: Add detection type for full checksums in detection entries
ShivangNagta Jul 25, 2025
2bc1e6f
INTEGRITY: Update timestamp for detection files in partial fileset co…
ShivangNagta Jul 25, 2025
749b5a9
INTEGRITY: Add extra error handling for parsing.
ShivangNagta Jul 26, 2025
546dfe3
INTEGRITY: Add commit/rollback transaction support to match_fileset a…
ShivangNagta Jul 26, 2025
686d06e
INTEGRITY: Remove early string escaping for database logs as queries …
ShivangNagta Jul 26, 2025
5e4627b
INTEGRITY: Remove depracated/redundant code.
ShivangNagta Jul 26, 2025
4222dde
INTEGRITY: Improve homepage navbar.
ShivangNagta Jul 26, 2025
f810f51
INTEGRITY: Fix incorrect fileset redirection issue in logs.
ShivangNagta Jul 27, 2025
9fca525
INTEGRITY: Add fileset redirection message for merged filesets in the…
ShivangNagta Jul 27, 2025
9779d97
INTEGRITY: Display only matched files in confirm merge by default, in…
ShivangNagta Jul 29, 2025
8602689
INTEGRITY: Add check for matching files by missing size and hide merg…
ShivangNagta Jul 29, 2025
bf65cb0
INTEGRITY: Add configuration page with a feature to select items per …
ShivangNagta Jul 29, 2025
1d254e1
INTEGRITY: Add user details in manual merge log.
ShivangNagta Jul 29, 2025
b7a6e24
INTEGRITY: Add config page url in the homepage.
ShivangNagta Jul 29, 2025
9b62c15
INTEGRITY: Add user.dat processing logic.
ShivangNagta Jul 30, 2025
9213075
INTEGRITY: Add comprehensive search criterias in log with OR, AND con…
ShivangNagta Jul 30, 2025
45cbd16
INTEGRITY: Add separate logs per page and filesets per page in config.
ShivangNagta Jul 31, 2025
6b44b81
INTEGRITY: Add/update deployment related files.
ShivangNagta Jul 31, 2025
7aabe39
INTEGRITY: Add underline on hover for navbar links.
ShivangNagta Jul 31, 2025
9ac4cf7
INTEGRITY: Add favicon.
ShivangNagta Jul 31, 2025
0860198
INTEGRITY: Add column width variable in config.
ShivangNagta Jul 31, 2025
72c8da7
INTEGRITY: Add metadata information in seeding logs.
ShivangNagta Aug 1, 2025
5873216
INTEGRITY: Move html text file to static folder.
ShivangNagta Aug 1, 2025
f507ad5
INTEGRITY: Add visual symbols for sorting.
ShivangNagta Aug 1, 2025
212cd13
INTEGRITY: Add checksum filtering in fileset search page.
ShivangNagta Aug 2, 2025
a1c97c3
INTEGRITY: Encode url variables before changing page.
ShivangNagta Aug 2, 2025
d8665df
INTEGRITY: Fix the fileset details being displayed in merge dashboard.
ShivangNagta Aug 3, 2025
3a95049
INTEGRITY: Add default state for sorting along with ascending and des…
ShivangNagta Aug 3, 2025
fab9876
INTEGRITY: Refactor confirm merge code.
ShivangNagta Aug 3, 2025
3bddf9e
INTEGRITY: Remove icon for default sorting state.
ShivangNagta Aug 6, 2025
1efdc2a
INTEGRITY: Decode macbinary's filename as mac roman instead of utf-8.
ShivangNagta Aug 6, 2025
1abc41e
INTEGRITY: Wrap filename in scanned dat in double quotes instead of s…
ShivangNagta Aug 6, 2025
5c6bbf1
INTEGRITY: Update size filtering logic for scan.dat for macfiles.
ShivangNagta Aug 6, 2025
76134b1
INTEGRITY: Check for rt and dt checktype suffix while adding equal ch…
ShivangNagta Aug 7, 2025
a843c21
INTEGRITY: Add validation checks on user data from the payload along …
ShivangNagta Aug 8, 2025
6b81c44
INTEGRITY: Add python virtual environment path in apache config file.
ShivangNagta Aug 8, 2025
f1e0964
INTEGRITY: Remove apache basic auth from validate endpoint.
ShivangNagta Aug 8, 2025
2d5286e
INTEGRITY: Delete unused files.
ShivangNagta Aug 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions .htaccess

This file was deleted.

22 changes: 17 additions & 5 deletions apache2-config/gamesdb.sev.zone.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,24 @@
ServerAdmin webmaster@localhost
CustomLog ${APACHE_LOG_DIR}/integrity-access.log combined
ErrorLog ${APACHE_LOG_DIR}/integrity-error.log
DocumentRoot /home/ubuntu/projects/python/scummvm-sites
WSGIDaemonProcess scummvm-sites user=www-data group=www-data threads=5
WSGIScriptAlias / /home/ubuntu/projects/python/scummvm-sites/app.wsgi
DocumentRoot /home/ubuntu/projects/python/scummvm_sites_2025/scummvm-sites
WSGIDaemonProcess scummvm-sites \
user=www-data group=www-data threads=5 \
python-home=/home/ubuntu/projects/python/scummvm_sites_2025/scummvm-sites/venv
WSGIProcessGroup scummvm-sites
WSGIScriptAlias / /home/ubuntu/projects/python/scummvm_sites_2025/scummvm-sites/app.wsgi

<Directory /home/ubuntu/projects/python/scummvm-sites>
Require all granted
<Directory /home/ubuntu/projects/python/scummvm_sites_2025/scummvm-sites>
AuthType Basic
AuthName "nope"
AuthUserFile /home/ubuntu/projects/python/scummvm_sites_2025/.htpasswd
Require valid-user
</Directory>

<Location "/validate">
AuthType None
Require all granted
Satisfy Any
</Location>

</VirtualHost>
12 changes: 12 additions & 0 deletions app.wsgi
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import sys
import logging

sys.path.insert(0, "/home/ubuntu/projects/python/scummvm_sites_2025/scummvm-sites")

from fileset import app as application

logging.basicConfig(stream=sys.stderr)
sys.stderr = sys.stdout

if __name__ == "__main__":
application.run()
62 changes: 0 additions & 62 deletions clear.py

This file was deleted.

8 changes: 5 additions & 3 deletions compute_hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,8 @@ def extract_macbin_filename_from_header(file):
header = f.read(128)
name_len = header[1]
filename_bytes = header[2 : 2 + name_len]
return filename_bytes.decode("utf-8")
filename = filename_bytes.decode("mac_roman")
return filename


def file_classification(filepath):
Expand All @@ -562,7 +563,8 @@ def file_classification(filepath):

# 1. Macbinary
if is_macbin(filepath):
return [FileType.MAC_BINARY, extract_macbin_filename_from_header(filepath)]
base_name = extract_macbin_filename_from_header(filepath)
return [FileType.MAC_BINARY, base_name]

# 2. Appledouble .rsrc
if is_appledouble_rsrc(filepath):
Expand Down Expand Up @@ -816,7 +818,7 @@ def create_dat_file(hash_of_dirs, path, checksum_size=0):
timestamp,
) in hash_of_dir.items():
filename = encode_path_components(filename)
data = f"name '{filename}' size {size} size-r {size_r} size-rd {size_rd} modification-time {timestamp}"
data = f"""name "{filename}" size {size} size-r {size_r} size-rd {size_rd} modification-time {timestamp}"""
for key, value in hashes:
data += f" {key} {value}"

Expand Down
157 changes: 109 additions & 48 deletions dat_parser.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import re
import os
import sys
from db_functions import db_insert, match_fileset
import argparse

Expand Down Expand Up @@ -79,21 +80,40 @@ def match_outermost_brackets(input):
depth = 0
inside_quotes = False
cur_index = 0
line_number = 1
index_line = 1

for i in range(len(input)):
char = input[i]
for i, char in enumerate(input):
if char == "\n":
line_number += 1
inside_quotes = False

if char == "(" and not inside_quotes:
if char == '"' and input[i - 1] != "\\":
inside_quotes = not inside_quotes

elif char == "(" and not inside_quotes:
if depth == 0:
if "rom" in input[i - 4 : i]:
raise ValueError(
f"Missing an opening '(' for the game. Look near line {line_number}."
)
index_line = line_number
cur_index = i
depth += 1

elif char == ")" and not inside_quotes:
if depth == 0:
print(f"Warning: unmatched ')' at line {line_number}")
continue
depth -= 1
if depth == 0:
match = input[cur_index : i + 1]
matches.append((match, cur_index))
elif char == '"' and input[i - 1] != "\\":
inside_quotes = not inside_quotes

if depth != 0:
raise ValueError(
f"Unmatched '(' starting at line {index_line}: possibly an unclosed block."
)

return matches

Expand All @@ -104,61 +124,102 @@ def parse_dat(dat_filepath):
associated arrays
"""
if not os.path.isfile(dat_filepath):
print("File not readable")
return
print(f"Error: File does not exist or is unreadable: {dat_filepath}.")
return None

with open(dat_filepath, "r", encoding="utf-8") as dat_file:
content = dat_file.read()
try:
with open(dat_filepath, "r", encoding="utf-8") as dat_file:
content = dat_file.read()
except (IOError, UnicodeDecodeError) as e:
print(f"Error: Failed to read file {dat_filepath}: {e}")
return None

header = {}
game_data = []
resources = {}

matches = match_outermost_brackets(content)
# print(matches)
try:
matches = match_outermost_brackets(content)
except Exception as e:
print(f"Error: Failed to parse outer brackets in {dat_filepath}: {e}")
return None
if matches:
for data_segment in matches:
if (
"clrmamepro" in content[data_segment[1] - 11 : data_segment[1]]
or "scummvm" in content[data_segment[1] - 8 : data_segment[1]]
):
header = map_key_values(data_segment[0], header)
elif "game" in content[data_segment[1] - 5 : data_segment[1]]:
temp = {}
temp = map_key_values(data_segment[0], temp)
game_data.append(temp)
elif "resource" in content[data_segment[1] - 9 : data_segment[1]]:
temp = {}
temp = map_key_values(data_segment[0], temp)
resources[temp["name"]] = temp
# print(header, game_data, resources, dat_filepath)
try:
if (
"clrmamepro" in content[data_segment[1] - 11 : data_segment[1]]
or "scummvm" in content[data_segment[1] - 8 : data_segment[1]]
):
header = map_key_values(data_segment[0], header)
elif "game" in content[data_segment[1] - 5 : data_segment[1]]:
temp = {}
temp = map_key_values(data_segment[0], temp)
game_data.append(temp)
elif "resource" in content[data_segment[1] - 9 : data_segment[1]]:
temp = {}
temp = map_key_values(data_segment[0], temp)
resources[temp["name"]] = temp
except Exception as e:
print(f"Error: Failed to parse a data_segment: {e}")
return None

return header, game_data, resources, dat_filepath


def main():
parser = argparse.ArgumentParser(
description="Process DAT files and interact with the database."
)
parser.add_argument(
"--upload", nargs="+", help="Upload DAT file(s) to the database"
)
parser.add_argument(
"--match", nargs="+", help="Populate matching games in the database"
)
parser.add_argument("--user", help="Username for database")
parser.add_argument("-r", help="Recurse through directories", action="store_true")
parser.add_argument("--skiplog", help="Skip logging dups", action="store_true")

args = parser.parse_args()

if args.upload:
for filepath in args.upload:
db_insert(parse_dat(filepath), args.user, args.skiplog)

if args.match:
for filepath in args.match:
# print(parse_dat(filepath)[2])
match_fileset(parse_dat(filepath), args.user, args.skiplog)
try:
parser = argparse.ArgumentParser(
description="Process DAT files and interact with the database."
)
parser.add_argument(
"--upload", nargs="+", help="Upload DAT file(s) to the database"
)
parser.add_argument(
"--match", nargs="+", help="Populate matching games in the database"
)
parser.add_argument("--user", help="Username for database")
parser.add_argument(
"-r", help="Recurse through directories", action="store_true"
)
parser.add_argument("--skiplog", help="Skip logging dups", action="store_true")

args = parser.parse_args()

if not args.upload and not args.match:
print("Error: No action specified. Use --upload or --match")
parser.print_help()
sys.exit(1)

if args.upload:
for filepath in args.upload:
try:
parsed_data = parse_dat(filepath)
if parsed_data is not None:
db_insert(parsed_data, args.user, args.skiplog)
else:
print(f"Error: Failed to parse file for upload: {filepath}")
except Exception as e:
print(f"Error uploading {filepath}: {e}")
continue

if args.match:
for filepath in args.match:
try:
parsed_data = parse_dat(filepath)
if parsed_data[0] is not None:
match_fileset(parsed_data, args.user, args.skiplog)
else:
print(f"Error: Failed to parse file for matching: {filepath}")
except Exception as e:
print(f"Error matching {filepath}: {e}")
continue

except KeyboardInterrupt:
print("Operation cancelled by user")
sys.exit(0)
except Exception as e:
print(f"Error: Unexpected error in main: {e}")
sys.exit(1)


if __name__ == "__main__":
Expand Down
Loading