Commit 49e0a27c authored by Christian Rohlfing's avatar Christian Rohlfing
Browse files

streamlined positional arguments everywhere and adapted tests correspondingly

parent ccd3ac3d
...@@ -13,49 +13,38 @@ import preparemoodle ...@@ -13,49 +13,38 @@ import preparemoodle
def main(args): def main(args):
# Argument handling # Argument handling
parser = argparse.ArgumentParser(description=''' parser = argparse.ArgumentParser(description='''
Watermark and encrypts exams and prepares everything for moodle upload. Watermark and encrypts exams and prepares everything for moodle upload.
Attention: contents of folder 'out' will be deleted in the beginning! Attention: contents of folder 'out' will be deleted in the beginning!
Options:
-h, --help show this help text
-i, --in input folder with PDFs. Default: ./pdfs
-c, --csv Moodle grading CSV file, needed to construct folder names
for moodle
-o, --out output folder containing passwords.csv and
moodle_feedbacks.zip. Default: ./out
-p, --password sets global password. Default: empty, such that each PDF
gets custom password
-e, --cores number of cores for watermarking. Default: 1
-d, --dpi dpi parameter for pdf to image conversion. Default: 250
-q, --quality quality parameter for jpeg. Default: 25
-t, --tmp tmp folder. Default: ./tmp
''') ''')
parser.add_argument("-i", "--infolder", default="./pdfs", parser.add_argument(
help="Input folder with PDFs. Default: ./pdfs") "infolder", help="Input folder with PDFs.")
parser.add_argument("-c", "--csv", default="Bewertungen.csv", parser.add_argument(
help="Moodle grading CSV file, needed to construct " + "csv",
"folder names for moodle zip") help="Moodle grading CSV file, needed to construct " +
parser.add_argument("-o", "--outfolder", default="./out", "folder names for moodle zip")
help="output folder containing passwords.csv and " + parser.add_argument(
"moodle_feedbacks.zip. Default: ./out") "outfolder",
parser.add_argument("-e", "--cores", default="2", help="output folder with passwords.csv and moodle_feedbacks.zip.")
help="Number of cores for parallel processing. " + parser.add_argument(
"Default: 2") "-e", "--cores", default="2",
parser.add_argument("-p", "--password", default="", help="Number of cores for parallel processing. Default: 2")
help="sets global password. Default: empty, " + parser.add_argument(
"such that each PDF gets custom password") "-p", "--password", default="",
parser.add_argument("-d", "--dpi", default="250", help="sets global password. Default: empty, such that each PDF gets " +
help="DPI parameter for pdf to image conversion. " + "custom password")
"Default: 250") parser.add_argument(
parser.add_argument("-t", "--tmp", default="./tmp", "-d", "--dpi", default="150",
help="tmp folder. Default: ./tmp/") help="DPI parameter for pdf to image conversion. Default: 150")
parser.add_argument("-u", "--supinfolder", default="./supplements", parser.add_argument(
help="Input folder with sample solutions. Default: ./supplements") "-t", "--tmp", default="./tmp", help="Tmp folder. Default: ./tmp/")
parser.add_argument("-w", "--sup", default="0", parser.add_argument(
help="Flag for watermarking sample solutions. 0 means no 1 means yes. Default: 0") "--suppinfolder", default="./supplements",
parser.add_argument("-x", "--zip", default="0", help="Input folder with sample solutions. Default: ./supplements")
help="Input zip file. Default: 0") parser.add_argument(
"--supp", action='store_true',
help="Flag for watermarking supplements.")
parser.add_argument(
"--zip", default="0", help="Input zip file. Default: 0")
args = parser.parse_args(args) args = parser.parse_args(args)
infolder = args.infolder infolder = args.infolder
...@@ -65,29 +54,29 @@ Options: ...@@ -65,29 +54,29 @@ Options:
dpi = args.dpi dpi = args.dpi
tmp = args.tmp tmp = args.tmp
password = args.password password = args.password
sup = int(args.sup) watermark_supp = args.supp
supinfolder = args.supinfolder supinfolder = args.suppinfolder
inzip = args.zip inzip = args.zip
starttime = time.time() starttime = time.time()
# Unzip submissions if provided zip archive # Unzip submissions if provided zip archive
if inzip != "0" : if inzip != "0":
if not os.path.exists(infolder): if not os.path.exists(infolder):
os.makedirs(infolder) os.makedirs(infolder)
preparepdf.main(['--in', inzip, '--out', infolder, '--csv', csv]) preparepdf.main([inzip, csv, infolder])
# Watermarking # Watermarking
watermark_outfolder = os.path.join(tmp, 'pdfs_watermarked') watermark_outfolder = os.path.join(tmp, 'pdfs_watermarked')
if not os.path.exists(watermark_outfolder): if not os.path.exists(watermark_outfolder):
os.makedirs(watermark_outfolder) os.makedirs(watermark_outfolder)
watermark.main([infolder, watermark_outfolder, watermark.main([infolder, watermark_outfolder,
'--cores', cores, '--dpi', dpi]) '--cores', cores, '--dpi', dpi])
if sup == 1: if watermark_supp:
supoutfolder = os.path.join(tmp, 'supplements_out') supoutfolder = os.path.join(tmp, 'supplements_out')
if not os.path.exists(supoutfolder): if not os.path.exists(supoutfolder):
os.makedirs(supoutfolder) os.makedirs(supoutfolder)
supplements.main(['--in', supinfolder, '--out', supoutfolder]) supplements.main([supinfolder, csv, supoutfolder])
watermark.main([supoutfolder, watermark_outfolder, watermark.main([supoutfolder, watermark_outfolder,
'--cores', cores, '--dpi', dpi]) '--cores', cores, '--dpi', dpi])
......
...@@ -38,7 +38,7 @@ def main(args): ...@@ -38,7 +38,7 @@ def main(args):
"""Main function """Main function
1) Lists all PDFs to be encrypted from input folder 1) Lists all PDFs to be encrypted from input folder
2) Encrypt pdf witn randomly generated 8 character long password 2) Encrypt pdf with randomly generated 8 character long password
3) Prepare a csv file that contains matriculation number and password 3) Prepare a csv file that contains matriculation number and password
""" """
...@@ -47,27 +47,26 @@ def main(args): ...@@ -47,27 +47,26 @@ def main(args):
PDFs in input folder are encrypted and stored in output folder. PDFs in input folder are encrypted and stored in output folder.
Alongside with a CSV file mapping passwords to each PDF. Alongside with a CSV file mapping passwords to each PDF.
''') ''')
parser.add_argument("infolder", help="Input PDF folder.") parser.add_argument(
"infolder", help="Input folder storing PDFs to be encrypted.")
parser.add_argument("outfolder", help="Output folder storing encrypted PDFs. ") parser.add_argument(
"outfolder", help="Output folder storing encrypted PDFs.")
parser.add_argument("-p", "--password", default="", parser.add_argument(
help="Common password for all encrypted PDFs. " + "-p", "--password", default="",
"Default: '' " + help="Common password for all encrypted PDFs. " +
"results in generation of random passwords.") "Default: '' results in generation of random passwords.")
parser.add_argument(
parser.add_argument("-w", "--passwordout", default="", "-w", "--passwordout", default="",
help="Output path for CSV file. " + help="Output path for CSV file. " +
"Default: '' will be changed to " + "Default: '' will be changed to [outfolder]/passwords.csv.")
"[outfolder]/passwords.csv.")
args = parser.parse_args(args) args = parser.parse_args(args)
infolder = args.infolder infolder = args.infolder
outfolder = args.outfolder outfolder = args.outfolder
if not os.path.exists(outfolder): if not os.path.exists(outfolder):
os.makedirs(outfolder) os.makedirs(outfolder)
if args.passwordout == "": if args.passwordout == "":
password_file = os.path.join(outfolder, 'passwords.csv') password_file = os.path.join(outfolder, 'passwords.csv')
else: else:
...@@ -78,7 +77,7 @@ def main(args): ...@@ -78,7 +77,7 @@ def main(args):
pdf_folder = os.listdir(infolder) pdf_folder = os.listdir(infolder)
pdf_files = [_ for _ in pdf_folder pdf_files = [_ for _ in pdf_folder
if _.lower().endswith(".pdf")] if _.lower().endswith(".pdf")]
if len(pdf_files)>0: if len(pdf_files) > 0:
print(""" print("""
Available PDFs to be encrypted: Available PDFs to be encrypted:
- {} - {}
...@@ -86,7 +85,7 @@ Available PDFs to be encrypted: ...@@ -86,7 +85,7 @@ Available PDFs to be encrypted:
Files in output folder {} will be overwritten during this process. Files in output folder {} will be overwritten during this process.
""".format("\n- ".join(pdf_files), outfolder)) """.format("\n- ".join(pdf_files), outfolder))
else: else:
print (""" print("""
There are no PDFs in the given directory. There are no PDFs in the given directory.
Exiting now.""") Exiting now.""")
return return
...@@ -105,7 +104,7 @@ Exiting now.""") ...@@ -105,7 +104,7 @@ Exiting now.""")
password = pwgen.pwgen(8) password = pwgen.pwgen(8)
else: else:
password = args.password password = args.password
# Encrypt # Encrypt
in_file = os.path.join(infolder, pdf_file) in_file = os.path.join(infolder, pdf_file)
enc_file = os.path.splitext(pdf_file)[0] + '_aes.pdf' enc_file = os.path.splitext(pdf_file)[0] + '_aes.pdf'
......
...@@ -147,8 +147,9 @@ def main(args): ...@@ -147,8 +147,9 @@ def main(args):
parser.add_argument( parser.add_argument(
"infolder", help="Input folder with PDFs.") "infolder", help="Input folder with PDFs.")
parser.add_argument( parser.add_argument(
"csv", "csv", help="Moodle grading sheet.")
help="Moodle grading sheet. Default: ./Bewertungen.csv") parser.add_argument(
"outzip", help="Zip archive with feedback files.")
parser.add_argument( parser.add_argument(
"--csvdelim", default=",", help="CSV delimiter. Default: ','") "--csvdelim", default=",", help="CSV delimiter. Default: ','")
parser.add_argument( parser.add_argument(
...@@ -157,8 +158,6 @@ def main(args): ...@@ -157,8 +158,6 @@ def main(args):
"--csvenc", default="utf-8", help="CSV encoding scheme. " + "--csvenc", default="utf-8", help="CSV encoding scheme. " +
"Typical encodings:'utf-8', 'utf-8-sig', or 'cp1252' (Windows). " + "Typical encodings:'utf-8', 'utf-8-sig', or 'cp1252' (Windows). " +
"Default: 'utf-8'") "Default: 'utf-8'")
parser.add_argument(
"outzip", help="Zip archive.")
parser.add_argument( parser.add_argument(
"-d", "--dry", action='store_true', help="Flag for dry run.") "-d", "--dry", action='store_true', help="Flag for dry run.")
parser.add_argument( parser.add_argument(
...@@ -307,4 +306,4 @@ Time taken: {:.2f}""".format(endtime-starttime)) ...@@ -307,4 +306,4 @@ Time taken: {:.2f}""".format(endtime-starttime))
# Main routine # Main routine
if __name__ == '__main__': if __name__ == '__main__':
main(sys.argv[1:]) main(sys.argv[1:])
\ No newline at end of file
...@@ -28,12 +28,11 @@ def main(args): ...@@ -28,12 +28,11 @@ def main(args):
and placed in folder 'outfolder'. and placed in folder 'outfolder'.
''') ''')
parser.add_argument( parser.add_argument(
"-i", "--inzip", default="submissions.zip", "inzip", help="Input zip file or already extracted folder.")
help="Input zip file or already extracted folder. " +
"Default: ./submissions.zip")
parser.add_argument( parser.add_argument(
"-o", "--outfolder", default="./pdfs", "csv", help="Moodle grading sheet.")
help="Output folder with PDFs. Default: ./pdfs") parser.add_argument(
"outfolder", help="Output folder with PDFs.")
parser.add_argument( parser.add_argument(
"--filenameformat", default="{matnum}_{fullname[0]}", "--filenameformat", default="{matnum}_{fullname[0]}",
help="File name format. Available keywords: " + help="File name format. Available keywords: " +
...@@ -45,9 +44,6 @@ def main(args): ...@@ -45,9 +44,6 @@ def main(args):
parser.add_argument( parser.add_argument(
"--appendoriginal", action='store_true', "--appendoriginal", action='store_true',
help="If set, appends original file name to new location's file name") help="If set, appends original file name to new location's file name")
parser.add_argument(
"-c", "--csv", default="./Bewertungen.csv",
help="Moodle grading sheet. Default: ./Bewertungen.csv")
parser.add_argument( parser.add_argument(
"--csvdelim", default=",", help="CSV delimiter. Default: ','") "--csvdelim", default=",", help="CSV delimiter. Default: ','")
parser.add_argument( parser.add_argument(
......
...@@ -26,19 +26,16 @@ def main(args): ...@@ -26,19 +26,16 @@ def main(args):
''') ''')
parser.add_argument( parser.add_argument(
"-i", "--infolder", default="./pdfs_scan", "infolder", help="Input folder with PDFs.")
help="Input folder with PDFs. Default: ./pdfs_scan")
parser.add_argument( parser.add_argument(
"-o", "--outfolder", default="./pdfs", "csv", help="Moodle grading sheet.")
help="Output folder with renamed scans. Default: ./pdfs") parser.add_argument(
"outfolder", help="Output folder with renamed scans.")
parser.add_argument( parser.add_argument(
"--filenameformat", default="{matnum}_{fullname[0]}", "--filenameformat", default="{matnum}_{fullname[0]}",
help="File name format. Available keywords: " + help="File name format. Available keywords: " +
"{matnum}, {fullname}, {lastname}, {firstname}. " + "{matnum}, {fullname}, {lastname}, {firstname}. " +
"Default: '{matnum}_{fullname[0]}'") "Default: '{matnum}_{fullname[0]}'")
parser.add_argument(
"-c", "--csv", default="./Bewertungen.csv",
help="Moodle grading sheet file. Default: ./Bewertungen.csv")
parser.add_argument( parser.add_argument(
"--csvdelim", default=",", help="CSV delimiter. Default: ','") "--csvdelim", default=",", help="CSV delimiter. Default: ','")
parser.add_argument( parser.add_argument(
......
...@@ -83,15 +83,15 @@ def main(args): ...@@ -83,15 +83,15 @@ def main(args):
from the Moodle grading CSV file. from the Moodle grading CSV file.
''') ''')
parser.add_argument( parser.add_argument(
"-i", "--infolder", default="./supplements", "infolder",
help="Folder with supplements. Default: ./supplements") help="Folder with supplements.")
parser.add_argument( parser.add_argument(
"-p", "--prefix", default="./pdfs", "prefix",
help="Provides information to construct prefixes. Either PDF folder " + help="Provides information to construct prefixes. Either PDF folder " +
"with scanned PDFs or Moodle grading CSV file. Default: ./pdfs") "with scanned PDFs or Moodle grading CSV file.")
parser.add_argument( parser.add_argument(
"-o", "--outfolder", default="./supplements_out", "outfolder",
help="Output folder. Default: ./supplements_out") help="Output folder with supplements per student.")
parser.add_argument( parser.add_argument(
"--filenameformat", default="{matnum}_{fullname[0]}", "--filenameformat", default="{matnum}_{fullname[0]}",
help="File name format. Available keywords: " + help="File name format. Available keywords: " +
......
...@@ -46,8 +46,9 @@ class MainTest(unittest.TestCase): ...@@ -46,8 +46,9 @@ class MainTest(unittest.TestCase):
os.mkdir(zipout_dir) os.mkdir(zipout_dir)
# Copy supplements file # Copy supplements file
batch.main(["-i", in_dir, "-o", out_dir, "-c", csv, "-t", tmp_dir, batch.main([
"--cores", "1", "--dpi", str(dpi)]) in_dir, csv, out_dir,
"-t", tmp_dir, "--cores", "1", "--dpi", str(dpi)])
# Assert output # Assert output
created_files = os.listdir(out_dir) created_files = os.listdir(out_dir)
......
...@@ -21,17 +21,20 @@ class MainTest(unittest.TestCase): ...@@ -21,17 +21,20 @@ class MainTest(unittest.TestCase):
def test_encrypt_scan_single(self): def test_encrypt_scan_single(self):
import encrypt import encrypt
expected_files = ["123001_LastnameA_aes.pdf", expected_files = [
'passwords.csv'] '123001_LastnameA_aes.pdf']
# Prepare parameter # Prepare parameter
in_dir = './tests/assets/pdfs' in_pdf = './tests/assets/pdfs/123001_LastnameA.pdf'
enc_pdf = '123001_LastnameA_aes.pdf'
out_dir = os.path.join(self.test_dir, 'out') out_dir = os.path.join(self.test_dir, 'out')
os.mkdir(out_dir) os.mkdir(out_dir)
# Encrypt files # Encrypt files
encrypt.main([in_dir,out_dir]) encrypt.encrypt(
pdf_file=in_pdf, enc_file=os.path.join(out_dir, enc_pdf),
password='tests_are_fun')
created_files = os.listdir(out_dir) created_files = os.listdir(out_dir)
created_files.sort() created_files.sort()
...@@ -53,7 +56,7 @@ class MainTest(unittest.TestCase): ...@@ -53,7 +56,7 @@ class MainTest(unittest.TestCase):
os.mkdir(out_dir) os.mkdir(out_dir)
# Encrypt files # Encrypt files
encrypt.main([in_dir,out_dir]) encrypt.main([in_dir, out_dir])
created_files = os.listdir(out_dir) created_files = os.listdir(out_dir)
created_files.sort() created_files.sort()
......
...@@ -19,9 +19,10 @@ class MainTest(unittest.TestCase): ...@@ -19,9 +19,10 @@ class MainTest(unittest.TestCase):
import preparepdf import preparepdf
expected_files = [ expected_files = [
'123456_F.pdf', '123001_L.pdf',
'123457_O.pdf', '123002_L.pdf',
'125412_T.pdf'] '123010_L.pdf',
'123011_L.pdf']
# Prepare parameter # Prepare parameter
in_zip = './tests/assets/submissions.zip' in_zip = './tests/assets/submissions.zip'
...@@ -35,8 +36,7 @@ class MainTest(unittest.TestCase): ...@@ -35,8 +36,7 @@ class MainTest(unittest.TestCase):
# Call function # Call function
preparepdf.main([ preparepdf.main([
"-i", in_zip, "-o", out_dir, "-c", sheet_csv, in_zip, sheet_csv, out_dir, "-t", tmp_dir])
"-t", tmp_dir])
# Assert output # Assert output
created_files = os.listdir(out_dir) created_files = os.listdir(out_dir)
......
...@@ -28,7 +28,7 @@ class MainTest(unittest.TestCase): ...@@ -28,7 +28,7 @@ class MainTest(unittest.TestCase):
# Call function # Call function
try: try:
renamescans.main([ renamescans.main([
"-i", in_dir, "-o", out_dir, "-c", sheet_csv, in_dir, sheet_csv, out_dir,
"--dry", "--checkqr"]) "--dry", "--checkqr"])
except Exception: except Exception:
pass pass
...@@ -51,7 +51,7 @@ class MainTest(unittest.TestCase): ...@@ -51,7 +51,7 @@ class MainTest(unittest.TestCase):
os.mkdir(out_dir) os.mkdir(out_dir)
# Call function # Call function
renamescans.main(["-i", in_dir, "-o", out_dir, "-c", sheet_csv]) renamescans.main([in_dir, sheet_csv, out_dir])
# Assert output # Assert output
created_files = os.listdir(out_dir) created_files = os.listdir(out_dir)
......
...@@ -39,7 +39,7 @@ class MainTest(unittest.TestCase): ...@@ -39,7 +39,7 @@ class MainTest(unittest.TestCase):
os.mkdir(tmp_dir) os.mkdir(tmp_dir)
# Copy supplements file # Copy supplements file
supplements.main(["-i", supp_dir, "-p", pdf_dir, "-o", supp_out_dir]) supplements.main([supp_dir, pdf_dir, supp_out_dir])
# Assert output # Assert output
created_files = os.listdir(supp_out_dir) created_files = os.listdir(supp_out_dir)
...@@ -72,7 +72,7 @@ class MainTest(unittest.TestCase): ...@@ -72,7 +72,7 @@ class MainTest(unittest.TestCase):
os.mkdir(tmp_dir) os.mkdir(tmp_dir)
# Copy supplements file # Copy supplements file
supplements.main(["-i", supp_dir, "-p", csv, "-o", supp_out_dir]) supplements.main([supp_dir, csv, supp_out_dir])
# Assert output # Assert output
created_files = os.listdir(supp_out_dir) created_files = os.listdir(supp_out_dir)
...@@ -108,8 +108,7 @@ class MainTest(unittest.TestCase): ...@@ -108,8 +108,7 @@ class MainTest(unittest.TestCase):
os.mkdir(out_dir) os.mkdir(out_dir)
# Copy supplements file # Copy supplements file
supplements.main( supplements.main([supp_dir, pdf_dir, supp_out_dir])
["-i", supp_dir, "-p", pdf_dir, "-o", supp_out_dir])
# Watermark files # Watermark files
watermark.main( watermark.main(
......
...@@ -92,7 +92,8 @@ def create_watermark_template(img_file, matnum, fontsize, dpi): ...@@ -92,7 +92,8 @@ def create_watermark_template(img_file, matnum, fontsize, dpi):
template = Image.new('RGBA', newsize, (255, 255, 255, 0)) template = Image.new('RGBA', newsize, (255, 255, 255, 0))
# Font # Font
fnt = ImageFont.truetype('./assets/fonts/arial.ttf', round(fontsize * dpi/250)) fnt = ImageFont.truetype(
'./assets/fonts/arial.ttf', round(fontsize*dpi/250))
# Drawing context # Drawing context
d = ImageDraw.Draw(template) d = ImageDraw.Draw(template)
...@@ -195,7 +196,7 @@ def combine_all_pdfs(pdf_pages, out_dir): ...@@ -195,7 +196,7 @@ def combine_all_pdfs(pdf_pages, out_dir):
def watermark_pdf(input_dir, tmp_dir, output_dir, def watermark_pdf(input_dir, tmp_dir, output_dir,
fontsize, dpi, quality, pdf_file): fontsize, dpi, quality, pdf_file):
"""Watermarkes each page of a given PDF file """Watermarks each page of a given PDF file
Args: Args:
input_dir (str): path to input directory input_dir (str): path to input directory
...@@ -212,7 +213,7 @@ def watermark_pdf(input_dir, tmp_dir, output_dir, ...@@ -212,7 +213,7 @@ def watermark_pdf(input_dir, tmp_dir, output_dir,
# img_files = convert_pdf_to_img(pdf_file, input_dir, tmp_dir, dpi) # img_files = convert_pdf_to_img(pdf_file, input_dir, tmp_dir, dpi)
img_files = convert_pdf_to_img(pdf_file, input_dir, tmp_dir, dpi) img_files = convert_pdf_to_img(pdf_file, input_dir, tmp_dir, dpi)
# Extracting matriculation numebers # Extracting matriculation numbers
matnum = matnum_utils.get_matnum(pdf_file) matnum = matnum_utils.get_matnum(pdf_file)
# Watermarking PDF page images # Watermarking PDF page images
...@@ -251,21 +252,24 @@ def main(args): ...@@ -251,21 +252,24 @@ def main(args):
matriculation number of the respective student. matriculation number of the respective student.
Watermarked PDFs are stored in folder 'out' Watermarked PDFs are stored in folder 'out'
''') ''')
parser.add_argument("infolder", help="Input folder with PDFs.") parser.add_argument(
parser.add_argument("outfolder", help="Output folder of the PDFs. ") "infolder", help="Input folder with PDFs.")
parser.add_argument("-f", "--fontsize", default="75", parser.add_argument(
help="Font size of watermark text in points. " + "outfolder", help="Output folder of the PDFs. ")
"Default: 75") parser.add_argument(
parser.add_argument("-c", "--cores", default="1", "-f", "--fontsize", default="75",
help="Number of cores for parallel processing. " + help="Font size of watermark text in points. Default: 75")
"Default: 1") parser.add_argument(
parser.add_argument("-t", "--tmp", default="./tmp", "-c", "--cores", default="1",
help="tmp folder. Default: ./tmp/") help="Number of cores for parallel processing. Default: 1")
parser.add_argument("-d", "--dpi", default="150", parser.add_argument(
help="DPI parameter for PDF to image conversion. " + "-t", "--tmp", default="./tmp", help="Tmp. folder. Default: ./tmp/")
"Default: 150") parser.add_argument(
parser.add_argument("-q", "--quality", default="75", "-d", "--dpi", default="150",