<commit_before># -*- coding: utf-8 -*-
## $Id$
##
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## CDS 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.
##
## CDS 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 CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

""" Database related functions for webbasket module """

from zlib import decompress
from time import localtime

from invenio.dbquery import run_sql, escape_string
from invenio.webbasket_config import cfg_webbasket_share_levels, \
                                     cfg_webbasket_actions, \
                                     cfg_webbasket_share_levels_ordered
from invenio.dateutils import convert_datestruct_to_datetext
from invenio.websession_config import cfg_websession_usergroup_status

########################### Table of contents ################################
#
# NB. functions preceeded by a star use usergroup table
#
# 1. General functions
#    - count_baskets
#    - check_user_owns_basket
#    - get_max_user_rights_on_basket
#
# 2. Personal baskets
#    - get_personal_baskets_infos
#    - get_all_personal_baskets_names
#    - get_basket_name
#    - get_personal_topics_infos
#    - rename_basket
#    - rename_topic
#    - move_baskets_to_topic
#    - delete_basket
#    - create_basket
#
# 3. Actions on baskets
#    - get_basket_record
#    - share_basket_with_group
#    - update_rights
#    - move_item
#    - delete_item
#    - add_to_basket
#    - get_basket_content
#
# 4. Group baskets
#    - get_group_basket_infos
#    - (*) get_all_group_baskets_names
#    - is_shared_to
#
# 5. External baskets (baskets user has subscribed to)
#    - get_external_baskets_infos
#    - count_external_baskets
#    - get_all_external_baskets_names
#
# 6. Public baskets (interface to subscribe to baskets)
#    - get_public_basket_infos
#    - get_basket_general_infos
#    - count_public_baskets
#    - get_public_baskets_list
#    - subscribe
#    - unsubscribe
#    - count_subscribers
#    - (*) get_groups_subscribing_to_basket
# 
# 7. Commenting
#    - get_comments
#    - get_comment
#    - save_comment
#    - delete_comment
#
# 8. Usergroup functions
#    - (*) get_group_infos
#    - count_groups_user_member_of
#    - (*) get_groups_user_member_of
#
# 9. Useful functions
#    - __wash_count
#    - __decompress_last
#
########################## General functions ##################################

def count_baskets(uid):
    """Return (nb personal baskets, nb group baskets, nb external
    baskets) tuple for given user"""
    query1 = "SELECT COUNT(id) FROM bskBASKET WHERE id_owner=%i"
    res1 = run_sql(query1 % int(uid))
    personal = __wash_count(res1)
    query2 = """SELECT count(ugbsk.id_bskbasket) 
                FROM usergroup_bskBASKET ugbsk LEFT JOIN user_usergroup uug 
                                               ON ugbsk.id_usergroup=uug.id_usergroup
                WHERE uug.id_user=%i AND uug.user_status!='%s'
                GROUP BY ugbsk.id_usergroup"""
    params = (int(uid), cfg_websession_usergroup_status['PENDING'])
    res2 = run_sql(query2 % params)
    if len(res2):
        groups = reduce(lambda x, y: x + y, map(lambda x: x[0], res2))
    else:
        groups = 0
    external = count_external_baskets(uid)
    return (personal, groups, external)

def check_user_owns_baskets(uid, bskids):
    """ Return 1 if user is owner of every basket in list bskids"""
    if not((type(bskids) is list) or (type(bskids) is tuple)):
        bskids = [bskids]
    query = """SELECT id_owner FROM bskBASKET WHERE %s GROUP BY id_owner"""
    sep = ' OR '
    query %= sep.join(map(lambda x: 'id=%i'% int(x), bskids))
    res = run_sql(query)
    if len(res)==1 and int(res[0][0])==uid:
        return 1
    else:
        return 0

def get_max_user_rights_on_basket(uid, bskid):
    """Return the max rights a user has on this basket"""
    query_owner = "SELECT count(id_owner) FROM bskBASKET WHERE id_owner=%i and id=%i"
    params_owner = (int(uid), int(bskid))
    res = run_sql(query_owner % params_owner)
    if res and res[0][0]:
        # if this user is owner of this baskets he can do anything he wants.
        return cfg_webbasket_share_levels['MANAGE']
    # not owner => group member ?
    query_group_baskets = """
    SELECT share_level
    FROM user_usergroup AS ug LEFT JOIN usergroup_bskBASKET AS ub
                              ON ug.id_usergroup=ub.id_usergroup
    WHERE ug.id_user=%i AND ub.id_bskBASKET=%i AND NOT(ub.share_level='NO') AND ug.user_status!='%s'
    """
    max_rights_index = None
    params_group_baskets = (uid, bskid, cfg_websession_usergroup_status['PENDING'])
    res = run_sql(query_group_baskets % params_group_baskets)
    if res:
        group_rights = res[0][0]
        try:
            max_rights_index = cfg_webbasket_share_levels_ordered.index(group_rights)
        except ValueError:
            return None
    # public basket ?
    query_public_baskets = """
    SELECT share_level
    FROM usergroup_bskBASKET
    WHERE id_usergroup=0 AND id_bskBASKET=%i
    """
    res = run_sql(query_public_baskets % bskid)
    if res:
        public_rights = res[0][0]
        try:
            index = cfg_webbasket_share_levels_ordered.index(public_rights)
            if index > max_rights_index:
                return cfg_webbasket_share_levels_ordered[index]
            else:
                return cfg_webbasket_share_levels_ordered[max_rights_index]
        except ValueError:
            return None
            
            
########################### Personal baskets ##################################


def get_personal_baskets_infos(uid, topic):
    """
    Get useful infos (see below) for every personal basket of a given user in a given topic
    share level is assumed to be MA (MAnage) for a personal basket! 
    @param uid: user id (int)
    @param topic: topic of the basket
    @return a tuple of (id,
                       name,
                       share_level,
                       date_modification
                       nb_views) tuples
    """
    query = """
    SELECT bsk.id,
           bsk.name,
           DATE_FORMAT(bsk.date_modification, '%%Y-%%m-%%d %%H:%%i:%%s'),
           bsk.nb_views,
           count(rec.id_bibrec_or_bskEXTREC),<commit_msg>Bugfix: impossible to comment on a group-shared basket if this basket is also public and its public rights are lower than group-level ones.<commit_after># -*- coding: utf-8 -*-
## $Id$
##
## This file is part of CDS Invenio.
## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## CDS 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.
##
## CDS 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 CDS Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

""" Database related functions for webbasket module """

from zlib import decompress
from time import localtime

from invenio.dbquery import run_sql, escape_string
from invenio.webbasket_config import cfg_webbasket_share_levels, \
                                     cfg_webbasket_actions, \
                                     cfg_webbasket_share_levels_ordered
from invenio.dateutils import convert_datestruct_to_datetext
from invenio.websession_config import cfg_websession_usergroup_status

########################### Table of contents ################################
#
# NB. functions preceeded by a star use usergroup table
#
# 1. General functions
#    - count_baskets
#    - check_user_owns_basket
#    - get_max_user_rights_on_basket
#
# 2. Personal baskets
#    - get_personal_baskets_infos
#    - get_all_personal_baskets_names
#    - get_basket_name
#    - get_personal_topics_infos
#    - rename_basket
#    - rename_topic
#    - move_baskets_to_topic
#    - delete_basket
#    - create_basket
#
# 3. Actions on baskets
#    - get_basket_record
#    - share_basket_with_group
#    - update_rights
#    - move_item
#    - delete_item
#    - add_to_basket
#    - get_basket_content
#
# 4. Group baskets
#    - get_group_basket_infos
#    - (*) get_all_group_baskets_names
#    - is_shared_to
#
# 5. External baskets (baskets user has subscribed to)
#    - get_external_baskets_infos
#    - count_external_baskets
#    - get_all_external_baskets_names
#
# 6. Public baskets (interface to subscribe to baskets)
#    - get_public_basket_infos
#    - get_basket_general_infos
#    - count_public_baskets
#    - get_public_baskets_list
#    - subscribe
#    - unsubscribe
#    - count_subscribers
#    - (*) get_groups_subscribing_to_basket
# 
# 7. Commenting
#    - get_comments
#    - get_comment
#    - save_comment
#    - delete_comment
#
# 8. Usergroup functions
#    - (*) get_group_infos
#    - count_groups_user_member_of
#    - (*) get_groups_user_member_of
#
# 9. Useful functions
#    - __wash_count
#    - __decompress_last
#
########################## General functions ##################################

def count_baskets(uid):
    """Return (nb personal baskets, nb group baskets, nb external
    baskets) tuple for given user"""
    query1 = "SELECT COUNT(id) FROM bskBASKET WHERE id_owner=%i"
    res1 = run_sql(query1 % int(uid))
    personal = __wash_count(res1)
    query2 = """SELECT count(ugbsk.id_bskbasket) 
                FROM usergroup_bskBASKET ugbsk LEFT JOIN user_usergroup uug 
                                               ON ugbsk.id_usergroup=uug.id_usergroup
                WHERE uug.id_user=%i AND uug.user_status!='%s'
                GROUP BY ugbsk.id_usergroup"""
    params = (int(uid), cfg_websession_usergroup_status['PENDING'])
    res2 = run_sql(query2 % params)
    if len(res2):
        groups = reduce(lambda x, y: x + y, map(lambda x: x[0], res2))
    else:
        groups = 0
    external = count_external_baskets(uid)
    return (personal, groups, external)

def check_user_owns_baskets(uid, bskids):
    """ Return 1 if user is owner of every basket in list bskids"""
    if not((type(bskids) is list) or (type(bskids) is tuple)):
        bskids = [bskids]
    query = """SELECT id_owner FROM bskBASKET WHERE %s GROUP BY id_owner"""
    sep = ' OR '
    query %= sep.join(map(lambda x: 'id=%i'% int(x), bskids))
    res = run_sql(query)
    if len(res)==1 and int(res[0][0])==uid:
        return 1
    else:
        return 0

def get_max_user_rights_on_basket(uid, bskid):
    """Return the max rights a user has on this basket"""
    query_owner = "SELECT count(id_owner) FROM bskBASKET WHERE id_owner=%i and id=%i"
    params_owner = (int(uid), int(bskid))
    res = run_sql(query_owner % params_owner)
    if res and res[0][0]:
        # if this user is owner of this baskets he can do anything he wants.
        return cfg_webbasket_share_levels['MANAGE']
    # not owner => group member ?
    query_group_baskets = """
    SELECT share_level
    FROM user_usergroup AS ug LEFT JOIN usergroup_bskBASKET AS ub
                              ON ug.id_usergroup=ub.id_usergroup
    WHERE ug.id_user=%i AND ub.id_bskBASKET=%i AND NOT(ub.share_level='NO') AND ug.user_status!='%s'
    """
    params_group_baskets = (uid, bskid, cfg_websession_usergroup_status['PENDING'])
    res = run_sql(query_group_baskets % params_group_baskets)
    group_index = None
    if res:
        try:
            group_index = cfg_webbasket_share_levels_ordered.index(res[0][0])
        except:
            return None
    # public basket ?
    query_public_baskets = """
    SELECT share_level
    FROM usergroup_bskBASKET
    WHERE id_usergroup=0 AND id_bskBASKET=%i
    """
    public_index = None
    res = run_sql(query_public_baskets % bskid)
    if res:
        try:
            public_index = cfg_webbasket_share_levels_ordered.index(res[0][0])
        except:
            return None
    if group_index > public_index:
        return cfg_webbasket_share_levels_ordered[group_index]
    else:
        return cfg_webbasket_share_levels_ordered[public_index]
            
########################### Personal baskets ##################################


def get_personal_baskets_infos(uid, topic):
    """
    Get useful infos (see below) for every personal basket of a given user in a given topic
    share level is assumed to be MA (MAnage) for a personal basket! 
    @param uid: user id (int)
    @param topic: topic of the basket
    @return a tuple of (id,
                       name,
                       share_level,
                       date_modification
                       nb_views) tuples
    """
    query = """
    SELECT bsk.id,
           bsk.name,
           DATE_FORMAT(bsk.date_modification, '%%Y-%%m-%%d %%H:%%i:%%s'),
           bsk.nb_views,
           count(rec.id_bibrec_or_bskEXTREC),
{'fraction_non_alphanumeric': 0.11167031363967907, 'fraction_numerical': 0.010065645514223195, 'mean_word_length': 2.890749148694665, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2128390', 'n_tokens_mistral': 4629, 'n_tokens_neox': 4377, 'n_words': 1171}