## Script (Python) "search_students"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=REQUEST
##title=
##
# $Id: search_students.py 911 2006-11-20 15:11:29Z henrik $
"""
list Students for ClearanceOfficers
"""
import logging
logger = logging.getLogger('Search.Timer')
from DateTime import DateTime
#
#with_timer = True
with_timer = False
#
request = REQUEST
form = request.form
fget = form.get
mtool = context.portal_membership
member = mtool.getAuthenticatedMember()
is_anon = mtool.isAnonymousUser()
lt = context.portal_layouts
path_info = request.get('PATH_INFO').split('/')

allowed = True
if is_anon:
    allowed = False
try:
    from Products.AdvancedQuery import Eq, Between, Le,In
    evalAdvancedQuery = context.portal_catalog.evalAdvancedQuery
    aq_students = context.students_catalog.evalAdvancedQuery
except:
    evalAdvancedQuery = None

def cmp_id(a,b):
    if a.getId() > b.getId():
        return 1
    return -1

student_subobjects = ("StudentApplication",
                      "StudentPersonal",
                      "StudentStudyCourse",
                      "StudentAccommodation",
                      "StudentStudyLevel",)

#student_objects = student_subobjects + ("Student",)
student_objects = ("Student",)

user_info = {}
items = []
validate = request.has_key("cpsdocument_edit_button")

state = "all"
user_info['member'] = str(member)
user_info['departments'] = []
user_info['faculties'] = []
co_view = False
faculties =  fget('faculties')
departments = fget('departments')
dep_str = fac_str = ''
if "ClearanceOfficers" in member.getGroups():
    state = "clearance_requested"
    only_review = False
    co_view = True
    if faculties or departments:
        #from Products.zdb import set_trace;set_trace()
        if faculties:
            fac_str = faculties
            faculties = faculties.split()
        if departments:
            dep_str = departments
            departments = departments.split()
    else:
        query = In('portal_type',('Faculty',)) &\
                 In('localUsersWithRoles', ("user:%s" % member,))
        res = evalAdvancedQuery(query)
        faculties = []
        if res:
            faculties = [f.getId for f in res]
        user_info['faculties'] = faculties
        fac_str = " ".join(faculties)
        query = In('portal_type',('Department',)) &\
                 In('localUsersWithRoles', ("user:%s" % member,))
        res = evalAdvancedQuery(query)
        departments = []
        if res:
            departments = [f.getId for f in res]
        user_info['departments'] = departments
        dep_str = " ".join(departments)
default = {'search_mode': 'student_id',
        'review_state': state,
        'search_string': ''
        }
rend,psm,ds = lt.renderLayout(layout_id= 'student_search',
                      schema_id= 'student_search',
                      context=context,
                      mapping=validate and REQUEST,
                      ob=default,
                      layout_mode='edit',
                      formaction="search_students",
                      faculties = fac_str,
                      departments = dep_str,
                      commit = False,
                      )
if psm == '':
    return context.search_students_form(rendered = rend,
                             psm = psm,
                             #psm = "%s, %s" % (psm,ds),
                             info = user_info,
                             students = [],
                             allowed = allowed,
                             )
what = ds.get('search_mode')
state = ds.get('review_state')
st = term = ds.get('search_string')
err = False
with_review = state != "all"
only_review = with_review and not term
bools = "with_review = %s<br\> only_review = %s<br\>" % (with_review,only_review)
if not term and not with_review:
    psm = "You must specify a search string when searching 'all states'!"
    err = True
elif '*' in term:
    psm = "Wildcards are not supported!"
    err = True
if err:
    return context.search_students_form(rendered = rend,
                             psm = psm,
                             #psm = "%s, %s" % (psm,ds),
                             info = user_info,
                             students = items,
                             allowed = allowed,
                             )
st_queries = ('jamb_reg_no','matric_no','name')
review_res = None
query = None
items = []
res = []
review_set = []
search_set = []
if len(term) > 0:
    if what == "student_id":
        students_folder = context.portal_url.getPortalObject().campus.students
        if hasattr(students_folder,term.strip()):
            request.RESPONSE.redirect("%s/%s" % (students_folder.absolute_url(),term))
        return context.search_students_form(rendered = rend,
                             psm = "No student found!",
                             students = [],
                             allowed = allowed,
                             )
    elif what == "department":
        res = context.students_catalog(department=term.strip())
        search_set = [r.id for r in res]
    elif what == "matric_no":
        res = context.students_catalog(matric_no=term.strip())
        search_set = [r.id for r in res]
    elif what in st_queries:
        if what == "jamb_reg_no":
            pt = ('StudentApplication',)
            st = "%s" % term.strip().lower()
        elif what == "name":
            pt = ('StudentPersonal')
            st = "%s" % term.strip()
        query = In('portal_type',pt) & Eq('SearchableText',"%s*" % term.strip())
        res = evalAdvancedQuery(query)
        if res:
            for r in res:
                pl = r.getPath().split('/')
                search_set.append(pl[pl.index('students') + 1])
if only_review or with_review or co_view:
    if with_timer:
        start = DateTime().timeTime()
        logger.info('"%s","start 100"' % member)
    query = Eq('review_state',state)
    review_res = evalAdvancedQuery(query)
    if with_timer:
        end = DateTime().timeTime()
        logger.info('"%s","searchtime","%6.2f"' % (member,end-start))
if co_view:
    only_review = False
    with_review = True
    if with_timer:
        start = DateTime().timeTime()
        logger.info('"%s","start 200"' % member)
    query = In('faculty',faculties) | In('department',departments)
    res = aq_students(query)
    if with_timer:
        end = DateTime().timeTime()
        logger.info('"%s","searchtime","%6.2f"' % (member,end-start))
    start = DateTime().timeTime()
    search_set = [r.id for r in res]
    if with_timer:
        end = DateTime().timeTime()
        logger.info('"%s","searchtime","%6.2f"' % (member,end-start))
if with_timer:
    logger.info('"%s","start 300"' % member)
    start = DateTime().timeTime()
if review_res:
    review_set = [r.getId for r in review_res]
if with_timer:
    end = DateTime().timeTime()
    logger.info('"%s","searchtime","%6.2f"' % (member,end-start))
    logger.info('"%s","start 400"' % member)
    start = DateTime().timeTime()
if only_review:
    all = review_set
elif with_review:
    all = []
    for i in search_set:
        if i in review_set:
            all.append(i)
else:
    all = search_set
if with_timer:
    end = DateTime().timeTime()
    logger.info('"%s","searchtime","%6.2f"' % (member,end-start))
items = all[:500]
students = []
if with_timer:
    logger.info('"%s","start 500"' % member)
    start = DateTime().timeTime()
if items:
    for item in items:
        stcat = context.students_catalog
        record = stcat(id = item)[0]
        info = {}
        for field in stcat.schema() + stcat.indexes():
            info[field] = getattr(record, field)
        else:
            students.append(info)
    if with_timer:
        end = DateTime().timeTime()
        logger.info('"%s","searchtime","%6.2f"' % (member,end-start))

    return context.search_students_form(rendered = rend,
                             psm = "",
                             info = user_info,
                             students = students,
                             allowed = allowed,
                             co_view = co_view,
                             )
return context.search_students_form(rendered = rend,
                             psm = "No student found!",
                             info = user_info,
                             students = students,
                             allowed = allowed,
                             )


