diff --git a/modules/webmessage/lib/webmessage.py b/modules/webmessage/lib/webmessage.py index 4ae827c2d..93e9e0a1e 100644 --- a/modules/webmessage/lib/webmessage.py +++ b/modules/webmessage/lib/webmessage.py @@ -1,471 +1,471 @@ # -*- coding: utf-8 -*- ## $Id$ ## Messaging system (internal) ## This file is part of the CERN Document Server Software (CDSware). ## Copyright (C) 2002, 2003, 2004, 2005 CERN. ## ## The CDSware is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## The CDSware is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDSware; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. """webmessage module, messaging system""" __lastupdated__ = """$Date$""" # CDSWare imports from cdsware.webmessage_dblayer import * from cdsware.webmessage_config import * from cdsware.config import cdslang from cdsware.messages import gettext_set_language -from cdsware.dateutils import date_convert_to_MySQL +from cdsware.dateutils import get_db_date from cdsware.webuser import list_users_in_roles from cdsware.search_engine import wash_url_argument import cdsware.template try: webmessage_templates = cdsware.template.load('webmessage') except: pass def perform_request_display_msg(uid, msgid, ln = cdslang): """ Displays a specific message @param uid: user id @param msgid: message id @return a (body, errors[], warnings[]) formed tuple """ # Wash the arguments... uid = wash_url_argument(uid, 'int') msgid = wash_url_argument(msgid, 'int') errors = [] warnings = [] body = "" if (check_user_owns_message(uid, msgid) == 0): # The user doesn't own this message errors.append(('ERR_WEBMESSAGE_NOTOWNER',)) else: (msg_id, msg_from_id, msg_from_nickname, msg_sent_to, msg_sent_to_group, msg_subject, msg_body, msg_sent_date, msg_received_date, msg_status) = get_message(uid, msgid) if (msg_id == ""): # The message exists in table user_msgMESSAGE # but not in table msgMESSAGE => table inconsistency errors.append(('ERR_WEBMESSAGE_NOMESSAGE',)) else: if (msg_status == 'N'): set_message_status(uid, msgid, 'R') body = webmessage_templates.tmpl_display_msg(msg_id, msg_from_id, msg_from_nickname, msg_sent_to, msg_sent_to_group, msg_subject, msg_body, msg_sent_date, msg_received_date, ln) return (body, errors, warnings) def perform_request_display(uid, errors=[], warnings=[], infos=[], ln=cdslang): """ Displays the user's Inbox @param uid: user id @return a (body, [errors], [warnings]) formed tuple """ # Wash the arguments... uid = wash_url_argument(uid, 'int') body = "" rows = [] rows = get_all_messages_for_user(uid) nb_messages = 0 no_quota_users = list_users_in_roles(cfg_webmessage_roles_without_quota) if (not(uid in no_quota_users)): nb_messages = count_nb_messages(uid) body = webmessage_templates.tmpl_display_inbox(messages=rows, infos=infos, warnings=warnings, nb_messages=nb_messages, ln=ln) return (body, errors, warnings) def perform_request_delete_msg(uid, msgid, ln=cdslang): """ Delete a given message from user inbox @param uid: user id (int) @param msgid: message id (int) @param ln: language @return a (body, errors, warning tuple) """ # Wash the arguments... uid = wash_url_argument(uid, 'int') msgid = wash_url_argument(msgid, 'int') _ = gettext_set_language(ln) errors = [] warnings = [] infos = [] if (check_user_owns_message(uid, msgid) == 0): # The user doesn't own this message errors.append(('ERR_WEBMESSAGE_NOTOWNER',)) else: if (delete_message_from_user_inbox(uid, msgid)==0): warnings.append(_("The message could not be deleted")) else: infos.append(_("Delete successful")) return perform_request_display(uid, errors, warnings, infos, ln) def perform_request_delete_all(uid, confirmed=0, ln=cdslang): """ Delete every message for a given user @param uid: user id (int) @param confirmed: 0 will produce a confirmation message @param ln: language @return a (body, errors, warnings) tuple """ infos = [] warnings = [] errors = [] confirmed = wash_url_argument(confirmed, 'int') _ = gettext_set_language(ln) if (confirmed == 1): delete_all_messages(uid) infos = [_("Your mailbox has been emptied")] return perform_request_display(uid, warnings, errors, infos, ln) else: body = webmessage_templates.tmpl_confirm_delete(ln) return (body, errors, warnings) def perform_request_write(uid, msg_reply_id="", msg_to="", msg_to_group="", ln=cdslang): """ Display a write a message page. @param uid: user id (int) @param msg_reply_id: if this message is a reply to another, other's ID (int) @param msg_to: comma separated usernames (string) @param msg_to_group: comma separated groupnames (string) @param ln: language @return a (body, errors, warnings) tuple """ # wash arguments uid = wash_url_argument(uid, 'int') msg_reply_id = wash_url_argument(msg_reply_id, 'int') msg_to = wash_url_argument(msg_to, 'str') msg_to_group = wash_url_argument(msg_to_group, 'str') # ln has already been washed in yourmessages.py errors = [] warnings = [] body = "" msg_from_nickname = "" msg_subject = "" msg_body = "" msg_id = 0 if (msg_reply_id): if (check_user_owns_message(uid, msg_reply_id) == 0): # The user doesn't own this message errors.append(('ERR_WEBMESSAGE_NOTOWNER',)) else: # Junk== make pylint happy! junk = 0 (msg_id, junk, msg_from_nickname, junk, junk, msg_subject, msg_body, junk, junk, junk) = get_message(uid, msg_reply_id) if (msg_id == ""): # The message exists in table user_msgMESSAGE # but not in table msgMESSAGE => table inconsistency errors.append(('ERR_WEBMESSAGE_NOMESSAGE',)) else: msg_to = msg_from_nickname body = webmessage_templates.tmpl_write(msg_to=msg_to, msg_to_group=msg_to_group, msg_id=msg_id, msg_subject=msg_subject, msg_body=msg_body, warnings=[], ln=ln) return (body, errors, warnings) def perform_request_write_with_search(msg_to_user="", msg_to_group="", msg_subject="", msg_body="", msg_send_year=0, msg_send_month=0, msg_send_day=0, users_to_add=[], groups_to_add=[], user_search_pattern="", group_search_pattern="", mode_user=1, add_values=0, ln=cdslang): """ Display a write message page, with prefilled values @param msg_to_user: comma separated usernames (str) @param msg_to_group: comma separated groupnames (str) @param msg_subject: message subject (str) @param msg_bidy: message body (string) @param msg_send_year: year to send this message on (int) @param_msg_send_month: month to send this message on (int) @param_msg_send_day: day to send this message on (int) @param users_to_add: list of usernames ['str'] to add to msg_to_user @param groups_to_add: list of groupnames ['str'] to add to msg_to_group @param user_search_pattern: will search users with this pattern (str) @param group_search_pattern: will search groups with this pattern (str) @param mode_user: if 1 display user search box, else group search box @param add_values: if 1 users_to_add will be added to msg_to_user field.. @param ln: language @return a (body, errors, warnings) formed tuple. """ # wash arguments users_to_add = wash_url_argument(users_to_add, 'list') groups_to_add = wash_url_argument(groups_to_add, 'list') msg_send_year = wash_url_argument(msg_send_year, 'int') msg_send_month = wash_url_argument(msg_send_month, 'int') msg_send_day = wash_url_argument(msg_send_day, 'int') user_list_output = [] group_list_output = [] warnings = [] errors = [] def separate(name1, name2): """ name1, name2 => "name1, name2" """ return name1 + cfg_webmessage_separator + " " + name2 if mode_user: if add_values and users_to_add: tmp = users_to_add if msg_to_user: tmp.insert(0, msg_to_user) msg_to_user = reduce(separate, tmp) if user_search_pattern: users_found = get_nicknames_like(user_search_pattern) if users_found: for user_name in users_found: user_list_output.append((user_name[0], user_name[0] in users_to_add)) else: if add_values and groups_to_add: tmp = groups_to_add if msg_to_group: tmp.insert(0, msg_to_group) msg_to_group = reduce(separate, tmp) if group_search_pattern: groups_found = get_groupnames_like(group_search_pattern) if groups_found: for group_name in groups_found: group_list_output.append((group_name[0], group_name[0] in groups_to_add)) body = webmessage_templates.tmpl_write(msg_to=msg_to_user, msg_to_group=msg_to_group, msg_subject=msg_subject, msg_body=msg_body, msg_send_year=msg_send_year, msg_send_month=msg_send_month, msg_send_day=msg_send_day, warnings=warnings, users_to_add=user_list_output, groups_to_add=group_list_output, user_search_pattern=user_search_pattern, group_search_pattern=group_search_pattern, display_users_to_add=mode_user, ln=ln) return (body, errors, warnings) def perform_request_send(uid, msg_to_user="", msg_to_group="", msg_subject="", msg_body="", msg_send_year=0, msg_send_month=0, msg_send_day=0, ln=cdslang): """ send a message. if unable return warenings to write page @param uid: id of user from (int) @param msg_to_user: comma separated usernames (recipients) (str) @param msg_to_group: comma separated groupnames (recipeints) (str) @param msg_subject: subject of message (str) @param msg_body: body of message (str) @param msg_send_year: send this message on year x (int) @param msg_send_month: send this message on month y (int) @param msg_send_day: send this message on day z (int) @param ln: language @return a (body, errors, warnings) tuple """ # wash arguments msg_to_user = wash_url_argument(msg_to_user, 'str') msg_to_group = wash_url_argument(msg_to_group, 'str') msg_subject = wash_url_argument(msg_subject, 'str') msg_body = wash_url_argument(msg_body, 'str') msg_send_year = wash_url_argument(msg_send_year, 'int') msg_send_month = wash_url_argument(msg_send_month, 'int') msg_send_day = wash_url_argument(msg_send_day, 'int') _ = gettext_set_language(ln) def strip_spaces(str): """suppress spaces before and after x (str)""" return str.strip() # wash user input users_to = map(strip_spaces, msg_to_user.split(cfg_webmessage_separator)) groups_to = map(strip_spaces, msg_to_group.split(cfg_webmessage_separator)) if users_to == ['']: users_to = [] if groups_to == ['']: groups_to = [] warnings = [] errors = [] infos = [] problem = None users_to_str = cfg_webmessage_separator.join(users_to) groups_to_str = cfg_webmessage_separator.join(groups_to) if (msg_send_year == msg_send_month == msg_send_day == 0): status = cfg_webmessage_status_code['NEW'] else: status = cfg_webmessage_status_code['REMINDER'] try: - send_on_date = date_convert_to_MySQL(msg_send_year, msg_send_month, msg_send_day) + send_on_date = get_db_date(msg_send_year, msg_send_month, msg_send_day) except ValueError: warnings.append(_("The chosen date (%i/%i/%i) is invalid")%(msg_send_year, msg_send_month, msg_send_day)) problem = 1 if not(users_to_str or groups_to_str): # <=> not(users_to_str) AND not(groups_to_str) warnings.append(_("Please enter a user name or a group name")) problem = 1 if len(msg_body) > cfg_webmessage_max_size_of_message: warnings.append(_("""Your message is too long, please edit it. Max size allowed is %i characters """)%(cfg_webmessage_max_size_of_message,)) problem = 1 users_dict = get_uids_from_nicks(users_to) users_to = users_dict.items() groups_dict = get_gids_from_groupnames(groups_to) groups_to = groups_dict.items() gids_to = [] for (group_name, group_id) in groups_to: if not(group_id): warnings.append(_("Group '%s' doesn't exist\n")% (group_name)) problem = 1 else: gids_to.append(group_id) # Get uids from gids uids_from_group = get_uids_members_of_groups(gids_to) # Add the original uids, and make sure there is no double values. tmp_dict = {} for uid in uids_from_group: tmp_dict[uid] = None for (user_nick, user_id) in users_to: if user_id: if user_id not in tmp_dict: uids_from_group.append(user_id) tmp_dict[user_id] = None else: warnings.append(_("User '%s' doesn't exist\n")% (user_nick)) problem = 1 if problem: body = webmessage_templates.tmpl_write(msg_to=users_to_str, msg_to_group=groups_to_str, msg_subject=msg_subject, msg_body=msg_body, msg_send_year=msg_send_year, msg_send_month=msg_send_month, msg_send_day=msg_send_day, warnings=warnings, ln=ln) return (body, errors, warnings) else: msg_id = create_message(uid, users_to_str, groups_to_str, msg_subject, msg_body, send_on_date) uid_problem = send_message(uids_from_group, msg_id, status) if len(uid_problem) > 0: usernames_problem_dict = get_nicks_from_uids(uid_problem) usernames_problem = usernames_problem_dict.values() def listing(name1, name2): """ name1, name2 => 'name1, name2' """ return str(name1) + ", " + str(name2) warning = _("Your message couldn't be sent to the following recipients\n") warning += _("These users are overquota: ") warnings.append(warning + reduce(listing, usernames_problem)) if len(uids_from_group) != len(uid_problem): infos.append(_("Your message has been sent.")) else: check_if_need_to_delete_message_permanently([msg_id]) return perform_request_display(uid, errors, warnings, infos, ln) def account_new_mail(uid, ln=cdslang): """ display new mail info for myaccount.py page. @param uid: user id (int) @param ln: language @return html body """ nb_new_mail = get_nb_new_mail_for_user(uid) return webmessage_templates.tmpl_account_new_mail(nb_new_mail, ln) def get_navtrail(ln=cdslang, title=""): """ gets the navtrail for title... @param title: title of the page @param ln: language @return HTML output """ navtrail = webmessage_templates.tmpl_navtrail(ln, title) return navtrail diff --git a/modules/webmessage/lib/webmessage_dblayer.py b/modules/webmessage/lib/webmessage_dblayer.py index fcab82bbf..4b7b6cdf8 100644 --- a/modules/webmessage/lib/webmessage_dblayer.py +++ b/modules/webmessage/lib/webmessage_dblayer.py @@ -1,542 +1,542 @@ # -*- coding: utf-8 -*- ## $Id$ ## ## Every db-related function of module webmessage ## ## This file is part of the CERN Document Server Software (CDSware). ## Copyright (C) 2002, 2003, 2004, 2005 CERN. ## ## The CDSware is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## The CDSware is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDSware; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. import time from MySQLdb import escape_string from cdsware.dbquery import run_sql from cdsware.webmessage_config import cfg_webmessage_status_code, \ cfg_webmessage_max_nb_of_messages, \ cfg_webmessage_roles_without_quota, \ cfg_webmessage_days_before_delete_orphans from cdsware.webuser import list_users_in_roles def check_user_owns_message(uid, msgid): """ Checks whether a user owns a message @param uid: user id @param msgid: message id @return 1 if the user owns the message, else 0 """ query = """SELECT count(*) FROM user_msgMESSAGE WHERE id_user_to=%(user_id)i AND id_msgMESSAGE=%(message_id)i""" params = {'user_id': int(uid), 'message_id': int(msgid)} res = run_sql(query%params) return int(res[0][0]) def get_message(uid, msgid): """ get a message with its status @param uid: user id @param msgid: message id @return a (message_id, id_user_from, nickname_user_from, sent_to_user_nicks, sent_to_group_names, subject, body, sent_date, received_date, status) formed tuple or 0 (ZERO) if none found """ query = """SELECT m.id, m.id_user_from, u.nickname, m.sent_to_user_nicks, m.sent_to_group_names, m.subject, m.body, - m.sent_date, - m.received_date, + DATE_FORMAT(m.sent_date, '%%Y-%%m-%%d %%H:%%i:%%s'), + DATE_FORMAT(m.received_date, '%%Y-%%m-%%d %%H:%%i:%%s'), um.status FROM msgMESSAGE m, user_msgMESSAGE um, user u WHERE m.id=%(message_id)i AND um.id_msgMESSAGE=%(message_id)i AND um.id_user_to=%(user_id)i AND u.id=m.id_user_from""" params = {'message_id': int(msgid), 'user_id': int(uid)} res = run_sql(query%params) if res: return res[0] else: return 0 def set_message_status(uid, msgid, new_status): """ Change the status of a message (e.g. from "new" to "read"). the status is a single character string, specified in constant cfg_webmessage_status_code in file webmessage_config.py examples: N: New message R: alreay Read message M: reminder @param uid: user ID @param msgid: Message ID @param new_status: new status. Should be a single character @return 1 if succes, 0 if not """ query = """UPDATE user_msgMESSAGE SET status='%s' WHERE id_user_to=%i AND id_msgMESSAGE=%i""" params = (escape_string(new_status), uid, msgid) return int(run_sql(query%params)) def get_nb_new_mail_for_user(uid): """ Get number of new mails for a given user @param uid: user id (int) @return number of new mails as int. """ update_user_inbox_for_reminders(uid) new_status = cfg_webmessage_status_code['NEW'] query = """SELECT count(id_msgMESSAGE) FROM user_msgMESSAGE WHERE id_user_to=%i AND BINARY status='%s'""" params = (int(uid), escape_string(new_status)) res = run_sql(query%params) if res: return res[0][0] else: return 0 def get_all_messages_for_user(uid): """ Get all messages for a user's inbox, without the eventual non-expired reminders. @param uid: user id @return [(message_id, id_user_from, nickname_user_from, message_subject, message_sent_date, message_status)] """ update_user_inbox_for_reminders(uid) reminder_status = cfg_webmessage_status_code['REMINDER'] query = """SELECT m.id, m.id_user_from, u.nickname, m.subject, - m.sent_date, + DATE_FORMAT(m.sent_date, '%%Y-%%m-%%d %%H:%%i:%%s'), um.status FROM user_msgMESSAGE um, msgMESSAGE m, user u WHERE um.id_user_to = %(user_to)i AND !(BINARY um.status='%(status)s') AND um.id_msgMESSAGE=m.id AND u.id=m.id_user_from ORDER BY m.sent_date DESC """ params = {'user_to': int(uid), 'status': escape_string(reminder_status) } return run_sql(query%params) def count_nb_messages(uid): """ @param uid: user id @return integer of number of messages a user has, 0 if none """ uid = int(uid) query = """SELECT count(id_user_to) FROM user_msgMESSAGE WHERE id_user_to=%i """ res = run_sql(query%uid) if res: return int(res[0][0]) else: return 0 def delete_message_from_user_inbox(uid, msg_id): """ Delete message from users inbox If this message was does not exist in any other user's inbox, delete it permanently from the database @param uid: user id @param msg_id: message id @return integer 1 if delete was successful, integer 0 else """ query1 = """DELETE FROM user_msgMESSAGE WHERE id_user_to=%i AND id_msgMESSAGE=%i""" params1 = (int(uid), int(msg_id)) res1 = run_sql(query1%params1) check_if_need_to_delete_message_permanently([msg_id]) return int(res1) def check_if_need_to_delete_message_permanently(msg_ids): """ Checks if a list of messages exist in anyone's inbox, if not, delete them permanently @param msg_id: sequence of message ids @return number of deleted messages """ if not((type(msg_ids) is list) or (type(msg_ids) is tuple)): msg_ids = [msg_ids] query1 = """SELECT count(id_msgMESSAGE) FROM user_msgMESSAGE WHERE id_msgMESSAGE=%i""" messages_to_delete = [] for msg_id in msg_ids: nb_users = int(run_sql(query1%(int(msg_id),))[0][0]) if nb_users == 0: messages_to_delete.append(int(msg_id)) if len(messages_to_delete) > 0: query2 = """DELETE FROM msgMESSAGE WHERE""" for msg_id in messages_to_delete[0:-1]: query2 += " id=%i" % (msg_id,) + " OR" query2 += " id=%i" % (messages_to_delete[-1]) run_sql(query2) return len(messages_to_delete) def delete_all_messages(uid): """ Delete all messages of a user (except reminders) @param uid: user id @return the number of messages deleted """ reminder_status = cfg_webmessage_status_code['REMINDER'] query1 = """SELECT id_msgMESSAGE FROM user_msgMESSAGE WHERE id_user_to=%i AND NOT(BINARY status like '%s')""" params = (int(uid), reminder_status) msg_ids = map(get_element, run_sql(query1%params)) query2 = """DELETE FROM user_msgMESSAGE WHERE id_user_to=%i AND NOT(BINARY status like '%s')""" nb_messages = int(run_sql(query2%params)) check_if_need_to_delete_message_permanently(msg_ids) return nb_messages def get_uids_from_nicks(nicks): """ Get the association uid/nickname of given nicknames @param nicks: list or sequence of strings, each string being a nickname @return a dictionary {nickname: uid} """ if not((type(nicks) is list) or (type(nicks) is tuple)): nicks = [nicks] users = {} query = "SELECT nickname, id FROM user WHERE BINARY nickname in(" if len(nicks)> 0: for nick in nicks: users[nick] = None for nick in users.keys()[0:-1]: query += "'%s'," % escape_string(nick) query += "'%s')" % escape_string(users.keys()[-1]) res = run_sql(query) def enter_dict(couple): """ takes a a tuple and enters it into dict users """ users[couple[0]] = int(couple[1]) map(enter_dict, res) return users def get_nicks_from_uids(uids): """ Get the association uid/nickname of given uids @param uids: list or sequence of uids @return a dictionary {uid: nickname} where empty value is possible """ if not((type(uids) is list) or (type(uids) is tuple)): uids = [uids] users = {} query = "SELECT id, nickname FROM user WHERE id in(" if len(uids) > 0: for uid in uids: users[uid] = None for uid in users.keys()[0:-1]: query += "%i," % int(uid) query += "%i)" % int(users.keys()[-1]) res = run_sql(query) for (user_id, nickname) in res: users[int(user_id)] = nickname return users def get_gids_from_groupnames(groupnames): """ Get the gids of given groupnames @param groupnames: list or sequence of strings, each string being a groupname @return a dictionary {groupname: gid} """ if not((type(groupnames) is list) or (type(groupnames) is tuple)): groupnames = [groupnames] groups = {} query = "SELECT name, id FROM usergroup WHERE BINARY name in(" if len(groupnames) > 0: for groupname in groupnames: groups[groupname] = None for groupname in groups.keys()[0:-1]: query += "'%s'," % escape_string(groupname) query += "'%s')" % escape_string(groups.keys()[-1]) res = run_sql(query) def enter_dict(couple): """ enter a tuple into dictionary groups """ groups[couple[0]] = int(couple[1]) map(enter_dict, res) return groups def get_uids_members_of_groups(gids): """ Get the distinct ids of users members of given groups. @param groupnames: list or sequence of group ids @return a list of uids. """ if not((type(gids) is list) or (type(gids) is tuple)): gids = [gids] query = "SELECT DISTINCT id_user FROM user_usergroup WHERE" if len(gids) > 0: for gid in gids[0:-1]: query += " id_usergroup=" + str(int(gid)) + " OR" query += " id_usergroup=" + str(int(gids[-1])) return map(get_element, run_sql(query)) return [] def create_message(uid_from, users_to_str="", groups_to_str="", msg_subject="", msg_body="", msg_send_on_date="0000-00-00 00:00:00"): """ Creates a message in the msgMESSAGE table. Does NOT send the message. This function is like a datagramPacket... @param uid_from: uid of the sender (int) @param users_to_str: a string, with nicknames separated by semicolons (';') @param groups_to_str: a string with groupnames separated by semicolons @param msg_subject: string containing the subject of the message @param msg_body: string containing the body of the message @param msg_send_on_date: date on which message must be sent. Has to be a mySQL format (i.e. YYYY-mm-dd HH:MM:SS) @return id of the created message """ now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) query = """INSERT INTO msgMESSAGE(id_user_from, sent_to_user_nicks, sent_to_group_names, subject, body, sent_date, received_date) VALUES(%i,'%s','%s','%s','%s','%s','%s')""" params = (int(uid_from), escape_string(users_to_str), escape_string(groups_to_str), escape_string(msg_subject), escape_string(msg_body), escape_string(now), escape_string(msg_send_on_date)) msg_id = run_sql(query%params) return int(msg_id) def send_message(uids_to, msgid, status=cfg_webmessage_status_code['NEW']): """ Send message to uids @param uids: sequence of user ids @param msg_id: id of message @param status: status of the message. (single char, see webmessage_config.py). @return a list of users having their mailbox full """ if not((type(uids_to) is list) or (type(uids_to) is tuple)): uids_to = [uids_to] user_problem = [] if len(uids_to) > 0: users_quotas = check_quota(cfg_webmessage_max_nb_of_messages - 1) query = """INSERT INTO user_msgMESSAGE (id_user_to, id_msgMESSAGE, status) VALUES """ fixed_value = ",%i,'%s')" % (int(msgid), status) def not_users_quotas_has_key(key): """ not(is key in users over quota?)""" return not(users_quotas.has_key(key)) user_ids_to = filter(not_users_quotas_has_key, uids_to) user_problem = filter(users_quotas.has_key, uids_to) if len(user_ids_to) > 0: for uid_to in user_ids_to[0:-1]: query += "(%i%s," % (int(uid_to), fixed_value) query += "(%i%s" % (int(user_ids_to[-1]), fixed_value) run_sql(query) return user_problem def check_quota(nb_messages): """ @param nb_messages: max number of messages a user can have @return a dictionary of users over-quota """ where = '' no_quota_users = list_users_in_roles(cfg_webmessage_roles_without_quota) if len(no_quota_users) > 0: where = """WHERE """ for uid in no_quota_users[:-1]: where += "id_user_to!=%i AND " % uid where += "id_user_to!=%i" % no_quota_users[-1] query = """SELECT id_user_to, count(id_user_to) FROM user_msgMESSAGE %s GROUP BY id_user_to HAVING count(id_user_to)>%i""" res = run_sql(query % (where, int(nb_messages))) user_over_quota = {} def enter_dict(couple): """ enter a tuple in user_over_quota dict """ user_over_quota[int(couple[0])] = int(couple[1]) map(enter_dict, res) return user_over_quota def update_user_inbox_for_reminders(uid): """ Updates user's inbox with any reminders that should have arrived @param uid: user id @return integer number of new expired reminders """ now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) reminder_status = cfg_webmessage_status_code['REMINDER'] new_status = cfg_webmessage_status_code['NEW'] query1 = """SELECT m.id FROM msgMESSAGE m, user_msgMESSAGE um WHERE um.id_user_to=%(uid)i AND um.id_msgMESSAGE=m.id AND m.received_date <= '%(date)s' AND um.status like binary '%(old_status)s' """ params1 = {'uid': int(uid), 'date': now, 'old_status': reminder_status } res_ids = run_sql(query1%params1) out = len(res_ids) if (out>0): query2 = """UPDATE user_msgMESSAGE SET status='%(new_status)s' WHERE id_user_to=%(uid)i AND (""" for msg_id in res_ids[0:-1]: query2 += "id_msgMESSAGE=" + str(int(msg_id[0])) + " OR " params2 = {'uid': int(uid), 'new_status': new_status, } query2 += "id_msgMESSAGE=" + str(int(res_ids[-1][0])) + ")" run_sql(query2%params2) return out def get_nicknames_like(pattern): """get nicknames like pattern""" query = "SELECT nickname FROM user WHERE nickname RLIKE '%s'" pattern = escape_string(pattern) res = run_sql(query%pattern) return res def get_groupnames_like(pattern): """Get groupnames like pattern""" query = "SELECT name FROM usergroup WHERE name RLIKE '%s'" pattern = escape_string(pattern) res = run_sql(query%pattern) return res def get_element(sql_res): """convert mySQL output @param x: a tuple like this: (6789L,) @return integer conversion of the number in tuple """ return int(sql_res[0]) def clean_messages(): """ Cleans msgMESSAGE table""" current_time = time.localtime() seconds = time.mktime(current_time) seconds -= cfg_webmessage_days_before_delete_orphans * 86400 format = "%Y-%m-%d %H:%M:%S" sql_date = time.strftime(format, time.localtime(seconds)) deleted_items = 0 #find id and email from every user who has got an email query1 = """SELECT distinct(umsg.id_user_to), user.email FROM user_msgMESSAGE umsg LEFT JOIN user ON umsg.id_user_to=user.id""" res1 = run_sql(query1) # if there is no email, user has disappeared users_deleted = map(lambda u: int(u[0]), filter(lambda x: x[1] == None, res1)) # find ids from messages in user's inbox query2 = """SELECT distinct(umsg.id_msgMESSAGE), msg.id FROM user_msgMESSAGE umsg LEFT JOIN msgMESSAGE msg ON umsg.id_msgMESSAGE=msg.id""" res2 = run_sql(query2) # if there is no id, message was deleted from table msgMESSAGE... messages_deleted = map(lambda u: int(u[0]), filter(lambda x: x[1] == None, res2)) def tuplize(el1, el2): return str(el1) + ',' + str(el2) if len(users_deleted) or len(messages_deleted): # Suppress every referential error from user_msgMESSAGE query3 = "DELETE FROM user_msgMESSAGE WHERE " if len(users_deleted): query3 += "id_user_to IN (%s)" % reduce(tuplize, users_deleted) if len(messages_deleted): query3 += ' OR ' if len(messages_deleted): query3 += "id_msgMESSAGE IN (%s)" % reduce(tuplize, messages_deleted) deleted_items = int(run_sql(query3)) # find every message that is nobody's inbox query4 = """SELECT msg.id FROM msgMESSAGE msg LEFT JOIN user_msgMESSAGE umsg ON msg.id=umsg.id_msgMESSAGE WHERE msg.sent_date<'%s' GROUP BY umsg.id_msgMESSAGE HAVING count(umsg.id_msgMESSAGE)=0 """ res4 = map(lambda x: x[0], run_sql(query4% sql_date)) if len(res4): # delete these messages query5 = "DELETE FROM msgMESSAGE WHERE " query5 += "id IN (%s)" % reduce(tuplize, res4) deleted_items += int(run_sql(query5)) return deleted_items diff --git a/modules/webmessage/lib/webmessage_templates.py b/modules/webmessage/lib/webmessage_templates.py index 70fcb11f6..67e85f067 100644 --- a/modules/webmessage/lib/webmessage_templates.py +++ b/modules/webmessage/lib/webmessage_templates.py @@ -1,630 +1,630 @@ # -*- coding: utf-8 -*- ## $Id$ ## ## handles rendering of webmessage module ## ## This file is part of the CERN Document Server Software (CDSware). ## Copyright (C) 2002, 2003, 2004, 2005 CERN. ## ## The CDSware is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## The CDSware is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with CDSware; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. # CDS imports from cdsware.webmessage_mailutils import email_quoted_txt2html, email_quote_txt from cdsware.webmessage_config import cfg_webmessage_status_code, \ cfg_webmessage_separator, \ cfg_webmessage_max_nb_of_messages from cdsware.textutils import indent_text -from cdsware.dateutils import date_convert_MySQL_to_text, \ +from cdsware.dateutils import get_i18n_dbdatetext, \ create_day_selectbox, \ create_month_selectbox, \ - create_year_inputbox + create_year_selectbox from cdsware.config import weburl, cdslang from cdsware.messages import gettext_set_language class Template: def tmpl_display_inbox(self, messages, infos=[], warnings=[], nb_messages=0, ln=cdslang): """ Displays a list of messages, with the appropriate links and buttons @param messages: a list of tuples: [(message_id, user_from_id, user_from_nickname, subject, sent_date, status=] @param infos: a list of informations to print on top of page @param ln: language of the page. @return the list in HTML format """ _ = gettext_set_language(ln) junk = 0 inbox = self.tmpl_warning(warnings, ln) inbox += self.tmpl_infobox(infos, ln) inbox += self.tmpl_quota(nb_messages, ln) inbox += """ """ %(_("Subject"), _("Sender"), _("Date")) if len(messages) == 0: inbox += """ """ %(_("No new mail"),) for (msgid, junk, user_from_nick, subject, sent_date, status) in messages: subject_link = '%s'% (msgid, ln, subject) from_link = '%s'% (user_from_nick, ln, user_from_nick) action_link = '%s'% (msgid, ln, _("Delete")) - s_date = date_convert_MySQL_to_text(sent_date, ln) + s_date = get_i18n_dbdatetext(sent_date, ln) stat_style = '' if (status == cfg_webmessage_status_code['NEW']): stat_style = ' style="font-weight:bold"' inbox += """ %s """ %(stat_style, subject_link, from_link, s_date, action_link) inbox += """
%s %s %s  
%s
%s %s %s
 
""" % {'ln': ln, 'write_label': _("New message"), 'delete_all_label': _("Delete All")} return indent_text(inbox, 2) def tmpl_write(self, msg_to="", msg_to_group="", msg_id=0, msg_subject="", msg_body="", msg_send_year=0, msg_send_month=0, msg_send_day=0, warnings=[], users_to_add=[], groups_to_add=[], user_search_pattern="", group_search_pattern="", display_users_to_add=1, ln=cdslang): """ Displays a writing message form with optional prefilled fields @param msg_to: nick of the user (prefills the To: field) @param msg_subject: subject of the message (prefills the Subject: field) @param msg_body: body of the message (prefills the Message: field) @param msg_send_year: prefills to year field @param msg_send_month: prefills the month field @param msg_send_day: prefills the day field @param warnings: display warnings on top of page @param users_to_add: list to select users @param groups_to_add: list to select groups @param user_search_pattern: prefills this field! @param group_search_pattern: idem @param display_users_to_add: 1: display user search box, 0: group... @param ln: language of the form @return the form in HTML format """ _ = gettext_set_language(ln) write_box = self.tmpl_warning(warnings) # escape forbidden character msg_to = msg_to.replace('"', '"') msg_to_group = msg_to_group.replace('"', '"') msg_subject = msg_subject.replace('"', '"') user_search_pattern = user_search_pattern.replace('"','"') group_search_pattern = group_search_pattern.replace('"','"') if display_users_to_add: to_select = self.tmpl_user_or_group_search(users_to_add, user_search_pattern, 1, ln) else: to_select = self.tmpl_user_or_group_search(groups_to_add, group_search_pattern, 0, ln) if (msg_id != 0): msg_subject = _("Re: ") + msg_subject msg_body = email_quote_txt(msg_body) msg_body = msg_body.replace('>', '>') write_box += """
""" search_field_name = "user_search_pattern" search_button_name = "search_user_button" multiple_select = self.tmpl_multiple_select('users_to_add', tuples_list) add_button = "" add_button = add_button % _("Add to users") else: header = """ """ search_field_name = "group_search_pattern" search_button_name = "search_group_button" multiple_select = self.tmpl_multiple_select('groups_to_add', tuples_list) add_button = "" add_button = add_button % _("Add to groups") out = "
%(to_label)s %(users_label)s
  %(groups_label)s
     
%(subject_label)s
%(message_label)s "+ write_box_part2 day_field = create_day_selectbox('msg_send_day', msg_send_day, ln) month_field = create_month_selectbox('msg_send_month', msg_send_month, ln) - year_field = create_year_inputbox('msg_send_year', msg_send_year) + year_field = create_year_selectbox('msg_send_year', -1, 10, msg_send_year, ln) write_box = write_box % {'to_users' : msg_to, 'to_groups': msg_to_group, 'subject' : msg_subject, 'body' : msg_body, 'ln': ln, 'day_field': day_field, 'month_field': month_field, 'year_field': year_field, 'to_select': to_select, 'send_later_label': _("Send Later:"), 'to_label': _("To:"), 'users_label': _("Users"), 'groups_label': _("Groups"), 'subject_label': _("Subject:"), 'message_label': _("Message:"), 'send_label': _("SEND")} return write_box def tmpl_display_msg(self, msg_id="", msg_from_id="", msg_from_nickname="", msg_sent_to="", msg_sent_to_group="", msg_subject="", msg_body="", msg_sent_date="", msg_received_date="0000-00-00 00:00:00", ln=cdslang): """ Displays a given message @param msg_id: id of the message @param msg_from_id: id of user who sent the message @param msg_from_nickname: nickname of the user who sent the message @param msg_sent_to: list of users who received the message (comma separated string) @param msg_sent_to_group: list of groups who received the message (comma separated string) @param msg_subject: subject of the message @param msg_body: body of the message @param msg_sent_date: date at which the message was sent @param msg_received_date: date at which the message had to be received (if this argument != 0000-00-00 => reminder @param ln: language of the page @return the message in HTML format """ # load the right message language _ = gettext_set_language(ln) sent_to_link = "" tos = msg_sent_to.split(cfg_webmessage_separator) if (tos): for to in tos[0:-1]: sent_to_link += ''% (to, ln) sent_to_link += '%s%s '% (to, cfg_webmessage_separator) sent_to_link += '%s'% (tos[-1], ln, tos[-1]) group_to_link = "" groups = msg_sent_to_group.split(cfg_webmessage_separator) if (groups): for group in groups[0:-1]: group_to_link += ''% (group, ln) group_to_link += '%s%s '% (group, cfg_webmessage_separator) group_to_link += '%s'% (groups[-1], ln, groups[-1]) # format the msg so that the '>>' chars give vertical lines final_body = email_quoted_txt2html(msg_body) out = """ """ if (msg_received_date != '0000-00-00 00:00:00'): out += """ """ out += """ """ if (msg_sent_to_group != ""): out += """ """ out += """
From: %(from)s
Subject: %(subject)s
Sent: %(sent_date)s
Received: %(received_date)s
CC: %(sent_to)s
Groups: %(sent_to_group)s
%(body)s
""" out = out % {'from' : msg_from_nickname, - 'sent_date' : date_convert_MySQL_to_text(msg_sent_date, ln), - 'received_date': date_convert_MySQL_to_text(msg_received_date, ln), + 'sent_date' : get_i18n_dbdatetext(msg_sent_date, ln), + 'received_date': get_i18n_dbdatetext(msg_received_date, ln), 'sent_to': sent_to_link, 'sent_to_group': group_to_link, 'subject' : msg_subject, 'body' : final_body, 'reply_to': msg_from_id, 'msg_id': msg_id, 'ln': ln, 'reply_txt':_("REPLY"), 'delete_txt': _("DELETE")} return indent_text(out, 2) def tmpl_navtrail(self, ln=cdslang, title=""): """ display the navtrail, e.g.: Your account > Your messages > title @param title: the last part of the navtrail. Is not a link @param ln: language return html formatted navtrail """ _ = gettext_set_language(ln) nav_h1 = '%s' nav_h2 = "" if (title != ""): nav_h2 = ' > %s' nav_h2 = nav_h2 % (weburl, _("Your Messages")) return nav_h1% (weburl,_("Your Account")) + nav_h2 def tmpl_confirm_delete(self, ln=cdslang): """ display a confirm message @param ln: language @return html output """ _ = gettext_set_language(ln) out = """
%(message)s
"""% {'message': _("Are your sure you want to empty your whole mailbox?"), 'ln':ln, 'yes_label': _("Yes"), 'no_label': _("No")} return indent_text(out, 2) def tmpl_infobox(self, infos, ln=cdslang): """Display len(infos) information fields @param infos: list of strings @param ln=language @return html output """ _ = gettext_set_language(ln) if not((type(infos) is list) or (type(infos) is tuple)): infos = [infos] infobox = "" for info in infos: infobox += "
" lines = info.split("\n") for line in lines[0:-1]: infobox += line + "
\n" infobox += lines[-1] + "

\n" return infobox def tmpl_warning(self, warnings, ln=cdslang): """ Display len(warnings) warning fields @param infos: list of strings @param ln=language @return html output """ if not((type(warnings) is list) or (type(warnings) is tuple)): warnings = [warnings] warningbox = "" if warnings != []: warningbox = "
\n Warning:\n" for warning in warnings: lines = warning.split("\n") warningbox += "

" for line in lines[0:-1]: warningbox += line + "
\n" warningbox += lines[-1] + "

" warningbox += "

\n" return warningbox def tmpl_quota(self, nb_messages=0, ln=cdslang): """ Display a quota bar. @nb_messages: number of messages in inbox. @ln=language @return html output """ _ = gettext_set_language(ln) quota = float(cfg_webmessage_max_nb_of_messages) ratio = float(nb_messages) / quota out = """ %(quota_label)s
""" %{'quota_label' : _("Quota: %.1f%%")%(ratio * 100.0), 'width' : int(ratio * 200) } return out def tmpl_multiple_select(self, select_name, tuples_list, ln=cdslang): """displays a multiple select environment @param tuples_list: a list of (value, isSelected) tuples @return HTML output """ _ = gettext_set_language(ln) if not((type(tuples_list) is list) or (type(tuples_list) is tuple)): tuples_list = [tuples_list] out = """
%(search_user_label)s
%(search_group_label)s
\n" + header out += """
%(multiple_select)s %(add_button)s
""" out = out% {'search_user_label' : _("Find a user"), 'search_group_label' : _("Find a group"), 'search_button_label': _("Search"), 'search_field_name' : search_field_name, 'search_pattern' : search_pattern, 'search_button_name' : search_button_name, 'multiple_select' : multiple_select, 'add_button' : add_button} return out def tmpl_account_new_mail(self, nb_new_mail=0, ln=cdslang): """ display infos about inbox (used by myaccount.py) @param nb_new_mail: number of new mails @param ln: language retourn: html output. """ _ = gettext_set_language(ln) out = _("You got %i new messages.
\n")% nb_new_mail out += _("You can see all your messages in your inbox")% ln return out