-
Notifications
You must be signed in to change notification settings - Fork 153
/
validate-spice
executable file
·142 lines (119 loc) · 5.51 KB
/
validate-spice
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/python3
import json
import os
import sys
import subprocess
from PIL import Image
if len(sys.argv) != 2:
print("Usage:")
print("./validate-spice uuid")
print("./validate-spice --all")
sys.exit(1)
SPICE_TYPE="desklet"
class CheckError(Exception):
pass
# function with checks for an xlet
def validate_xlet(uuid):
valid = False
os.chdir(uuid)
try:
# Check mandatory files
for file in ["info.json", "screenshot.png", "files/%s/metadata.json" % uuid, "files/%s/icon.png" % uuid]:
if not os.path.exists(file):
raise CheckError("[%s] Missing file: %s" % (uuid, file))
found = False
for root, dirs, files in os.walk("files/%s" % uuid):
if any(ext.endswith(".po") for ext in files) and not any(ext.endswith(".pot") for ext in files):
raise CheckError("[%s] Invalid location for translation files!" % (uuid))
for file in files:
if file == "%s.js" % SPICE_TYPE:
found = True
if not found:
raise CheckError("[%s] Missing main %s.js" % (uuid, SPICE_TYPE))
# Check forbidden files
for file in ["icon.png"]:
if os.path.exists(file):
raise CheckError("[%s] Forbidden file: %s" % (uuid, file))
# Check mandatory directories
for directory in ["files", "files/%s" % uuid]:
if not os.path.isdir(directory):
raise CheckError("[%s] Missing directory: %s" % (uuid, directory))
# Check that there are no files in files other than the uuid directory
if len(os.listdir("files")) != 1:
raise CheckError("[%s] The files directory should ONLY contain the $uuid directory!" % (uuid))
# check info.json
with open("info.json") as file:
try:
info = json.load(file)
except Exception as e:
raise CheckError("Could not parse info.json: %s" % e)
# check mandatory fields
for field in ['author']:
if field not in info:
raise CheckError("[%s] Missing field '%s' in info.json" % (uuid, field))
# check metadata.json
with open("files/%s/metadata.json" % uuid) as file:
try:
metadata = json.load(file)
except Exception as e:
raise CheckError("Could not parse metadata.json: %s" % e)
# check forbidden fields
for field in ['icon', 'dangerous', 'last-edited']:
if field in metadata:
raise CheckError("[%s] Forbidden field '%s' in %s" % (uuid, field, "files/%s/metadata.json" % uuid))
# check mandatory fields
for field in ['uuid', 'name', 'description']:
if field not in metadata:
raise CheckError("[%s] Missing field '%s' in %s" % (uuid, field, "files/%s/metadata.json" % uuid))
# check uuid value
if metadata['uuid'] != uuid:
raise CheckError("[%s] Wrong uuid in %s" % (uuid, "files/%s/metadata.json" % uuid))
# check for unicode characters in metadata
for field in metadata:
strvalue = str(metadata[field])
if len(strvalue.encode()) != len(strvalue):
raise CheckError("[%s] Forbidden unicode characters in field '%s' in %s" % (uuid, field, "files/%s/metadata.json" % uuid))
# check if icon is square
im = Image.open("files/%s/icon.png" % uuid)
(width, height) = im.size
if width != height:
raise CheckError("[%s] icon.png has to be square." % uuid)
# check po and pot files
podir = "files/%s/po" % uuid
if os.path.isdir(podir):
for file in os.listdir(podir):
if file.endswith(".po"):
pocheck = subprocess.run(["msgfmt", "-c", os.path.join(podir, file), "-o", "-"], stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, text=True)
if pocheck.stderr:
raise CheckError("[%s] The following errors were found in translation file '%s':\n%s"
"HINT: Most errors in translation file `%s` can usually be prevented and solved by using Poedit.\n"
% (uuid, file, pocheck.stderr, file)
)
elif file.endswith(".pot"):
potcheck = subprocess.run(["xgettext", os.path.join(podir, file), "-o", "-"], stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, text=True)
if potcheck.stderr:
raise CheckError("[%s] The following errors were found in translation template '%s':\n%s" % (uuid, file, potcheck.stderr))
# Finally...
valid = True
except CheckError as error:
print("[%s] Error during validation: %s" % (uuid, error))
except Exception as error:
print("[%s] Unknown error. %s" % (uuid, error))
os.chdir("..")
return valid
def quit(valid):
if (valid):
print ("No errors found. Everything looks good.")
sys.exit(0)
else:
print ("\nErrors were found! Once you fix the issue, please re-run "
"'validate-spice <uuid>'' to check for further errors.")
sys.exit(1)
if sys.argv[1] == "--all":
valid = True
for uuid in os.listdir("."):
if os.path.isdir(uuid) and not uuid.startswith("."):
valid = validate_xlet(uuid) and valid
else:
valid = validate_xlet(sys.argv[1])
quit(valid)