<commit_before>"""
views.py - xmlrpc request manager

Author 
    <NAME> <<EMAIL>>

License
    Copyright (c) 2010 Massachusetts Institute of Technology.
    MIT License (cf. MIT-LICENSE.txt or http://www.opensource.org/licenses/mit-license.php)
"""
from base import annotations
import  json, sys, datetime, time
from base import  auth, signals, constants, models as M, utils_response as UR
#TODO import responder
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from django.template.loader import render_to_string
import logging, random, string
import urllib
id_log = "".join([ random.choice(string.ascii_letters+string.digits) for i in xrange(0,10)])
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(levelname)s %(message)s', filename='/tmp/nb_rpc_%s.log' % ( id_log,), filemode='a')
SLEEPTIME = 0.1
#The functions that are allowed to be called from a http client
__EXPORTS = [
    "getObjects", 
    "getParams", 
    "getNotes",
    "saveNote", 
    "editNote", 
    "deleteNote", 
    "getStats",
    "getMyNotes", 
    "getGuestFileInfo", 
    "markNote", 
    "request_source_id",
    "log_history",
    "remote_log",
    "getGradees", 
    "edit_assignment",
    "get_location_info", 
    "get_comment_info", 
    "save_settings", 
    "approveNote", 
    "editPoll", 
    "getMembers",
    "sendInvites", 
    "passwordLost", 
    "presearch",
    "get_stats_ensemble", 
    "add_folder", 
    "add_ensemble", 
    "rename_file", 
    "delete_file", 
    "move_file", 
    "register_user", 
    "login_user", 
    "set_grade_assignment"
    ]
__AVAILABLE_TYPES = set(["folders", "ensembles", "files", "assignments", "marks", "settings", "file_stats", "ensemble_stats", "polls", "choices", "responses", "polls_stats", "ensemble_stats2"])
__AVAILABLE_PARAMS = ["RESOLUTIONS", "RESOLUTION_COORDINATES"]
__AVAILABLE_STATS = ["auth", "newauth", "question", "newquestion", "unclear", "newunclear","auth_group", "newauth_group", "question_group", "newquestion_group", "unclear_group", "newunclear_group", "auth_grader", "newauth_grader", "auth_admin", "newauth_admin", "unanswered", "auth_everyone", "newauth_everyone", "favorite", "newfavorite", "search" ]


def on_register_session(sender, **payload): 
    req = payload["req"]
    #print req.META
    uid =  UR.getUserInfo(req, True).id
    p={}
    p["ctime"] = payload["cid"]
    p["ip"]     = req.META["REMOTE_ADDR"] if "REMOTE_ADDR" in req.META else None
    annotations.register_session(uid, p)
signals.register_session.connect(on_register_session, weak=False)

def __parseEntities_str(s, delimiter):
    if delimiter in s: 
        return [x.strip().lower() for x in s.split(delimiter)]
    return [s.strip().lower()]

def __parseEntities_list(a, delimiter): 
    o = []
    for s in a: 
        o.extend(__parseEntities_str(s, delimiter))
    return o

def parseEntities(x, d): 
    o = x
    if type(d)==list: 
        for delimiter in d: 
            o = parseEntities(o, delimiter)
        return o
    else: 
        delimiter = d
        if type(x)==list: 
            return __parseEntities_list(x,delimiter)
        return __parseEntities_str(x,delimiter)

def sendInvites(payload, req): 
    from django.core.mail import EmailMessage
    uid = UR.getUserId(req);
    id_ensemble = payload["id_ensemble"]
    admin = 0 if "admin" not in payload else payload["admin"]
    if not auth.canSendInvite(uid,id_ensemble):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")      
    #extract emails in a somewhat robust fashion (i.e. using several possible delimiters)
    emails = parseEntities(payload["to"], [",", "\n", " "])
    logging.info("to: %s, extracted: %s" %  (payload["to"], emails))
    #add new users to DB w/ pending status
    for email in emails:       <commit_msg>improved email parsing so that we manage emails like "<NAME> <<EMAIL>> correctly"<commit_after>"""
views.py - xmlrpc request manager

Author 
    <NAME> <<EMAIL>>

License
    Copyright (c) 2010 Massachusetts Institute of Technology.
    MIT License (cf. MIT-LICENSE.txt or http://www.opensource.org/licenses/mit-license.php)
"""
from base import annotations
import  json, sys, datetime, time
from base import  auth, signals, constants, models as M, utils_response as UR
#TODO import responder
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from django.template.loader import render_to_string
import logging, random, string
import urllib
id_log = "".join([ random.choice(string.ascii_letters+string.digits) for i in xrange(0,10)])
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(levelname)s %(message)s', filename='/tmp/nb_rpc_%s.log' % ( id_log,), filemode='a')
SLEEPTIME = 0.1
#The functions that are allowed to be called from a http client
__EXPORTS = [
    "getObjects", 
    "getParams", 
    "getNotes",
    "saveNote", 
    "editNote", 
    "deleteNote", 
    "getStats",
    "getMyNotes", 
    "getGuestFileInfo", 
    "markNote", 
    "request_source_id",
    "log_history",
    "remote_log",
    "getGradees", 
    "edit_assignment",
    "get_location_info", 
    "get_comment_info", 
    "save_settings", 
    "approveNote", 
    "editPoll", 
    "getMembers",
    "sendInvites", 
    "passwordLost", 
    "presearch",
    "get_stats_ensemble", 
    "add_folder", 
    "add_ensemble", 
    "rename_file", 
    "delete_file", 
    "move_file", 
    "register_user", 
    "login_user", 
    "set_grade_assignment"
    ]
__AVAILABLE_TYPES = set(["folders", "ensembles", "files", "assignments", "marks", "settings", "file_stats", "ensemble_stats", "polls", "choices", "responses", "polls_stats", "ensemble_stats2"])
__AVAILABLE_PARAMS = ["RESOLUTIONS", "RESOLUTION_COORDINATES"]
__AVAILABLE_STATS = ["auth", "newauth", "question", "newquestion", "unclear", "newunclear","auth_group", "newauth_group", "question_group", "newquestion_group", "unclear_group", "newunclear_group", "auth_grader", "newauth_grader", "auth_admin", "newauth_admin", "unanswered", "auth_everyone", "newauth_everyone", "favorite", "newfavorite", "search" ]


def on_register_session(sender, **payload): 
    req = payload["req"]
    #print req.META
    uid =  UR.getUserInfo(req, True).id
    p={}
    p["ctime"] = payload["cid"]
    p["ip"]     = req.META["REMOTE_ADDR"] if "REMOTE_ADDR" in req.META else None
    annotations.register_session(uid, p)
signals.register_session.connect(on_register_session, weak=False)

def __parseEntities_str(s, delimiter):
    if delimiter in s: 
        return [x.strip().lower() for x in s.split(delimiter)]
    return [s.strip().lower()]

def __parseEntities_list(a, delimiter): 
    o = []
    for s in a: 
        o.extend(__parseEntities_str(s, delimiter))
    return o

def parseEntities(x, d): 
    o = x
    if type(d)==list: 
        for delimiter in d: 
            o = parseEntities(o, delimiter)
        return o
    else: 
        delimiter = d
        if type(x)==list: 
            return __parseEntities_list(x,delimiter)
        return __parseEntities_str(x,delimiter)

def sendInvites(payload, req): 
    from django.core.mail import EmailMessage
    uid = UR.getUserId(req);
    id_ensemble = payload["id_ensemble"]
    admin = 0 if "admin" not in payload else payload["admin"]
    if not auth.canSendInvite(uid,id_ensemble):
        return UR.prepare_response({}, 1,  "NOT ALLOWED")      
    #extract emails in a somewhat robust fashion (i.e. using several possible delimiters)
    emails = parseEntities(payload["to"], [",", "\n", " "])
    #remove spurious stuff: strings that don't have an "@" and trailings "<" and ">" characters, 
    #because some emails the following format: <NAME> <<EMAIL>>     
    emails = [o.replace("<", "").replace(">", "") for o in emails if "@" in o]          
    logging.info("to: %s, extracted: %s" %  (payload["to"], emails))
    #add new users to DB w/ pending status
    for email in emails:       
{'fraction_non_alphanumeric': 0.13855572213893053, 'fraction_numerical': 0.0029985007496251873, 'mean_word_length': 3.822289156626506, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4366043', 'n_tokens_mistral': 2766, 'n_tokens_neox': 2662, 'n_words': 653}