Skip to content
Snippets Groups Projects
Select Git revision
  • master
  • rework_scenario_duplication
  • filter-actions
  • restore-pipeline
  • test-deploy
  • update_dependencies
  • update-mail
7 results

start.go

Blame
  • preparemoodle.py 5.38 KiB
    #!/usr/bin/env python
    
    import csv
    import os
    import shutil  # copyfile, make_archive
    import argparse, sys
    
    
    def find_file(pattern, path):
      if os.name == "posix":
        import subprocess
    
        result = [line[2:] for line in subprocess.check_output(
            "find " + path + " -type f -name " + pattern, 
            shell=True).splitlines()]
        result = [tmp.decode("utf-8") for tmp in result]
    
      else: 
        import fnmatch
    
        result = []
        for root, _, files in os.walk(path):
          for name in files:
            if fnmatch.fnmatch(name, pattern):
              result.append(os.path.join(root, name))
    
      return result
    
    if __name__ == '__main__':
    
      parser = argparse.ArgumentParser(description='''
      prepares batch upload to Moodle via assignment module. 
      PDFs in folder 'in' are moved to folder 'tmp' with a certain folder structure and finally zipped to 'out'. 
      Attention: zip-archive 'out' will be overwritten in the following!
    
      ''')
      parser.add_argument("-i", "--infolder", default="./pdfs/encrypted", 
        help="Input folder with PDFs. Default: ./pdfs/encrypted")
      parser.add_argument("-c", "--csv", default="./Bewertungen.csv",
        help="Moodle grading CSV file, needed to construct the folder names. Default: ./Bewertungen.csv")
      parser.add_argument("-o", "--outzip", default="./moodle_feedbacks.zip",
        help="Output zip archive. Default: ./moodle_feedbacks.zip")
      parser.add_argument("-d", "--dry", action='store_true', 
        help="Flag for dry run, displays only the folder structure inside the archive moodle_feedbacks.zip")
      parser.add_argument("-t", "--tmp", default="./tmp",
        help="temporary folder Default: ./tmp")
      parser.add_argument("--nowarn", action='store_true', 
        help="Disables warnings")
    
      args = parser.parse_args()
      infolder = args.infolder
      csvfilename = args.csv
      outzip = args.outzip
      tmpfolder = args.tmp
      dry = args.dry
      nowarn = args.nowarn
    
      numlines = 0
      with open(csvfilename, newline='') as csvfile:
        numlines = sum(1 for line in csvfile)
    
      print('''Preparing for moodle upload
      Processing {} lines
      '''.format(numlines))
    
      if dry:
        print("Dry run\n")
        dryoutput=""
      else:
        for root, dirs, files in os.walk(tmpfolder):
          for f in files:
              os.unlink(os.path.join(root, f))
          for d in dirs:
              shutil.rmtree(os.path.join(root, d))
    
        if os.path.exists(outzip): os.remove(outzip)
    
    
      with open(csvfilename, newline='') as csvfile:
        
        # Loop over all lines in CSV file
        numfoundpdfs = 0
        cnt = 0
        print("Start iterating...", sep='', end='', flush=True)
    
        reader = csv.reader(csvfile, delimiter=',', quotechar='"')
        next(reader)  # skip first row in CSV file since this should be the header
        for row in reader:
          # parse the required fields from the csv file
          id = row[0]
          id = id.replace("Teilnehmer/in", "")
          name = row[1]
          matnum = row[2]
    
          # if a pdf file for current student exists, create a directory and copy
          # the pdf file to it. The resulting directories can be uploaded to moodle
          longpdffile = ''
          paths = find_file(matnum + "*.pdf", infolder)
    
          if len(paths) > 0:
            longpdffile = paths[0]
          if len(paths) > 1:  # TODO: implement second loop for enabling distribution of multiple files
            raise Exception("More than one PDFs starting with matnum {} found!".format(matnum)) 
          
          
          if os.path.isfile(longpdffile):
            numfoundpdfs += 1
            pdffile = os.path.basename(longpdffile)
            folder = "{}_{}_assignsubmission_file_".format(name, id)
            longfolder = os.path.join(tmpfolder, folder)
    
            if not dry:
              os.mkdir(longfolder)
              shutil.copyfile(longpdffile, os.path.join(longfolder, pdffile))
            else:
              dryoutput += "\n{}".format(os.path.join(folder, pdffile))
          else:
              if not nowarn:
                print("Warning: PDF corresponding to matriculation number {} (id={}, name={}) not available.".format(
                  matnum, id, name
                ))
          
          # Progress
          if not (cnt % round(numlines/10)): 
            print(".", sep=' ', end='', flush=True)
          cnt += 1
          
      print("done.\n")
    
      print("Found {} PDFs (CSV had {} entries)\n".format(numfoundpdfs, numlines))
    
      print("Searching for matriculation numbers not present in CSV but in PDF input folder:")
    
      # Check for PDFs which are not reflected in CSV (student not registered in Moodle)
      numnotfoundmatnums = 0
      notfoundmatnums = ""
    
      for root, dirs, files in os.walk(infolder):
          for pdffile in files:
              if pdffile.endswith(".pdf"):
                # Get matriculation number from file
                matnum = pdffile[0:6]
                
                # Search in CSV
                with open(csvfilename, 'r') as csvfile:
                  notfound = True
                  for line in csvfile:
                      if matnum in line:
                        notfound = False
    
                if notfound:
                  numnotfoundmatnums += 1
                  notfoundmatnums += matnum + ", "
                  if not nowarn:
                    print("Warning: Could not find {} in CSV".format(matnum))
    
      if numnotfoundmatnums > 0:
        print('''I could not find the following {} matriculation numbers in CSV:
          {}'''.format(numnotfoundmatnums, notfoundmatnums))
    
      print("Done.")
    
      # Zipping
      if not dry:
        print("Zipping")
    
        shutil.make_archive(os.path.splitext(outzip)[0], 'zip', tmpfolder)
    
      else:
        print("\nResults from dry ryn:\n{}".format(dryoutput))
    
    
      print("\nDone.\n")