Commit d8fa8241 authored by Dennis Baurichter's avatar Dennis Baurichter

commit: Handle archiving exams

Provide or adjust options to archive exams. If selected, the folder
referenced by klausurarchiv.config.defaultArchiveId from last commit
(a233a8e8) will be used as the default
archive folder. The user may also (optionally) select different archive
folders. Exams selected for archiving will not be printed.

See #91
Apart from the documentation, that issue is fixed now.
parent a233a8e8
......@@ -281,7 +281,7 @@ def allExams():
try:
n=klausurarchiv.namingscheme.New(fn)
except:
except klausurarchiv.namingscheme.InvalidNameException:
if not fDirectory:
print("\x1b[33;1mWarning\x1b[30;0m: %s does not conform to naming "
"scheme. Skipping!"%(fn))
......@@ -380,35 +380,37 @@ def find_similar_items(item,ns):
for base, ns, items in sorted(all_exams,key=lambda i:i[1].lectures[0]+i[1].date):
#for base, ns, items in allExams():
output=""
output+=(
"--------------------------------------------------------------------\n"
"processing exam: \x1b[36;1m%s\x1b[30;0m\n"
%base)
assigned_folders=folders.assign(ns)
target_directory=os.path.join(exams_root,ns.date[:4],ns.date[5:7])
first_try=True
exam_processed=False
archive_exam=False
abort_all=False
def skip_or_manual_select(prompt):
global exam_processed, assigned_folders
global exam_processed, archive_exam, assigned_folders
sys.stdout.write(prompt)
while True:
opt=ask_option(
"Continue with next exam",
"Manually select folders")
"Manually select folders",
"Archive exam")
if opt==0:
exam_processed=True
break
elif opt==1:
new_folders=klausurarchiv.folder_selection.selectFolders(
"select folders for exam %s"%base,
assigned_folders)
"Select folders for exam %s"%base,
assigned_folders,archive=False)
if new_folders is None:
continue
assigned_folders=set(new_folders)
break
elif opt==2:
archive_exam=True
assigned_folders={folders.folders[
klausurarchiv.config.defaultArchiveId]}
break
while not exam_processed:
......@@ -432,6 +434,13 @@ for base, ns, items in sorted(all_exams,key=lambda i:i[1].lectures[0]+i[1].date)
# if we skip over lended folders, we must not delete the original files
keep_original_files=False
output=("Processing new" if first_try else "Continuing processing")
output=(
"--------------------------------------------------------------------\n"
"%s exam: \x1b[36;1m%s\x1b[30;0m\n"
%(output,base))
first_try=False
output+=("corresponding items:\n")
for item in items:
item_checksums[item]=checksum(item)
......@@ -480,6 +489,7 @@ for base, ns, items in sorted(all_exams,key=lambda i:i[1].lectures[0]+i[1].date)
output+=(" \x1b[32;1mnon-existent\x1b[30;0m %s\n"%item)
if hasSimilar:
os.system("clear -x")
sys.stdout.write(output)
output=""
sys.stdout.write(
......@@ -563,13 +573,14 @@ for base, ns, items in sorted(all_exams,key=lambda i:i[1].lectures[0]+i[1].date)
if ok:
output+=("\x1b[32;1m OK\x1b[30;0m\n")
print_count+=1
link_directories.add(folder.path)
if not archive_exam:
print_count+=1
else:
output+=("\n")
output+=("Number of exams copies to print: %s\n"%print_count)
output+=("Number of files/folders to move: %s\n"%relocate_count)
output+=("Number of exam copies to print: %s\n"%print_count)
output+=("Number of pages to print: %s\n"%(page_count*print_count))
output+=("Number of pages to print (duplex): %s\n"%(ceil(page_count*0.5)*print_count))
......@@ -584,6 +595,7 @@ for base, ns, items in sorted(all_exams,key=lambda i:i[1].lectures[0]+i[1].date)
show=not fDryRun or (isCollision and fShowCollisions) or (isErroneous and fShowErrors) or (isUnassigned and fShowUnassigned)
if show:
os.system("clear -x")
sys.stdout.write(output)
num_shown+=1
......@@ -610,22 +622,24 @@ for base, ns, items in sorted(all_exams,key=lambda i:i[1].lectures[0]+i[1].date)
opt=ask_option(
"I have all folders, issue printjob!",
"Just insert digital copies, no printing!",
"archive the exam, do not print or insert in digital folders!",
"Archive the exam, do not print it!",
"Let me adjust the list of folders!",
"abort and continue with next exam!")
"Abort and continue with next exam!")
if opt==0:
break
elif opt==1:
print_count=0
break
elif opt==2:
link_directories.clear()
print_count=0
archive_exam=True
assigned_folders={folders.folders[
klausurarchiv.config.defaultArchiveId]}
reiterate=True
break
elif opt==3:
new_folders=klausurarchiv.folder_selection.selectFolders(
"select folders for exam %s"%base,
assigned_folders)
"Select folders for exam %s"%base,
assigned_folders,archive=False)
if new_folders is None:
continue
assigned_folders=set(new_folders)
......@@ -683,6 +697,38 @@ for base, ns, items in sorted(all_exams,key=lambda i:i[1].lectures[0]+i[1].date)
exam_processed=True
continue
print("Splendid. I will now adjust the digital folders...")
elif archive_exam:
print("\x1b[32;1mOk\x1b[30;0m: Everything looks fine from this end.")
execute=True
reiterate=False
while True:
opt=ask_option(
"Archive the exam in the selected folder!",
"Let me adjust the list of archive folders!",
"Abort and continue with next exam!")
if opt==0:
break
elif opt==1:
new_folders=klausurarchiv.folder_selection.selectFolders(
"Select archive folders for exam %s"%base,
assigned_folders,archive=True)
if new_folders is None:
continue
assigned_folders=set(new_folders)
reiterate=True
break
elif opt==2:
execute=False
break
if reiterate:
continue
if not execute:
exam_processed=True
continue
else:
print("No printing is needed")
if not ask("OK to adjust the digital folders now?",True):
......@@ -725,7 +771,7 @@ for base, ns, items in sorted(all_exams,key=lambda i:i[1].lectures[0]+i[1].date)
print(
"\x1b[31;1mError\x1b[30;0m: %s"%e)
if not ask("Okay to continue",False):
exit(1)
sys.exit(1)
exam_processed=True
if abort_all:
......
......@@ -10,6 +10,7 @@ import math
import re
import os
from . import config
from . import folders
from . import cursesutil
from . import namingscheme
......@@ -73,21 +74,48 @@ class FolderSelectActivity:
# This is used for displaying errors occuring outside the activity that cause
# it to be re-executed.
#
# If archive=True and defaultFolders is None,
# klausurarchiv.config.defaultArchiveId will be selected as the default
# folder.
#
# \param title Title text to display.
# \param defaultFolders optional set of folders to use as original selection
def initialize(s,title,defaultFolders=None):
# \param archive (Only) archive folders will be offered for selection iff set
# to True
def initialize(s,title,defaultFolders=None,archive=False):
s.title=title
s.suggestions=[]
s.suggestionIndex=None
s.query=""
s._mode="query"
s.folders=[]
s._all_folders=set(s.registry.folders.values())
if not archive:
ids=s.registry.folder_ids-s.registry.archived_folder_ids
else:
ids=s.registry.archived_folder_ids
if archive and defaultFolders is None:
defaultFolders=[s.registry.folders[config.defaultArchiveId]]
s._all_folders=set(s.registry.folders[fid] for fid in ids)
s.folders=[]
if defaultFolders is not None:
s.folders=list(sorted(defaultFolders,key=lambda f:f.display_title))
# Handle the case where defaultFolders is not a subset of _all_folders
# (e.g. regular folders as defaultFolders, but archive=True).
suspicious_ids=[]
for folder in s.folders:
if folder.id not in ids:
suspicious_ids.append(folder.id)
if len(suspicious_ids)>0:
s.showError("The following IDs where provided as selected folders, "
"although they are %s folders: %s\n"
"Not sure if that is what you want..."
%(("no archive" if archive else "archived"),
", ".join(suspicious_ids)))
s.fieldsIndex=None
s.message=None
......@@ -351,11 +379,13 @@ class FolderSelectActivity:
#
# \param prompt Text to display on top of the activity
# \param defaultFolders Optional set of pre-selected folders
# \param archive (Only) archive folders will be offered for selection iff set
# to True
# \param args Additional positional arguments to be passed to the
# constructor of #SelectFolderActivity.
# \param kwargs Additional named arguments to be passed to the
# constructor of #SelectFolderActivity.
def selectFolders(prompt,defaultFolders=None,*args,**kwargs):
def selectFolders(prompt,defaultFolders=None,archive=False,*args,**kwargs):
try:
stdscr=curses.initscr()
curses.noecho()
......@@ -368,7 +398,7 @@ def selectFolders(prompt,defaultFolders=None,*args,**kwargs):
curses.use_default_colors()
act=FolderSelectActivity(stdscr,*args,**kwargs)
act.initialize(prompt,defaultFolders)
act.initialize(prompt,defaultFolders,archive)
res=act.execute()
return res
......
......@@ -445,6 +445,7 @@ class FolderRegistry:
s._folders=dict()
s._folder_groups=dict()
s._folder_ids=set()
s._archived_folder_ids=set()
s._invalid_folders=set()
if root==None:
root=os.path.join(s._root,"alle-ordner")
......@@ -477,6 +478,9 @@ class FolderRegistry:
s._folders[fb]=m
s._folders[m.id]=m
s._folder_ids.add(m.id)
if m.archived:
s._archived_folder_ids.add(m.id)
gid=m.id[:-1]
if not gid in s._folder_groups:
......@@ -538,6 +542,16 @@ class FolderRegistry:
s.load()
return s._folder_ids
## \brief Returns a set of all archived folder IDs.
#
# This set contains the IDs of all folders which have `archived=True` set.
#
@property
def archived_folder_ids(s):
if not s._loaded:
s.load()
return s._archived_folder_ids
## \brief Returns a set of all the names of directories that are not valid
# digital folders.
#
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment