check_missing_media.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import os
  2. import re
  3. #made by Awesome :peeposhrug:
  4. script_directory = os.path.dirname(os.path.realpath(__file__))
  5. text_path = os.path.dirname(script_directory)
  6. qsrc_directory = os.path.join(text_path, 'locations')
  7. image_directory = input('Enter the game directory: ')
  8. keywords = input('Enter keywords to exclude (comma-separated, press Enter to skip): ')
  9. keywords_to_exclude = keywords.split(',')
  10. # Create a list to store missing images
  11. missing_images = []
  12. color_values = ['black', 'brown', 'red', 'blonde', 'light red', 'dark blue', 'blue', 'light blue', 'dark green', 'green', 'light green', 'dark pink', 'pink', 'light pink', 'dark purple', 'purple', 'light purple', 'light orange', 'dark red', 'medium red', 'turquoise', 'medium orange', 'dark orange']
  13. def exclude_keywords(image_path, keywords):
  14. for keyword in keywords:
  15. if keyword and keyword.lower() in image_path.lower():
  16. return True
  17. return False
  18. keywords_to_exclude.append('$pcs_haircol')
  19. keywords_to_exclude.append('set_<<')
  20. keywords_to_exclude.append('+iif')
  21. keywords_to_exclude.append('<<FUNC')
  22. # Function to construct the absolute path from a relative image reference
  23. def construct_absolute_path(image_reference, image_directory):
  24. return os.path.join(image_directory, image_reference.replace("images\\", ""))
  25. # Function to evaluate and replace random expressions within a string
  26. def evaluate_and_replace_random(expression):
  27. image_paths = []
  28. # Define a regular expression pattern to find '+rand(...)' or '<<rand(...)>>' expressions
  29. rand_pattern = r'(\+\s*rand\(([^)]*)\)\s*\+|\s*<<rand\(([^)]*)\)>>)'
  30. # Find all matching expressions in the input string
  31. matches = re.finditer(rand_pattern, expression)
  32. # Initialize the modified expression
  33. modified_expression = expression
  34. # Iterate through the matches and replace them
  35. for match in matches:
  36. rand_expression = match.group(2) or match.group(3)
  37. if rand_expression:
  38. # Check if there are numeric values within the parentheses
  39. numeric_values = re.findall(r'\d+', rand_expression)
  40. if numeric_values:
  41. min_value = int(numeric_values[0])
  42. max_value = int(numeric_values[1]) if len(numeric_values) > 1 else min_value
  43. if min_value <= max_value:
  44. # Generate image paths for each number in the range
  45. image_paths.extend([str(num) for num in range(min_value, max_value + 1)])
  46. # Replace the match in the expression with a placeholder
  47. modified_expression = modified_expression.replace(match.group(0), '<REPLACED>')
  48. # Remove single quotes and extra spaces
  49. modified_expression = modified_expression.replace("'", "").strip()
  50. modified_expression = modified_expression.replace(" ", "")
  51. # Add the generated image paths to the result
  52. image_paths = [modified_expression.replace('<REPLACED>', str(num)) for num in image_paths]
  53. return image_paths
  54. # Function to evaluate and replace variables within a string
  55. def evaluate_and_replace_variables(expression, variables):
  56. variable_matches = re.findall(r'<<(\$?[a-zA-Z_][a-zAZ0-9_]*)>>', expression)
  57. for variable_name in variable_matches:
  58. if variable_name.startswith("$"):
  59. variable_value = variables.get(variable_name[1:], "")
  60. else:
  61. variable_value = variables.get(variable_name, "")
  62. expression = expression.replace(f"<<{variable_name}>>", str(variable_value))
  63. return [expression]
  64. # Iterate through .qsrc files in the specified directory and its subdirectories
  65. for root, dirs, files in os.walk(qsrc_directory):
  66. for file in files:
  67. if file.endswith(".qsrc"):
  68. qsrc_file = os.path.join(root, file)
  69. # Read the .qsrc file
  70. with open(qsrc_file, "r", encoding="utf-8") as script_file:
  71. script_content = script_file.readlines()
  72. # Find and extract variable assignments within the same code block
  73. variable_matches = re.findall(r'<<(\$?[a-zA-Z_][a-zAZ0-9_]*)>>\s*=\s*([\'"]?[^\'"]+[\'"]?)', ''.join(script_content))
  74. # Store variable values for this code block
  75. code_block_variables = {}
  76. for variable_name, variable_value in variable_matches:
  77. code_block_variables[variable_name] = variable_value.strip("'\"")
  78. # Use regular expressions to find image references in the script
  79. for line_number, line in enumerate(script_content, start=1):
  80. if line.strip().startswith('!') or '+iif' in line or '<<FUNC' in line:
  81. continue
  82. image_references = re.findall(r'<(?:img <<\$set_imgh>>|video autoplay loop) src="([^"]+)"', line)
  83. for image_reference in image_references:
  84. if exclude_keywords(image_reference, keywords_to_exclude):
  85. continue
  86. # If the image reference contains '<<$pcs_haircol>>', replace it with each color value
  87. if '<<$pcs_haircol>>' in image_reference:
  88. for color in color_values:
  89. # Replace spaces with underscores in color names
  90. image_reference_color = image_reference.replace('<<$pcs_haircol>>', color)
  91. # Handle the '+rand(1,19)+' part
  92. if '+rand(1,19)+' in image_reference_color:
  93. for i in range(1, 20): # 20 is exclusive, so this will give numbers from 1 to 19
  94. image_reference_color_i = image_reference_color.replace('+rand(1,19)+', str(i))
  95. # Remove single quotes around the number
  96. image_reference_color_i = image_reference_color_i.replace("'"+str(i)+"'", str(i))
  97. absolute_path = construct_absolute_path(image_reference_color_i, image_directory)
  98. if not os.path.exists(absolute_path):
  99. missing_images.append((os.path.basename(qsrc_file), image_reference_color_i, line_number)) # Store the .qsrc filename, image path, and line number
  100. else:
  101. absolute_path = construct_absolute_path(image_reference_color, image_directory)
  102. if not os.path.exists(absolute_path):
  103. missing_images.append((os.path.basename(qsrc_file), image_reference_color, line_number)) # Store the .qsrc filename, image path, and line number
  104. else:
  105. # Evaluate variables first
  106. image_reference = evaluate_and_replace_variables(image_reference, code_block_variables)[0]
  107. image_paths = evaluate_and_replace_random(image_reference)
  108. for path in image_paths:
  109. if exclude_keywords(path, keywords_to_exclude):
  110. continue
  111. absolute_path = construct_absolute_path(path, image_directory)
  112. if not os.path.exists(absolute_path):
  113. missing_images.append((os.path.basename(qsrc_file), path, line_number)) # Store the .qsrc filename, image path, and line number
  114. missing_media_count = len(missing_images)
  115. # Specify the path to the "missing_media.txt" output file
  116. missing_media_file = os.path.join(text_path, "missing_media.txt")
  117. # Write the list of missing images with full image paths to the "missing_media.txt" file
  118. with open(missing_media_file, "w", encoding="utf-8") as file:
  119. for qsrc_file, image_path, line_number in missing_images:
  120. file.write(f"From file: {qsrc_file}, line: {line_number}\n") # Write the .qsrc filename and line number
  121. file.write(f"images/{image_path.replace('images/', '')}\n\n") # Write the relative image path and start a new line
  122. file.write(f"\nTotal missing media files: {missing_media_count}\n") # Write the count of missing media files at the end of the file
  123. file.write(f"this amazing script was made by Awesome(with help from chatGPT)\n") #bragging
  124. print(f"{missing_media_count} Missing images have been saved to 'missing_media.txt'.")
  125. pause = input("Press Enter to exit.")