Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F93583013
webmessage_query.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Nov 29, 22:26
Size
21 KB
Mime Type
text/x-python
Expires
Sun, Dec 1, 22:26 (2 d)
Engine
blob
Format
Raw Data
Handle
22670246
Attached To
R3600 invenio-infoscience
webmessage_query.py
View Options
# -*- coding: utf-8 -*-
##
## This file is part of Invenio.
## Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 CERN.
##
## Invenio 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.
##
## Invenio 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 Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Query definitions for module webmessage"""
from
time
import
localtime
,
mktime
from
datetime
import
datetime
from
invenio.config
import
\
CFG_WEBMESSAGE_MAX_NB_OF_MESSAGES
,
\
CFG_WEBMESSAGE_DAYS_BEFORE_DELETE_ORPHANS
from
invenio.dbquery
import
run_sql
,
OperationalError
from
invenio.webmessage_config
import
CFG_WEBMESSAGE_STATUS_CODE
,
\
CFG_WEBMESSAGE_ROLES_WITHOUT_QUOTA
from
invenio.dateutils
import
datetext_default
,
\
convert_datestruct_to_datetext
from
invenio.websession_config
import
CFG_WEBSESSION_USERGROUP_STATUS
from
invenio.sqlalchemyutils
import
db
from
invenio.webmessage_model
import
MsgMESSAGE
,
UserMsgMESSAGE
from
invenio.websession_model
import
User
def
filter_messages_from_user_with_status
(
uid
,
status
):
"""
Filter message from user with status code.
@param uid: user id
@return: sqlalchemy.sql.expression.ClauseElement
"""
# AsBINARY removed!!!
return
(
UserMsgMESSAGE
.
status
.
__eq__
(
status
))
&
\
(
UserMsgMESSAGE
.
id_user_to
==
uid
)
def
filter_all_messages_from_user
(
uid
):
"""
Filter all message from user with status code not 'reminder'.
@param uid: user id
@return: sqlalchemy.sql.expression.ClauseElement
"""
reminder
=
CFG_WEBMESSAGE_STATUS_CODE
[
'REMINDER'
]
return
db
.
not_
(
UserMsgMESSAGE
.
status
.
__eq__
(
reminder
))
&
\
(
UserMsgMESSAGE
.
id_user_to
==
uid
)
#return db.not_(db.AsBINARY(UserMsgMESSAGE.status.__eq__(reminder))) & \
# (UserMsgMESSAGE.id_user_to == uid)
def
filter_user_message
(
uid
,
msgid
):
"""
Filter message from user with defined id(s).
@param uid: user id
@param msgid: message id(s)
@return: sqlalchemy.sql.expression.ClauseElement
"""
try
:
iter
(
msgid
)
return
(
UserMsgMESSAGE
.
id_user_to
==
uid
)
&
\
(
UserMsgMESSAGE
.
id_msgMESSAGE
.
in_
(
msgid
))
except
:
return
(
UserMsgMESSAGE
.
id_user_to
==
uid
)
&
\
(
UserMsgMESSAGE
.
id_msgMESSAGE
==
msgid
)
def
check_user_owns_message
(
uid
,
msgid
):
"""
Checks whether a user owns a message
@param uid: user id
@param msgid: message id
@return: number of messages own by user
"""
return
db
.
session
.
query
(
db
.
func
.
count
(
'*'
))
.
\
select_from
(
UserMsgMESSAGE
)
.
\
filter
(
filter_user_message
(
uid
,
msgid
))
.
scalar
()
def
get_message
(
uid
,
msgid
):
"""
Get a message with its status and sender nickname.
@param uid: user id
@param msgid: message id
@return: exactly one message or raise an exception.
"""
return
UserMsgMESSAGE
.
query
.
options
(
\
db
.
joinedload_all
(
UserMsgMESSAGE
.
message
,
MsgMESSAGE
.
user_from
))
.
\
options
(
db
.
joinedload
(
UserMsgMESSAGE
.
user_to
))
.
\
filter
(
filter_user_message
(
uid
,
msgid
))
.
one
()
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
"""
return
db
.
session
.
query
(
UserMsgMESSAGE
)
.
\
filter
(
filter_user_message
(
uid
,
msgid
))
.
\
update
({
UserMsgMESSAGE
.
status
:
new_status
})
def
get_nb_new_messages_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'
]
return
db
.
session
.
query
(
db
.
func
.
count
(
UserMsgMESSAGE
.
id_msgMESSAGE
))
.
\
select_from
(
UserMsgMESSSAGE
)
.
\
filter
(
filter_messages_from_user_with_status
(
uid
,
new_status
))
.
\
scalar
()
def
get_nb_readable_messages_for_user
(
uid
):
""" Get number of mails of a fiven user. Reminders are not counted
@param uid: user id (int)
@return: number of messages (int)
"""
return
db
.
session
.
query
(
db
.
func
.
count
(
UserMsgMESSAGE
.
id_msgMESSAGE
))
.
\
select_from
(
UserMsgMESSAGE
)
.
\
filter
(
filter_all_messages_from_user
(
uid
))
.
\
scalar
()
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
)
return
MsgMESSAGE
.
query
.
options
(
db
.
joinedload
(
MsgMESSAGE
.
user_from
))
.
\
join
(
UserMsgMESSAGE
)
.
\
filter
(
filter_all_messages_from_user
(
uid
))
.
\
order_by
(
MsgMESSAGE
.
sent_date
)
.
all
()
def
count_nb_messages
(
uid
):
"""
@param uid: user id
@return: integer of number of messages a user has, 0 if none
"""
uid
=
int
(
uid
)
return
db
.
session
.
query
(
db
.
func
.
count
(
UserMsgMESSAGE
.
id_user_to
))
.
\
select_from
(
UserMsgMESSAGE
)
.
\
filter
(
UserMsgMESSAGE
.
id_user_to
==
uid
)
.
\
scalar
()
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
"""
res
=
UserMsgMESSAGE
.
query
.
filter
(
filter_user_message
(
uid
,
msg_id
))
.
\
delete
(
synchronize_session
=
False
)
check_if_need_to_delete_message_permanently
(
msg_id
)
return
res
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
]
msg_used
=
db
.
session
.
query
(
UserMsgMESSAGE
.
id_msgMESSAGE
)
.
\
filter
(
UserMsgMESSAGE
.
id_msgMESSAGE
.
in_
(
msg_ids
))
.
\
group_by
(
UserMsgMESSAGE
.
id_msgMESSAGE
)
.
\
having
(
db
.
func
.
count
(
UserMsgMESSAGE
.
id_user_to
)
>
0
)
.
\
subquery
()
return
MsgMESSAGE
.
query
.
filter
(
MsgMESSAGE
.
id
.
in_
(
msg_ids
)
&
\
db
.
not_
(
MsgMESSAGE
.
id
.
in_
(
msg_used
)))
.
\
delete
(
synchronize_session
=
False
)
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'
]
msg_ids
=
map
(
lambda
(
x
,
):
x
,
db
.
session
.
query
(
UserMsgMESSAGE
.
id_msgMESSAGE
)
.
\
filter
(
UserMsgMESSAGE
.
id_user_to
==
uid
&
\
UserMsgMESSAGE
.
status
!=
reminder_status
)
.
all
())
nb_messages
=
UserMsgMESSAGE
.
query
.
\
filter
(
UserMsgMESSAGE
.
id_user_to
==
uid
&
\
UserMsgMESSAGE
.
status
!=
reminder_status
)
.
\
delete
(
synchronize_session
=
False
)
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}
"""
# FIXME: test case
if
not
((
type
(
nicks
)
is
list
)
or
(
type
(
nicks
)
is
tuple
)):
nicks
=
[
nicks
]
users
=
{}
query
=
"SELECT nickname, id FROM user WHERE BINARY nickname IN ("
query_params
=
()
if
len
(
nicks
)
>
0
:
for
nick
in
nicks
:
users
[
nick
]
=
None
users_keys
=
users
.
keys
()
for
nick
in
users_keys
[
0
:
-
1
]:
query
+=
"
%s
,"
query_params
+=
(
nick
,)
query
+=
"
%s
)"
query_params
+=
(
users_keys
[
-
1
],)
res
=
run_sql
(
query
,
query_params
)
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("
query_params
=
[]
if
len
(
uids
)
>
0
:
for
uid
in
uids
:
users
[
uid
]
=
None
for
uid
in
users
.
keys
()[
0
:
-
1
]:
query
+=
"
%s
,"
query_params
.
append
(
uid
)
query
+=
"
%s
)"
query_params
.
append
(
users
.
keys
()[
-
1
])
res
=
run_sql
(
query
,
tuple
(
query_params
))
for
(
user_id
,
nickname
)
in
res
:
users
[
int
(
user_id
)]
=
nickname
return
users
def
get_uids_from_emails
(
emails
):
"""
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}
"""
# FIXME: test case
if
not
((
type
(
emails
)
is
list
)
or
(
type
(
emails
)
is
tuple
)):
emails
=
[
emails
]
users
=
{}
query
=
"SELECT email, id FROM user WHERE BINARY email IN ("
query_params
=
()
if
len
(
emails
)
>
0
:
for
mail
in
emails
:
users
[
mail
]
=
None
users_keys
=
users
.
keys
()
for
mail
in
users_keys
[
0
:
-
1
]:
query
+=
"
%s
,"
query_params
+=
(
mail
,)
query
+=
"
%s
)"
query_params
+=
(
users_keys
[
-
1
],)
res
=
run_sql
(
query
,
query_params
)
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_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}
"""
# FIXME: test case
if
not
((
type
(
groupnames
)
is
list
)
or
(
type
(
groupnames
)
is
tuple
)):
groupnames
=
[
groupnames
]
groups
=
{}
query
=
"SELECT name, id FROM usergroup WHERE BINARY name IN ("
query_params
=
()
if
len
(
groupnames
)
>
0
:
for
groupname
in
groupnames
:
groups
[
groupname
]
=
None
groups_keys
=
groups
.
keys
()
for
groupname
in
groups_keys
[
0
:
-
1
]:
query
+=
"
%s
,"
query_params
+=
(
groupname
,)
query
+=
"
%s
)"
query_params
+=
(
groups_keys
[
-
1
],)
res
=
run_sql
(
query
,
query_params
)
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 user_status!=%s AND (
"""
query_params
=
[
CFG_WEBSESSION_USERGROUP_STATUS
[
'PENDING'
]]
if
len
(
gids
)
>
0
:
for
gid
in
gids
[
0
:
-
1
]:
query
+=
" id_usergroup=
%s
OR"
query_params
.
append
(
gid
)
query
+=
" id_usergroup=
%s
)"
query_params
.
append
(
gids
[
-
1
])
return
map
(
get_element
,
run_sql
(
query
,
tuple
(
query_params
)))
return
[]
def
user_exists
(
uid
):
""" checks if a user exists in the system, given his uid. return 0 or 1"""
query
=
"SELECT count(id) FROM user WHERE id=
%s
GROUP BY id"
res
=
run_sql
(
query
,
(
uid
,
))
if
res
:
return
int
(
res
[
0
][
0
])
return
0
def
create_message
(
uid_from
,
users_to_str
=
""
,
groups_to_str
=
""
,
msg_subject
=
""
,
msg_body
=
""
,
msg_send_on_date
=
datetext_default
):
"""
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
datetex format (i.e. YYYY-mm-dd HH:MM:SS)
@return: id of the created message
"""
now
=
convert_datestruct_to_datetext
(
localtime
())
msg_id
=
run_sql
(
"""INSERT INTO msgMESSAGE(id_user_from,
sent_to_user_nicks,
sent_to_group_names,
subject,
body,
sent_date,
received_date)
VALUES (%s,%s,%s,%s,%s,%s,%s)"""
,
(
uid_from
,
users_to_str
,
groups_to_str
,
msg_subject
,
msg_body
,
now
,
msg_send_on_date
))
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
=
",
%s
,
%s
)"
query_params
=
[]
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
+=
"(
%%
s
%s
,"
%
fixed_value
query_params
+=
[
uid_to
,
msgid
,
status
]
query
+=
"(
%%
s
%s
"
%
fixed_value
query_params
+=
[
user_ids_to
[
-
1
],
msgid
,
status
]
run_sql
(
query
,
tuple
(
query_params
))
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
"""
from
invenio.webuser
import
collect_user_info
from
invenio.access_control_admin
import
acc_is_user_in_role
,
acc_get_role_id
no_quota_role_ids
=
[
acc_get_role_id
(
role
)
for
role
in
CFG_WEBMESSAGE_ROLES_WITHOUT_QUOTA
]
res
=
{}
for
uid
,
n
in
run_sql
(
"SELECT id_user_to, COUNT(id_user_to) FROM user_msgMESSAGE GROUP BY id_user_to HAVING COUNT(id_user_to) >
%s
"
,
(
nb_messages
,
)):
user_info
=
collect_user_info
(
uid
)
for
role_id
in
no_quota_role_ids
:
if
acc_is_user_in_role
(
user_info
,
role_id
):
break
else
:
res
[
uid
]
=
n
return
res
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
=
convert_datestruct_to_datetext
(
localtime
())
reminder_status
=
CFG_WEBMESSAGE_STATUS_CODE
[
'REMINDER'
]
new_status
=
CFG_WEBMESSAGE_STATUS_CODE
[
'NEW'
]
expired_reminders
=
db
.
session
.
query
(
UserMsgMESSAGE
.
id_msgMESSAGE
)
.
\
join
(
UserMsgMESSAGE
.
message
)
.
\
filter
(
db
.
and_
(
UserMsgMESSAGE
.
id_user_to
==
uid
,
UserMsgMESSAGE
.
status
.
like
(
reminder_status
),
MsgMESSAGE
.
received_date
<=
datetime
.
now
()
#MsgMESSAGE.received_date<=db.func.current_timestamp()
))
.
all
()
print
expired_reminders
res
=
UserMsgMESSAGE
.
query
.
filter
(
db
.
and_
(
UserMsgMESSAGE
.
id_user_to
==
uid
,
UserMsgMESSAGE
.
id_msgMESSAGE
.
in_
([
i
for
i
,
in
expired_reminders
])))
.
\
update
({
UserMsgMESSAGE
.
status
:
new_status
},
synchronize_session
=
'fetch'
)
return
res
def
get_nicknames_like
(
pattern
):
"""get nicknames like pattern"""
if
pattern
:
try
:
res
=
run_sql
(
"SELECT nickname FROM user WHERE nickname RLIKE
%s
"
,
(
pattern
,))
except
OperationalError
:
res
=
()
return
res
return
()
def
get_groupnames_like
(
uid
,
pattern
):
"""Get groupnames like pattern. Will return only groups that user is allowed to see
"""
groups
=
{}
if
pattern
:
# For this use case external groups are like invisible one
query1
=
"SELECT id, name FROM usergroup WHERE name RLIKE
%s
AND join_policy like 'V
%%
' AND join_policy<>'VE'"
try
:
res
=
run_sql
(
query1
,
(
pattern
,))
except
OperationalError
:
res
=
()
# The line belows inserts into groups dictionary every tuple the database returned,
# assuming field0=key and field1=value
map
(
lambda
x
:
groups
.
setdefault
(
x
[
0
],
x
[
1
]),
res
)
query2
=
"""SELECT g.id, g.name
FROM usergroup g, user_usergroup ug
WHERE g.id=ug.id_usergroup AND ug.id_user=%s AND g.name RLIKE %s"""
try
:
res
=
run_sql
(
query2
,
(
uid
,
pattern
))
except
OperationalError
:
res
=
()
map
(
lambda
x
:
groups
.
setdefault
(
x
[
0
],
x
[
1
]),
res
)
return
groups
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
=
localtime
()
seconds
=
mktime
(
current_time
)
seconds
-=
CFG_WEBMESSAGE_DAYS_BEFORE_DELETE_ORPHANS
*
86400
sql_date
=
convert_datestruct_to_datetext
(
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
]
is
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
]
is
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 "
query_params
=
[]
if
len
(
users_deleted
):
query3
+=
"id_user_to IN (
%s
)"
query_params
.
append
(
reduce
(
tuplize
,
users_deleted
))
if
len
(
messages_deleted
):
query3
+=
' OR '
if
len
(
messages_deleted
):
query3
+=
"id_msgMESSAGE IN (
%s
)"
query_params
.
append
(
reduce
(
tuplize
,
messages_deleted
))
deleted_items
=
int
(
run_sql
(
query3
,
tuple
(
query_params
)))
# 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
)"
deleted_items
+=
int
(
run_sql
(
query5
,
(
reduce
(
tuplize
,
res4
),
)))
return
deleted_items
Event Timeline
Log In to Comment