diff --git a/modules/bibformat/etc/format_templates/Basket_Search_Result.bft b/modules/bibformat/etc/format_templates/Basket_Search_Result.bft new file mode 100644 index 000000000..c42c4ead8 --- /dev/null +++ b/modules/bibformat/etc/format_templates/Basket_Search_Result.bft @@ -0,0 +1,6 @@ +<name>Basket Search Result</name> +<description>Tiny HTML record used to display search results within WebBasket</description> +<BFE_TITLE_BRIEF /> +<BFE_AUTHORS limit="1" prefix=" - " extension=" <em>et al</em>"/> +<BFE_PUBLI_INFO prefix=" - "/> +<BFE_PRIMARY_REPORT_NUMBER prefix=" - "/> diff --git a/modules/bibformat/etc/format_templates/Makefile.am b/modules/bibformat/etc/format_templates/Makefile.am index 71e964eb9..9fc05d304 100644 --- a/modules/bibformat/etc/format_templates/Makefile.am +++ b/modules/bibformat/etc/format_templates/Makefile.am @@ -1,40 +1,41 @@ ## This file is part of Invenio. ## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 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. etcdir = $(sysconfdir)/bibformat/format_templates etc_DATA = Default_HTML_captions.bft Picture_HTML_brief.bft \ Default_HTML_detailed.bft Default_HTML_portfolio.bft \ Picture_HTML_detailed.bft Default_HTML_brief.bft \ BibTeX.bft MARCXML.bft Excel.bft \ Default_HTML_similarity.bft NLM.xsl \ OAI_DC.xsl OAI_MARC.bft DC.xsl EndNote.xsl RSS.xsl \ RefWorks.xsl MODS.xsl \ Default_HTML_references.bft Default_HTML_files.bft \ Default_HTML_actions.bft Journal_HTML_detailed.bft \ Journal_HTML_brief.bft \ Poetry_HTML_brief.bft Poetry_HTML_detailed.bft \ AID_HTML_very_brief.bft Podcast.xsl \ - Video_HTML_brief.bft Video_HTML_detailed.bft + Video_HTML_brief.bft Video_HTML_detailed.bft \ + Basket_Search_Result.bft tmpdir = $(prefix)/var/tmp tmp_DATA = Test1.bft Test3.bft Test_2.bft Test_no_template.test EXTRA_DIST = $(etc_DATA) $(tmp_DATA) CLEANFILES = *.tmp diff --git a/modules/bibformat/etc/output_formats/BSR.bfo b/modules/bibformat/etc/output_formats/BSR.bfo new file mode 100644 index 000000000..175c9d2b1 --- /dev/null +++ b/modules/bibformat/etc/output_formats/BSR.bfo @@ -0,0 +1 @@ +default: Basket_Search_Result.bft diff --git a/modules/bibformat/etc/output_formats/Makefile.am b/modules/bibformat/etc/output_formats/Makefile.am index 01fd35d8a..0818698c0 100644 --- a/modules/bibformat/etc/output_formats/Makefile.am +++ b/modules/bibformat/etc/output_formats/Makefile.am @@ -1,32 +1,32 @@ ## This file is part of Invenio. ## Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 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. etcdir = $(sysconfdir)/bibformat/output_formats etc_DATA = HB.bfo HC.bfo HD.bfo HP.bfo HX.bfo XM.bfo EXCEL.bfo \ XD.bfo HS.bfo HA.bfo \ XE.bfo XN.bfo XR.bfo XW.bfo \ XOAIDC.bfo XO.bfo XOAIMARC.bfo \ - HDREF.bfo HDFILE.bfo HDACT.bfo XP.bfo + HDREF.bfo HDFILE.bfo HDACT.bfo XP.bfo BSR.bfo tmpdir = $(prefix)/var/tmp tmp_DATA = TEST1.bfo TEST2.bfo TEST3.bfo EXTRA_DIST = $(etc_DATA) $(tmp_DATA) CLEANFILES = *.tmp diff --git a/modules/webbasket/lib/webbasket.py b/modules/webbasket/lib/webbasket.py index bab1051b6..7fe9119aa 100644 --- a/modules/webbasket/lib/webbasket.py +++ b/modules/webbasket/lib/webbasket.py @@ -1,2874 +1,2874 @@ ## This file is part of Invenio. ## Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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. """Web Baskets features.""" __revision__ = "$Id$" import sys if sys.hexversion < 0x2040000: # pylint: disable=W0622 from sets import Set as set # pylint: enable=W0622 from invenio.intbitset import intbitset import cgi import urllib from httplib import urlsplit, HTTPConnection #from socket import getdefaulttimeout, setdefaulttimeout from zlib import decompress import re from invenio.config import CFG_SITE_LANG, CFG_SITE_URL, \ CFG_WEBBASKET_MAX_NUMBER_OF_DISPLAYED_BASKETS from invenio.messages import gettext_set_language from invenio.dateutils import convert_datetext_to_dategui, \ convert_datetext_to_datestruct,\ convert_datestruct_to_dategui from invenio.bibformat import format_record from invenio.webbasket_config import CFG_WEBBASKET_SHARE_LEVELS, \ CFG_WEBBASKET_SHARE_LEVELS_ORDERED, \ CFG_WEBBASKET_CATEGORIES, \ InvenioWebBasketWarning from invenio.urlutils import get_referer from invenio.webuser import isGuestUser, collect_user_info from invenio.search_engine import \ record_exists, \ check_user_can_view_record, \ print_records_prologue, \ print_records_epilogue #from invenio.webcomment import check_user_can_attach_file_to_comments import invenio.webbasket_dblayer as db try: import invenio.template webbasket_templates = invenio.template.load('webbasket') except ImportError: pass from invenio.websearch_external_collections_utils import get_collection_name_by_id from invenio.websearch_external_collections import select_hosted_search_engines from invenio.websearch_external_collections_config import CFG_EXTERNAL_COLLECTION_TIMEOUT from invenio.websearch_external_collections_getter import HTTPAsyncPageGetter, async_download from invenio.errorlib import register_exception from invenio.search_engine import search_unit from invenio.htmlutils import remove_html_markup ######################################## ### Display public baskets and notes ### ######################################## def perform_request_display_public(uid, selected_bskid=0, selected_recid=0, optional_params={}, of='hb', ln=CFG_SITE_LANG): """Engine for the display of a public interface. Calls the template and returns HTML. @param selected_bskid: The id of the basket to be displayed (optional) @param selected_recid: The id of the item to be displayed (optional) @param optional_params: optional parameters to be passed, used for notes @param of: display format @param ln: language""" _ = gettext_set_language(ln) warnings_item = [] warnings_basket = [] (of, of_warnings) = wash_of(of) if of_warnings: navtrail = create_webbasket_navtrail(uid, ln=ln) body = webbasket_templates.tmpl_warnings(of_warnings, ln) return (body, of_warnings, navtrail) basket = db.get_public_basket_info(selected_bskid) if not basket: if of != 'hb': return ("", None, None) try: raise InvenioWebBasketWarning(_('The selected public basket does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings_html = webbasket_templates.tmpl_warnings(exc.message, ln) #warnings.append(exc.message) #warnings = ['WRN_WEBBASKET_INVALID_OR_RESTRICTED_PUBLIC_BASKET'] (body, navtrail) = perform_request_list_public_baskets(uid) try: raise InvenioWebBasketWarning(_('Please select a valid public basket from the list of public baskets.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_SHOW_LIST_PUBLIC_BASKETS') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) body = warnings_html + body return (body, None, navtrail) else: (bskid, basket_name, id_owner, last_update, dummy, nb_items, recids, share_rights) = basket[0] if selected_recid: valid_recids = tuple(map(int, recids.split(','))) if selected_recid in valid_recids: (content, warnings_item) = __display_public_basket_single_item(bskid, basket_name, selected_recid, nb_items, share_rights, optional_params, of, ln) else: try: raise InvenioWebBasketWarning(_('The selected item does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings_item.append(exc.message) #warnings_item.append('WRN_WEBBASKET_INVALID_OR_RESTRICTED_ITEM') try: raise InvenioWebBasketWarning(_('Returning to the public basket view.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings_item.append(exc.message) #warnings_item.append('WRN_WEBBASKET_RETURN_TO_PUBLIC_BASKET') selected_recid = 0 if not selected_recid: if uid == id_owner: subscription_status = 0 else: if db.is_user_subscribed_to_basket(uid,bskid): subscription_status = 1 else: subscription_status = -1 (content, warnings_basket) = __display_public_basket(bskid, basket_name, last_update, nb_items, share_rights, id_owner, subscription_status, of, ln) if of == 'hb': body = webbasket_templates.tmpl_display(content=content) warnings = warnings_item + warnings_basket warnings_html = webbasket_templates.tmpl_warnings(warnings, ln) body = warnings_html + body else: body = content if of == 'hb': navtrail = create_webbasket_navtrail(uid, bskid=selected_bskid, public_basket=True, ln=ln) if of == 'hb': return (body, warnings, navtrail) else: return (body, None, None) def __display_public_basket(bskid, basket_name, last_update, nb_items, share_rights, id_owner, subscription_status, of='hb', ln=CFG_SITE_LANG): """Private function. Display a basket giving its category and topic or group. @param share_rights: rights user has on basket @param group_sharing_level: None if basket is not shared, 0 if public basket, > 0 if shared to usergroups but not public. @param category: selected category (see webbasket_config.py) @param selected_topic: # of selected topic to display baskets @param selected_group_id: id of group to display baskets @param ln: language""" _ = gettext_set_language(ln) warnings = [] nb_total_notes = 0 last_note = _("N/A") records = [] notes_dates = [] last_update = convert_datetext_to_dategui(last_update, ln) items = db.get_basket_content(bskid, of) external_recids = [] for (recid, collection_id, nb_notes, last_note, ext_val, int_val, score) in items: notes_dates.append(convert_datetext_to_datestruct(last_note)) last_note = convert_datetext_to_dategui(last_note, ln) colid = collection_id and collection_id or collection_id == 0 and -1 or 0 val = "" nb_total_notes += nb_notes if recid < 0: if ext_val: val = decompress(ext_val) else: external_recids.append(recid) else: if int_val: val = decompress(int_val) else: val = format_record(recid, of, on_the_fly=True) records.append((recid, colid, nb_notes, last_note, val, score)) if external_recids: external_records = format_external_records(external_recids, of) for external_record in external_records: for record in records: if record[0] == -external_record[0]: idx = records.index(record) tuple_to_list = list(records.pop(idx)) tuple_to_list[4] = external_record[1] records.insert(idx, tuple(tuple_to_list)) break if notes_dates: last_note = convert_datestruct_to_dategui(max(notes_dates), ln) body = webbasket_templates.tmpl_public_basket(bskid, basket_name, last_update, nb_items, (check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT'],),), nb_total_notes, records, id_owner, subscription_status, of, ln) return (body, warnings) def __display_public_basket_single_item(bskid, basket_name, recid, nb_items, share_rights, optional_params={}, of='hb', ln=CFG_SITE_LANG): """Private function. Display a basket giving its category and topic or group. @param share_rights: rights user has on basket @param group_sharing_level: None if basket is not shared, 0 if public basket, > 0 if shared to usergroups but not public. @param category: selected category (see webbasket_config.py) @param selected_topic: # of selected topic to display baskets @param selected_group_id: id of group to display baskets @param ln: language""" _ = gettext_set_language(ln) warnings = [] item = db.get_basket_item(bskid, recid, of) if item: (recid, collection_id, nb_notes, last_note, ext_val, int_val, score) = item[0] previous_item_recid = item[1] next_item_recid = item[2] item_index = item[3] else: # The validity of the recid and hence the item is already checked by the # previous function and the appropriate warning is returned. # This is just an extra check just in case we missed something. # An empty body is returned. body = "" try: raise InvenioWebBasketWarning(_('The selected item does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_INVALID_OR_RESTRICTED_ITEM') return (body, warnings) last_note = convert_datetext_to_dategui(last_note, ln) colid = collection_id and collection_id or collection_id == 0 and -1 or 0 val = "" if recid < 0: if ext_val: val = decompress(ext_val) else: external_record = format_external_records([recid], of) val = external_record and external_record[0][1] or "" else: if int_val: val = decompress(int_val) else: val = format_record(recid, of, on_the_fly=True) item = (recid, colid, nb_notes, last_note, val, score) notes = db.get_notes(bskid, recid) body = webbasket_templates.tmpl_public_basket_single_item(bskid, basket_name, nb_items, (check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']), check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT'])), item, notes, previous_item_recid, next_item_recid, item_index, optional_params, of, ln) return (body, warnings) def perform_request_list_public_baskets(uid, limit=1, sort='name', asc=1, nb_views_show_p=False, ln=CFG_SITE_LANG): """Display list of public baskets. @param limit: display baskets from the incrementally numbered 'limit' and on @param sort: sort by 'name' or 'views' or 'owner' or 'date' or 'items' @param asc: ascending sort or not @param ln: language""" warnings_html = "" number_of_all_public_baskets = db.count_all_public_baskets() limit -= 1 if limit < 0: limit = 0 elif limit >= number_of_all_public_baskets: limit = number_of_all_public_baskets - 1 if not nb_views_show_p and sort == 'views': # TODO: Add a 'sort by views' restriction warning #warnings.append('...') #warnings_html += webbasket_templates.tmpl_warnings(warnings, ln) sort = "name" all_public_baskets = db.get_list_public_baskets(limit, CFG_WEBBASKET_MAX_NUMBER_OF_DISPLAYED_BASKETS, sort, asc) body = webbasket_templates.tmpl_display_list_public_baskets(all_public_baskets, limit, number_of_all_public_baskets, sort, asc, nb_views_show_p, ln) search_box = __create_search_box(uid=uid, category=CFG_WEBBASKET_CATEGORIES['ALLPUBLIC'], ln=ln) body = webbasket_templates.tmpl_display(content=body, search_box=search_box) body = warnings_html + body navtrail = create_webbasket_navtrail(uid, public_basket=True, ln=ln) return (body, navtrail) def perform_request_write_public_note(uid, bskid=0, recid=0, cmtid=0, ln=CFG_SITE_LANG): """Display a note writing form @param uid: user id @param bskid: basket id @param recid: record id (comments are on a specific record in a specific basket) @param cmtid: if provided this comment is a reply to comment cmtid. @param category: selected category @param topic: selected topic @param group_id: selected group id @param ln: language """ _ = gettext_set_language(ln) optional_params = {} warnings_rights = [] warnings_html = "" if not can_add_notes_to_public_basket_p(bskid): try: raise InvenioWebBasketWarning(_('You do not have permission to write notes to this item.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') # warnings_rights = exc.message #warnings_rights = ['WRN_WEBBASKET_RESTRICTED_WRITE_NOTES'] warnings_html += webbasket_templates.tmpl_warnings(warnings_rights, ln) else: if cmtid and db.note_belongs_to_item_in_basket_p(cmtid, recid, bskid): optional_params["Add note"] = db.get_note(cmtid) optional_params["Reply to"] = cmtid elif cmtid: optional_params["Add note"] = () try: raise InvenioWebBasketWarning(_('The note you are quoting does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') optional_params["Warnings"] = exc.message else: optional_params["Add note"] = () (body, warnings, navtrail) = perform_request_display_public(uid=uid, selected_bskid=bskid, selected_recid=recid, optional_params=optional_params, of='hb', ln=CFG_SITE_LANG) if not warnings: body = warnings_html + body # warnings = warnings_rights return (body, navtrail) def perform_request_save_public_note(uid, bskid=0, recid=0, note_title="", note_body="", editor_type='textarea', ln=CFG_SITE_LANG, reply_to=None): """ Save a given comment if able to. @param uid: user id (int) @param bskid: basket id (int) @param recid: record id (int) @param title: title of comment (string) @param text: comment's body (string) @param ln: language (string) @param editor_type: the kind of editor/input used for the comment: 'textarea', 'ckeditor' @param reply_to: the id of the comment we are replying to """ optional_params = {} warnings_rights = [] warnings_html = "" _ = gettext_set_language(ln) if not can_add_notes_to_public_basket_p(bskid): try: raise InvenioWebBasketWarning(_('You do not have permission to write notes to this item.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') # warnings_rights = exc.message #warnings_rights = ['WRN_WEBBASKET_RESTRICTED_WRITE_NOTES'] warnings_html += webbasket_templates.tmpl_warnings(warnings_rights, ln) else: if not note_title or not note_body: # FIXME: improve check when ckeditor optional_params["Incomplete note"] = (note_title, note_body) try: raise InvenioWebBasketWarning(_('You must fill in both the subject and the body of the note.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') optional_params["Warnings"] = exc.message else: if editor_type == 'ckeditor': # Here we remove the line feeds introduced by CKEditor (they # have no meaning for the user) and replace the HTML line # breaks by linefeeds, so that we are close to an input that # would be done without the CKEditor. That's much better if a # reply to a comment is made with a browser that does not # support CKEditor. note_body = note_body.replace('\n', '').replace('\r', '').replace('<br />', '\n') if not(db.save_note(uid, bskid, recid, note_title, note_body, reply_to)): # TODO: The note could not be saved. DB problem? pass else: # TODO: inform about successful annotating. pass (body, warnings, navtrail) = perform_request_display_public(uid=uid, selected_bskid=bskid, selected_recid=recid, optional_params=optional_params, of='hb', ln=CFG_SITE_LANG) if not warnings: body = warnings_html + body # warnings = warnings_rights return (body, navtrail) ################################# ### Display baskets and notes ### ################################# def perform_request_display(uid, selected_category=CFG_WEBBASKET_CATEGORIES['PRIVATE'], selected_topic="", selected_group_id=0, selected_bskid=0, selected_recid=0, optional_params={}, of='hb', ln=CFG_SITE_LANG): """Display all the baskets of given category, topic or group. @param uid: user id @param selected_category: selected category (see webbasket_config.py) @param selected_topic: # of selected topic to display baskets @param selected_group_id: id of group to display baskets @param ln: language""" _ = gettext_set_language(ln) warnings = [] warnings_html = "" valid_category_choice = False selected_basket_info = [] content = "" search_box = "" (of, of_warnings) = wash_of(of) if of_warnings: navtrail = create_webbasket_navtrail(uid, ln=ln) body = webbasket_templates.tmpl_warnings(of_warnings, ln) return (body, of_warnings, navtrail) (selected_category, category_warnings) = wash_category(selected_category) if not selected_category and category_warnings: if of == 'xm': return ("", None. None) navtrail = create_webbasket_navtrail(uid, ln=ln) body = webbasket_templates.tmpl_warnings(category_warnings, ln) return (body, category_warnings, navtrail) if selected_category == CFG_WEBBASKET_CATEGORIES['ALLPUBLIC']: if of == 'xm': return ("", None. None) # TODO: Send the correct title of the page as well. return perform_request_list_public_baskets(uid) personal_info = db.get_all_user_personal_basket_ids_by_topic(uid) personal_baskets_info = () if personal_info and selected_category == CFG_WEBBASKET_CATEGORIES['PRIVATE']: # Create a dictionary that has the valid topics for keys and the basket # ids in each topic (string, ids separated by commas) as values. personal_info_dict = {} for personal_info_topic_and_bskids in personal_info: personal_info_dict[personal_info_topic_and_bskids[0]] = map(int, personal_info_topic_and_bskids[1].split(',')) valid_category_choice = True if selected_topic: valid_selected_topic_p = False # Validate the topic. Check if the selected topic is one of the keys # in the dictionary. If it is valid then get some more info for that # topic from the DB. if selected_topic in personal_info_dict.keys(): personal_baskets_info = db.get_personal_baskets_info_for_topic(uid, selected_topic) valid_selected_topic_p = True if not valid_selected_topic_p: try: raise InvenioWebBasketWarning(_('The selected topic does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_INVALID_OR_RESTRICTED_TOPIC') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) valid_selected_topic_p = False selected_topic = "" else: valid_selected_topic_p = True if valid_selected_topic_p and selected_bskid: if selected_topic: valid_bskids = personal_info_dict[selected_topic] else: valid_bskids = [] for valid_bskids_per_topic in personal_info_dict.values(): valid_bskids.extend(valid_bskids_per_topic) if selected_bskid in valid_bskids: if not selected_topic: for valid_topic in personal_info_dict.iterkeys(): if selected_bskid in personal_info_dict[valid_topic]: selected_topic = valid_topic break personal_baskets_info = db.get_personal_baskets_info_for_topic(uid, selected_topic) for personal_basket_info in personal_baskets_info: if personal_basket_info[0] == selected_bskid: selected_basket_info = list(personal_basket_info) selected_basket_info.append(CFG_WEBBASKET_SHARE_LEVELS['MANAGE']) break else: try: raise InvenioWebBasketWarning(_('The selected basket does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_INVALID_OR_RESTRICTED_BASKET') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) selected_bskid = 0 else: selected_bskid = 0 group_info = db.get_all_user_group_basket_ids_by_group(uid) group_baskets_info = () selected_group_name = "" if group_info and selected_category == CFG_WEBBASKET_CATEGORIES['GROUP']: # Create a dictionary that has the valid group as keys and the basket # ids in each group (string, ids separated by commas) as values. group_info_dict = {} for group_info_group_and_bskids in group_info: group_info_dict[group_info_group_and_bskids[0]] = (group_info_group_and_bskids[1], \ map(int, group_info_group_and_bskids[2].split(','))) valid_category_choice = True if selected_group_id: valid_selected_group_p = False # Validate the group. Check if the selected group is one of the keys # in the dictionary. If it is valid then get some more info for that # group from the DB. if selected_group_id in group_info_dict.keys(): selected_group_name = group_info_dict[selected_group_id][0] group_baskets_info = db.get_group_baskets_info_for_group(selected_group_id) valid_selected_group_p = True if not valid_selected_group_p: try: raise InvenioWebBasketWarning(_('The selected topic does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_INVALID_OR_RESTRICTED_GROUP') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) selected_group_id = "" valid_selected_group_p = False else: valid_selected_group_p = True if valid_selected_group_p and selected_bskid: if selected_group_id: valid_bskids = group_info_dict[selected_group_id][1] else: valid_bskids = [] for group_and_valid_bskids_per_group in group_info_dict.values(): valid_bskids_per_group = group_and_valid_bskids_per_group[1] valid_bskids.extend(valid_bskids_per_group) if selected_bskid in valid_bskids: if not selected_group_id: for valid_group_id in group_info_dict.iterkeys(): if selected_bskid in group_info_dict[valid_group_id][1]: selected_group_id = valid_group_id break selected_group_name = group_info_dict[selected_group_id][0] group_baskets_info = db.get_group_baskets_info_for_group(selected_group_id) for group_basket_info in group_baskets_info: if group_basket_info[0] == selected_bskid: selected_basket_info = list(group_basket_info) # INFO: uncomment the two following lines to give MANAGE # rights to the owner of the basket even when through # the group view of the basket. #if group_basket_info[7] == uid: # selected_basket_info[6] = CFG_WEBBASKET_SHARE_LEVELS['MANAGE'] selected_basket_info.pop(7) break else: try: raise InvenioWebBasketWarning(_('The selected topic does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_INVALID_OR_RESTRICTED_BASKET') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) selected_bskid = 0 else: selected_bskid = 0 public_info = db.get_all_external_basket_ids_and_names(uid) if public_info and selected_category == CFG_WEBBASKET_CATEGORIES['EXTERNAL']: valid_category_choice = True if selected_bskid: valid_bskids = [(valid_basket[0], valid_basket[3]) for valid_basket in public_info] if (selected_bskid, 0) in valid_bskids: public_basket_info = db.get_external_basket_info(selected_bskid) if public_basket_info: selected_basket_info = list(public_basket_info[0]) elif (selected_bskid, None) in valid_bskids: try: raise InvenioWebBasketWarning(_('The selected basket is no longer public.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_FORMER_PUBLIC_BASKET') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) selected_bskid = 0 else: try: raise InvenioWebBasketWarning(_('The selected basket does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_INVALID_OR_RESTRICTED_BASKET') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) selected_bskid = 0 if not valid_category_choice: if personal_info: selected_category = CFG_WEBBASKET_CATEGORIES['PRIVATE'] elif group_info: selected_category = CFG_WEBBASKET_CATEGORIES['GROUP'] elif public_info: selected_category = CFG_WEBBASKET_CATEGORIES['EXTERNAL'] else: selected_category = CFG_WEBBASKET_CATEGORIES['ALLPUBLIC'] if not of.startswith('x'): directory_box = webbasket_templates.tmpl_create_directory_box(selected_category, selected_topic, (selected_group_id, selected_group_name), selected_bskid, (personal_info, personal_baskets_info), (group_info, group_baskets_info), public_info, ln) if selected_basket_info: if selected_recid: (bskid, basket_name, last_update, dummy, nb_items, dummy, share_rights) = selected_basket_info (content, bsk_warnings) = __display_basket_single_item(bskid, basket_name, selected_recid, last_update, nb_items, share_rights, selected_category, selected_topic, selected_group_id, optional_params, of, ln) else: (bskid, basket_name, last_update, dummy, nb_items, dummy, share_rights) = selected_basket_info share_level = db.get_basket_share_level(bskid) if share_level: share_level = share_level[0][0] else: share_level = None if share_level == 0: nb_subscribers = db.count_public_basket_subscribers(bskid) else: nb_subscribers = None (content, bsk_warnings) = __display_basket(bskid, basket_name, last_update, nb_items, nb_subscribers, share_rights, share_level, selected_category, selected_topic, selected_group_id, of, ln) warnings.extend(bsk_warnings) if not of.startswith('x'): warnings_html += webbasket_templates.tmpl_warnings(bsk_warnings, ln) else: if not of.startswith('x'): search_box = __create_search_box(uid=uid, category=selected_category, topic=selected_topic, grpid=selected_group_id, p="", n=1, ln=ln) if not of.startswith('x'): body = webbasket_templates.tmpl_display(directory_box, content, search_box) body = warnings_html + body else: body = content if not of.startswith('x'): navtrail = create_webbasket_navtrail(uid, category=selected_category, topic=selected_topic, group=selected_group_id, bskid=selected_bskid, ln=ln) if not of.startswith('x'): return (body, warnings, navtrail) else: return (body, None, None) def __display_basket(bskid, basket_name, last_update, nb_items, nb_subscribers, share_rights, share_level, selected_category=CFG_WEBBASKET_CATEGORIES['PRIVATE'], selected_topic="", selected_group_id=0, of="hb", ln=CFG_SITE_LANG): """Private function. Display a basket giving its category and topic or group. @param share_rights: rights user has on basket @param share_level: None if basket is not shared, 0 if public basket, > 0 if shared to usergroups but not public. @param selected_category: selected category (see webbasket_config.py) @param selected_topic: # of selected topic to display baskets @param selected_group_id: id of group to display baskets @param ln: language""" _ = gettext_set_language(ln) warnings = [] nb_total_notes = 0 last_note = _("N/A") records = [] notes_dates = [] #date_modification = convert_datetext_to_dategui(date_modification, ln) last_update = convert_datetext_to_dategui(last_update, ln) items = db.get_basket_content(bskid, of) external_recids = [] for (recid, collection_id, nb_notes, last_note, ext_val, int_val, score) in items: notes_dates.append(convert_datetext_to_datestruct(last_note)) last_note = convert_datetext_to_dategui(last_note, ln) colid = collection_id and collection_id or collection_id == 0 and -1 or 0 val = "" nb_total_notes += nb_notes if recid < 0: if ext_val: val = decompress(ext_val) else: external_recids.append(recid) else: if int_val: val = decompress(int_val) else: val = format_record(recid, of, on_the_fly=True) ## external item (record): colid = positive integet ## external item (url): colid = -1 ## local item (record): colid = 0 records.append((recid, colid, nb_notes, last_note, val, score)) if external_recids: external_records = format_external_records(external_recids, of) for external_record in external_records: for record in records: if record[0] == -external_record[0]: idx = records.index(record) tuple_to_list = list(records.pop(idx)) tuple_to_list[4] = external_record[1] records.insert(idx, tuple(tuple_to_list)) break if notes_dates: last_note = convert_datestruct_to_dategui(max(notes_dates), ln) if of == 'hb' or of.startswith('x'): body = webbasket_templates.tmpl_basket(bskid, basket_name, last_update, nb_items, nb_subscribers, (check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READITM']), check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['MANAGE']), check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']), check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']), check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDITM']), check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['DELITM'])), nb_total_notes, share_level, selected_category, selected_topic, selected_group_id, records, of, ln) else: body = "" for rec in records: body += rec[4] return (body, warnings) def __display_basket_single_item(bskid, basket_name, recid, last_update, nb_items, share_rights, selected_category=CFG_WEBBASKET_CATEGORIES['PRIVATE'], selected_topic="", selected_group_id=0, optional_params={}, of='hb', ln=CFG_SITE_LANG): """Private function. Display a basket giving its category and topic or group. @param share_rights: rights user has on basket @param selected_category: selected category (see webbasket_config.py) @param selected_topic: # of selected topic to display baskets @param selected_group_id: id of group to display baskets @param ln: language""" _ = gettext_set_language(ln) warnings = [] last_note = _("N/A") notes_dates = [] #date_modification = convert_datetext_to_dategui(date_modification, ln) last_update = convert_datetext_to_dategui(last_update, ln) item = db.get_basket_item(bskid, recid, of) if item: (recid, collection_id, nb_notes, last_note, ext_val, int_val, score) = item[0] previous_item_recid = item[1] next_item_recid = item[2] item_index = item[3] else: share_level = db.get_basket_share_level(bskid) if share_level: share_level = share_level[0][0] else: share_level = None if share_level == 0: nb_subscribers = db.count_public_basket_subscribers(bskid) else: nb_subscribers = None (content, bsk_warnings) = __display_basket(bskid, basket_name, last_update, nb_items, nb_subscribers, share_rights, share_level, selected_category, selected_topic, selected_group_id, of, ln) try: raise InvenioWebBasketWarning(_('The selected item does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') bsk_warnings.append(exc.message) #bsk_warnings.append('WRN_WEBBASKET_INVALID_OR_RESTRICTED_ITEM') return (content, bsk_warnings) notes_dates.append(convert_datetext_to_datestruct(last_note)) last_note = convert_datetext_to_dategui(last_note, ln) colid = collection_id and collection_id or collection_id == 0 and -1 or 0 val = "" if recid < 0: if ext_val: val = decompress(ext_val) else: external_record = format_external_records([recid], of) val = external_record and external_record[0][1] or "" else: if int_val: val = decompress(int_val) else: val = format_record(recid, of, on_the_fly=True) item = (recid, colid, nb_notes, last_note, val, score) comments = db.get_notes(bskid, recid) if notes_dates: last_note = convert_datestruct_to_dategui(max(notes_dates), ln) body = webbasket_templates.tmpl_basket_single_item(bskid, basket_name, nb_items, (check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READITM']), check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']), check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']), check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['DELCMT'])), selected_category, selected_topic, selected_group_id, item, comments, previous_item_recid, next_item_recid, item_index, optional_params, of, ln) return (body, warnings) def perform_request_search(uid, selected_category="", selected_topic="", selected_group_id=0, p="", b="", n=0, #format='xm', ln=CFG_SITE_LANG): """Search the baskets... @param uid: user id @param category: selected category (see webbasket_config.py) @param selected_topic: # of selected topic to display baskets @param selected_group_id: id of group to display baskets @param ln: language""" _ = gettext_set_language(ln) body = "" #warnings = [] warnings_html = "" (b_category, b_topic_or_grpid, b_warnings) = wash_b_search(b) # we extract the category from the washed b GET variable. # if a valid category was returned we use it as the selected category. if b_category: selected_category = b_category if selected_category == CFG_WEBBASKET_CATEGORIES['PRIVATE']: selected_topic = b_topic_or_grpid elif selected_category == CFG_WEBBASKET_CATEGORIES['GROUP']: selected_group_id = b_topic_or_grpid # if no category was returned and there were warnings it means there was a # bad input, send the warning to the user and return the page. elif b_warnings: navtrail = create_webbasket_navtrail(uid, search_baskets=True, ln=ln) body = webbasket_templates.tmpl_warnings(b_warnings, ln) return (body, navtrail) # if no category was returned and there were no warnings it means no category # was defined in the b GET variable. If the user has not defined a category # either using the category GET variable it means there is no category defined # whatsoever. elif not selected_category: selected_category = "" # finally, if no category was returned but the user has defined a category # using the category GET variable we extract the category after washing the # variable. else: (selected_category, category_warnings) = wash_category(selected_category) if not selected_category and category_warnings: navtrail = create_webbasket_navtrail(uid, search_baskets=True, ln=ln) body = webbasket_templates.tmpl_warnings(category_warnings, ln) return (body, navtrail) if selected_category == CFG_WEBBASKET_CATEGORIES['PRIVATE'] and selected_topic: (selected_topic, topic_warnings) = wash_topic(uid, selected_topic) if not selected_topic and topic_warnings: navtrail = create_webbasket_navtrail(uid, search_baskets=True, ln=ln) body = webbasket_templates.tmpl_warnings(topic_warnings, ln) return (body, navtrail) if selected_category == CFG_WEBBASKET_CATEGORIES['GROUP'] and selected_group_id: (selected_group_id, group_warnings) = wash_group(uid, selected_group_id) if not selected_group_id and group_warnings: navtrail = create_webbasket_navtrail(uid, search_baskets=True, ln=ln) body = webbasket_templates.tmpl_warnings(group_warnings, ln) return (body, navtrail) # IDEA: in case we pass an "action=search" GET variable we can use the # following bit to warn the user he's searching for an empty search pattern. #if action == "search" and not p: # warnings_html += webbasket_templates.tmpl_warnings('WRN_WEBBASKET_NO_SEARCH_PATTERN', ln) # perform_search = 0 if p: # Let's set some initial values personal_search_results = None total_no_personal_search_results = 0 group_search_results = None total_no_group_search_results = 0 public_search_results = None total_no_public_search_results = 0 all_public_search_results = None total_no_all_public_search_results = 0 # Let's precalculate the local search resutls # and the pattern for the external search results local_search_results = search_unit(p) # How strict should the pattern be? Look for the exact word # (using word boundaries: \b) or is any substring enough? # not that strict: # since we remove the html markup before searching for the pattern we # can use a rather simple pattern here. # INFO: we choose a not so strict pattern, since there are issues with # word bounderies and utf-8 strings (ex. with greek that was tested) pattern = re.compile(r'%s' % (re.escape(p),), re.DOTALL + re.MULTILINE + re.IGNORECASE + re.UNICODE) #pattern = re.compile(r'%s(?!([^<]+)?>)' % (p,), re.DOTALL + re.MULTILINE + re.IGNORECASE + re.UNICODE) # strict: # since we remove the html markup before searching for the pattern we # can use a rather simple pattern here. #pattern = re.compile(r'\b%s\b' % (re.escape(p),), re.DOTALL + re.MULTILINE + re.IGNORECASE + re.UNICODE) #pattern = re.compile(r'%s\b(?!([^<]+)?>)' % (p,), re.DOTALL + re.MULTILINE + re.IGNORECASE + re.UNICODE) # TODO: All the external records are now saved automatically first in xml. # So, the search should be done on the "xm" formatted records in the database # and not the "hb" ones. (That is not the case for their comments though). # Records in xml in the database are stored escaped. It's then suggested # that the pattern is also escaped before we performed the search for more # consistent resutls. We could also use .replace("\n", "") to clean the # content (after the removal of html markup) from all the newline characters. # The search format for external records. This means in which format will # the external records be fetched from the database to be searched then. format = 'xm' ### Calculate the search results for the user's personal baskets ### if b.startswith("P") or not b: personal_search_results = {} personal_items = db.get_all_items_in_user_personal_baskets(uid, selected_topic, format) personal_local_items = personal_items[0] personal_external_items = personal_items[1] personal_external_items_xml_records = {} for local_info_per_basket in personal_local_items: bskid = local_info_per_basket[0] basket_name = local_info_per_basket[1] topic = local_info_per_basket[2] recid_list = local_info_per_basket[3] local_recids_per_basket = intbitset(map(int, recid_list.strip(',').split(','))) intsec = local_search_results.intersection(local_recids_per_basket) if intsec: personal_search_results[bskid] = [basket_name, topic, len(intsec), list(intsec)] total_no_personal_search_results += len(intsec) for external_info_per_basket in personal_external_items: bskid = external_info_per_basket[0] basket_name = external_info_per_basket[1] topic = external_info_per_basket[2] recid = external_info_per_basket[3] value = external_info_per_basket[4] xml_record = decompress(value) personal_external_items_xml_records[recid] = xml_record text = remove_html_markup(xml_record) #text = text.replace('\n', '') result = pattern.search(text) if result: if personal_search_results.has_key(bskid): personal_search_results[bskid][2] += 1 personal_search_results[bskid][3].append(recid) else: personal_search_results[bskid] = [basket_name, topic, 1, [recid]] total_no_personal_search_results += 1 if n: personal_items_by_matching_notes = db.get_all_items_in_user_personal_baskets_by_matching_notes(uid, selected_topic, p) for info_per_basket_by_matching_notes in personal_items_by_matching_notes: bskid = info_per_basket_by_matching_notes[0] basket_name = info_per_basket_by_matching_notes[1] topic = info_per_basket_by_matching_notes[2] recid_list = info_per_basket_by_matching_notes[3] recids_per_basket_by_matching_notes = set(map(int, recid_list.strip(',').split(','))) if personal_search_results.has_key(bskid): no_personal_search_results_per_basket_so_far = personal_search_results[bskid][2] personal_search_results[bskid][3] = list(set(personal_search_results[bskid][3]).union(recids_per_basket_by_matching_notes)) personal_search_results[bskid][2] = len(personal_search_results[bskid][3]) total_no_personal_search_results += ( personal_search_results[bskid][2] - no_personal_search_results_per_basket_so_far ) else: personal_search_results[bskid] = [basket_name, topic, len(recids_per_basket_by_matching_notes), list(recids_per_basket_by_matching_notes)] total_no_personal_search_results += len(recids_per_basket_by_matching_notes) # For every found record: calculate the number of notes # and the HTML representation of the record. for bskid in personal_search_results.keys(): recids = personal_search_results[bskid][3] number_of_notes_per_record = db.get_number_of_notes_per_record_in_basket(bskid, recids) records = [] for recid_and_notes in number_of_notes_per_record: recid = recid_and_notes[0] number_of_notes = recid_and_notes[1] if recid < 0: xml_record = personal_external_items_xml_records[recid] - record_html = format_record(None, of='hwbsr', xml_record=xml_record) + record_html = format_record(None, of='bsr', xml_record=xml_record) records.append((recid, number_of_notes, record_html)) else: - record_html = format_record(recid, of='hwbsr', on_the_fly=True) + record_html = format_record(recid, of='bsr', on_the_fly=True) records.append((recid, number_of_notes, record_html)) personal_search_results[bskid][3] = records ### Calculate the search results for the user's group baskets ### if b.startswith("G") or not b: group_search_results = {} group_items = db.get_all_items_in_user_group_baskets(uid, selected_group_id, format) group_local_items = group_items[0] group_external_items = group_items[1] group_external_items_xml_records = {} for local_info_per_basket in group_local_items: bskid = local_info_per_basket[0] basket_name = local_info_per_basket[1] grpid = local_info_per_basket[2] group_name = local_info_per_basket[3] share_rights = local_info_per_basket[4] recid_list = local_info_per_basket[5] local_recids_per_basket = intbitset(map(int, recid_list.strip(',').split(','))) intsec = local_search_results.intersection(local_recids_per_basket) if intsec: share_rights_view_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']) share_rights_add_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']) share_rights_notes = (share_rights_view_notes, share_rights_add_notes) group_search_results[bskid] = [basket_name, grpid, group_name, share_rights_notes, len(intsec), list(intsec)] total_no_group_search_results += len(intsec) for external_info_per_basket in group_external_items: bskid = external_info_per_basket[0] basket_name = external_info_per_basket[1] grpid = external_info_per_basket[2] group_name = external_info_per_basket[3] share_rights = external_info_per_basket[4] recid = external_info_per_basket[5] value = external_info_per_basket[6] xml_record = decompress(value) group_external_items_xml_records[recid] = xml_record text = remove_html_markup(xml_record) #text = text.replace('\n', '') result = pattern.search(text) if result: if group_search_results.has_key(bskid): group_search_results[bskid][4] += 1 group_search_results[bskid][5].append(recid) else: share_rights_view_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']) share_rights_add_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']) share_rights_notes = (share_rights_view_notes, share_rights_add_notes) group_search_results[bskid] = [basket_name, grpid, group_name, share_rights_notes, 1, [recid]] total_no_group_search_results += 1 if n: group_items_by_matching_notes = db.get_all_items_in_user_group_baskets_by_matching_notes(uid, selected_group_id, p) for info_per_basket_by_matching_notes in group_items_by_matching_notes: bskid = info_per_basket_by_matching_notes[0] basket_name = info_per_basket_by_matching_notes[1] grpid = info_per_basket_by_matching_notes[2] group_name = info_per_basket_by_matching_notes[3] share_rights = info_per_basket_by_matching_notes[4] recid_list = info_per_basket_by_matching_notes[5] recids_per_basket_by_matching_notes = set(map(int, recid_list.strip(',').split(','))) if group_search_results.has_key(bskid): no_group_search_results_per_basket_so_far = group_search_results[bskid][4] group_search_results[bskid][5] = list(set(group_search_results[bskid][5]).union(recids_per_basket_by_matching_notes)) group_search_results[bskid][4] = len(group_search_results[bskid][5]) total_no_group_search_results += ( group_search_results[bskid][4] - no_group_search_results_per_basket_so_far ) else: share_rights_view_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']) share_rights_add_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']) share_rights_notes = (share_rights_view_notes, share_rights_add_notes) group_search_results[bskid] = [basket_name, grpid, group_name, share_rights_notes, len(recids_per_basket_by_matching_notes), list(recids_per_basket_by_matching_notes)] total_no_group_search_results += len(recids_per_basket_by_matching_notes) # For every found record: calculate the number of notes # and the HTML representation of the record. for bskid in group_search_results.keys(): recids = group_search_results[bskid][5] number_of_notes_per_record = db.get_number_of_notes_per_record_in_basket(bskid, recids) records = [] for recid_and_notes in number_of_notes_per_record: recid = recid_and_notes[0] number_of_notes = recid_and_notes[1] if recid < 0: xml_record = group_external_items_xml_records[recid] - record_html = format_record(None, of='hwbsr', xml_record=xml_record) + record_html = format_record(None, of='bsr', xml_record=xml_record) records.append((recid, number_of_notes, record_html)) else: - record_html = format_record(recid, of='hwbsr', on_the_fly=True) + record_html = format_record(recid, of='bsr', on_the_fly=True) records.append((recid, number_of_notes, record_html)) group_search_results[bskid][5] = records ### Calculate the search results for the user's public baskets ### if b.startswith("E") or not b: public_search_results = {} public_items = db.get_all_items_in_user_public_baskets(uid, format) public_local_items = public_items[0] public_external_items = public_items[1] public_external_items_xml_records = {} for local_info_per_basket in public_local_items: bskid = local_info_per_basket[0] basket_name = local_info_per_basket[1] share_rights = local_info_per_basket[2] recid_list = local_info_per_basket[3] local_recids_per_basket = intbitset(map(int, recid_list.strip(',').split(','))) intsec = local_search_results.intersection(local_recids_per_basket) if intsec: share_rights_view_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']) share_rights_add_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']) share_rights_notes = (share_rights_view_notes, share_rights_add_notes) public_search_results[bskid] = [basket_name, share_rights_notes, len(intsec), list(intsec)] total_no_public_search_results += len(intsec) for external_info_per_basket in public_external_items: bskid = external_info_per_basket[0] basket_name = external_info_per_basket[1] share_rights = external_info_per_basket[2] recid = external_info_per_basket[3] value = external_info_per_basket[4] xml_record = decompress(value) public_external_items_xml_records[recid] = xml_record text = remove_html_markup(xml_record) #text = text.replace('\n', '') result = pattern.search(text) if result: if public_search_results.has_key(bskid): public_search_results[bskid][2] += 1 public_search_results[bskid][3].append(recid) else: share_rights_view_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']) share_rights_add_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']) share_rights_notes = (share_rights_view_notes, share_rights_add_notes) public_search_results[bskid] = [basket_name, share_rights_notes, 1, [recid]] total_no_public_search_results += 1 if n: public_items_by_matching_notes = db.get_all_items_in_user_public_baskets_by_matching_notes(uid, p) for info_per_basket_by_matching_notes in public_items_by_matching_notes: bskid = info_per_basket_by_matching_notes[0] basket_name = info_per_basket_by_matching_notes[1] share_rights = info_per_basket_by_matching_notes[2] recid_list = info_per_basket_by_matching_notes[3] recids_per_basket_by_matching_notes = set(map(int, recid_list.strip(',').split(','))) if public_search_results.has_key(bskid): no_public_search_results_per_basket_so_far = public_search_results[bskid][2] public_search_results[bskid][3] = list(set(public_search_results[bskid][3]).union(recids_per_basket_by_matching_notes)) public_search_results[bskid][2] = len(public_search_results[bskid][3]) total_no_public_search_results += ( public_search_results[bskid][2] - no_public_search_results_per_basket_so_far ) else: share_rights_view_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']) share_rights_add_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']) share_rights_notes = (share_rights_view_notes, share_rights_add_notes) public_search_results[bskid] = [basket_name, share_rights_notes, len(recids_per_basket_by_matching_notes), list(recids_per_basket_by_matching_notes)] total_no_public_search_results += len(recids_per_basket_by_matching_notes) # For every found record: calculate the number of notes # and the HTML representation of the record. for bskid in public_search_results.keys(): recids = public_search_results[bskid][3] number_of_notes_per_record = db.get_number_of_notes_per_record_in_basket(bskid, recids) records = [] for recid_and_notes in number_of_notes_per_record: recid = recid_and_notes[0] number_of_notes = recid_and_notes[1] if recid < 0: xml_record = public_external_items_xml_records[recid] - record_html = format_record(None, of='hwbsr', xml_record=xml_record) + record_html = format_record(None, of='bsr', xml_record=xml_record) records.append((recid, number_of_notes, record_html)) else: - record_html = format_record(recid, of='hwbsr', on_the_fly=True) + record_html = format_record(recid, of='bsr', on_the_fly=True) records.append((recid, number_of_notes, record_html)) public_search_results[bskid][3] = records ### Calculate the search results for all the public baskets ### if b.startswith("A"): all_public_search_results = {} all_public_items = db.get_all_items_in_all_public_baskets(format) all_public_local_items = all_public_items[0] all_public_external_items = all_public_items[1] all_public_external_items_xml_records = {} for local_info_per_basket in all_public_local_items: bskid = local_info_per_basket[0] basket_name = local_info_per_basket[1] share_rights = local_info_per_basket[2] recid_list = local_info_per_basket[3] local_recids_per_basket = intbitset(map(int, recid_list.strip(',').split(','))) intsec = local_search_results.intersection(local_recids_per_basket) if intsec: share_rights_view_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']) share_rights_add_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']) share_rights_notes = (share_rights_view_notes, share_rights_add_notes) all_public_search_results[bskid] = [basket_name, share_rights_notes, len(intsec), list(intsec)] total_no_all_public_search_results += len(intsec) for external_info_per_basket in all_public_external_items: bskid = external_info_per_basket[0] basket_name = external_info_per_basket[1] share_rights = external_info_per_basket[2] recid = external_info_per_basket[3] value = external_info_per_basket[4] xml_record = decompress(value) all_public_external_items_xml_records[recid] = xml_record text = remove_html_markup(xml_record) #text = text.replace('\n', '') result = pattern.search(text) if result: if all_public_search_results.has_key(bskid): all_public_search_results[bskid][2] += 1 all_public_search_results[bskid][3].append(recid) else: share_rights_view_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']) share_rights_add_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']) share_rights_notes = (share_rights_view_notes, share_rights_add_notes) all_public_search_results[bskid] = [basket_name, share_rights_notes, 1, [recid]] total_no_all_public_search_results += 1 if n: all_public_items_by_matching_notes = db.get_all_items_in_all_public_baskets_by_matching_notes(p) for info_per_basket_by_matching_notes in all_public_items_by_matching_notes: bskid = info_per_basket_by_matching_notes[0] basket_name = info_per_basket_by_matching_notes[1] share_rights = info_per_basket_by_matching_notes[2] recid_list = info_per_basket_by_matching_notes[3] recids_per_basket_by_matching_notes = set(map(int, recid_list.strip(',').split(','))) if all_public_search_results.has_key(bskid): no_all_public_search_results_per_basket_so_far = all_public_search_results[bskid][2] all_public_search_results[bskid][3] = list(set(all_public_search_results[bskid][3]).union(recids_per_basket_by_matching_notes)) all_public_search_results[bskid][2] = len(all_public_search_results[bskid][3]) total_no_all_public_search_results += ( all_public_search_results[bskid][2] - no_all_public_search_results_per_basket_so_far ) else: share_rights_view_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['READCMT']) share_rights_add_notes = check_sufficient_rights(share_rights, CFG_WEBBASKET_SHARE_LEVELS['ADDCMT']) share_rights_notes = (share_rights_view_notes, share_rights_add_notes) all_public_search_results[bskid] = [basket_name, share_rights_notes, len(recids_per_basket_by_matching_notes), list(recids_per_basket_by_matching_notes)] total_no_all_public_search_results += len(recids_per_basket_by_matching_notes) # For every found record: calculate the number of notes # and the HTML representation of the record. for bskid in all_public_search_results.keys(): recids = all_public_search_results[bskid][3] number_of_notes_per_record = db.get_number_of_notes_per_record_in_basket(bskid, recids) records = [] for recid_and_notes in number_of_notes_per_record: recid = recid_and_notes[0] number_of_notes = recid_and_notes[1] if recid < 0: xml_record = all_public_external_items_xml_records[recid] - record_html = format_record(None, of='hwbsr', xml_record=xml_record) + record_html = format_record(None, of='bsr', xml_record=xml_record) records.append((recid, number_of_notes, record_html)) else: - record_html = format_record(recid, of='hwbsr', on_the_fly=True) + record_html = format_record(recid, of='bsr', on_the_fly=True) records.append((recid, number_of_notes, record_html)) all_public_search_results[bskid][3] = records search_results_html = webbasket_templates.tmpl_search_results(personal_search_results, total_no_personal_search_results, group_search_results, total_no_group_search_results, public_search_results, total_no_public_search_results, all_public_search_results, total_no_all_public_search_results, ln) else: search_results_html = None search_box = __create_search_box(uid=uid, category=selected_category, topic=selected_topic, grpid=selected_group_id, p=p, n=n, ln=ln) body = webbasket_templates.tmpl_display(search_box=search_box, search_results=search_results_html) body = warnings_html + body navtrail = create_webbasket_navtrail(uid, search_baskets=True, ln=ln) return (body, navtrail) def perform_request_write_note(uid, category=CFG_WEBBASKET_CATEGORIES['PRIVATE'], topic="", group_id=0, bskid=0, recid=0, cmtid=0, ln=CFG_SITE_LANG): """Display a note writing form @param uid: user id @param bskid: basket id @param recid: record id (comments are on a specific record in a specific basket) @param cmtid: if provided this comment is a reply to comment cmtid. @param category: selected category @param topic: selected topic @param group_id: selected group id @param ln: language """ _ = gettext_set_language(ln) optional_params = {} #warnings_rights = [] warnings_html = "" if not check_user_can_comment(uid, bskid): try: raise InvenioWebBasketWarning(_('You do not have permission to write notes to this item.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings_rights = ['WRN_WEBBASKET_RESTRICTED_WRITE_NOTES'] warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) else: if cmtid and db.note_belongs_to_item_in_basket_p(cmtid, recid, bskid): optional_params["Add note"] = db.get_note(cmtid) optional_params["Reply to"] = cmtid elif cmtid: optional_params["Add note"] = () try: raise InvenioWebBasketWarning(_('The note you are quoting does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') optional_params["Warnings"] = exc.message else: optional_params["Add note"] = () (body, warnings, navtrail) = perform_request_display(uid=uid, selected_category=category, selected_topic=topic, selected_group_id=group_id, selected_bskid=bskid, selected_recid=recid, optional_params=optional_params, of='hb', ln=CFG_SITE_LANG) if not warnings: body = warnings_html + body #warnings = warnings_rights return (body, navtrail) def perform_request_save_note(uid, category=CFG_WEBBASKET_CATEGORIES['PRIVATE'], topic="", group_id=0, bskid=0, recid=0, note_title="", note_body="", editor_type='textarea', ln=CFG_SITE_LANG, reply_to=None): """ Save a given comment if able to. @param uid: user id (int) @param bskid: basket id (int) @param recid: record id (int) @param title: title of comment (string) @param text: comment's body (string) @param ln: language (string) @param editor_type: the kind of editor/input used for the comment: 'textarea', 'ckeditor' @param reply_to: the id of the comment we are replying to """ _ = gettext_set_language(ln) optional_params = {} #warnings_rights = [] warnings_html = "" if not check_user_can_comment(uid, bskid): try: raise InvenioWebBasketWarning(_('You do not have permission to write notes to this item.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings_rights = exc.message #warnings_rights = ['WRN_WEBBASKET_RESTRICTED_WRITE_NOTES'] warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) else: if not note_title or \ ((not note_body and editor_type != 'ckeditor') or \ (not remove_html_markup(note_body, '').replace('\n', '').replace('\r', '').strip() and editor_type == 'ckeditor')): optional_params["Incomplete note"] = (note_title, note_body) try: raise InvenioWebBasketWarning(_('You must fill in both the subject and the body of the note.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') optional_params["Warnings"] = exc.message else: if editor_type == 'ckeditor': # Here we remove the line feeds introduced by CKEditor (they # have no meaning for the user) and replace the HTML line # breaks by linefeeds, so that we are close to an input that # would be done without the CKEditor. That's much better if a # reply to a comment is made with a browser that does not # support CKEditor. note_body = note_body.replace('\n', '').replace('\r', '').replace('<br />', '\n') if not(db.save_note(uid, bskid, recid, note_title, note_body, reply_to)): # TODO: The note could not be saved. DB problem? pass else: # TODO: inform about successful annotating. pass (body, warnings, navtrail) = perform_request_display(uid=uid, selected_category=category, selected_topic=topic, selected_group_id=group_id, selected_bskid=bskid, selected_recid=recid, optional_params=optional_params, of='hb', ln=CFG_SITE_LANG) if not warnings: body = warnings_html + body #warnings = warnings_rights return (body, navtrail) def perform_request_delete_note(uid, category=CFG_WEBBASKET_CATEGORIES['PRIVATE'], topic="", group_id=0, bskid=0, recid=0, cmtid=0, ln=CFG_SITE_LANG): """Delete comment cmtid on record recid for basket bskid.""" _ = gettext_set_language(ln) #warnings_notes = [] warnings_html = "" if not __check_user_can_perform_action(uid, bskid, CFG_WEBBASKET_SHARE_LEVELS['DELCMT']): try: raise InvenioWebBasketWarning(_('You do not have permission to delete this note.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings_notes.append(exc.message) #warnings_notes.append('WRN_WEBBASKET_RESTRICTED_DELETE_NOTES') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) else: if cmtid and db.note_belongs_to_item_in_basket_p(cmtid, recid, bskid): db.delete_note(bskid, recid, cmtid) else: try: raise InvenioWebBasketWarning(_('The note you are deleting does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings_notes.append(exc.message) #warnings_notes.append('WRN_WEBBASKET_DELETE_INVALID_NOTE') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) (body, warnings, navtrail) = perform_request_display(uid=uid, selected_category=category, selected_topic=topic, selected_group_id=group_id, selected_bskid=bskid, selected_recid=recid, of='hb', ln=CFG_SITE_LANG) body = warnings_html + body #warnings.extend(warnings_notes) return (body, navtrail) def perform_request_add(uid, recids=[], category='', bskid=0, colid=0, es_title='', es_desc='', es_url='', note_body='', editor_type='', b='', successful_add=False, copy=False, wait=False, referer='', ln=CFG_SITE_LANG): """Add records to baskets @param uid: user id @param recids: list of records to add @param colid: in case of external collections, the id of the collection the records belong to @param bskids: list of baskets to add records to. if not provided, will return a page where user can select baskets @param es_title: the title of the external source @param es_desc: the description of the external source @param es_url: the url of the external source @param referer: URL of the referring page @param ln: language""" _ = gettext_set_language(ln) if successful_add: body = webbasket_templates.tmpl_add(recids=recids, category=category, bskid=bskid, colid=colid, successful_add=True, copy=copy, referer=referer, ln=ln) #warnings = [] navtrail = create_webbasket_navtrail(uid, add_to_basket=True, ln=ln) return (body, navtrail) #warnings = [] warnings_html = "" if type(recids) is not list: recids = [recids] validated_recids = [] if colid == 0: # Local records for recid in recids: recid = int(recid) if recid > 0 and record_exists(recid) == 1: validated_recids.append(recid) elif recid < 0 and copy: # if we are copying a record, colid will always be 0 but we may # still get negative recids when it comes to external items. # In that case, we just skip the checking and add them directly # to the validated_recids. validated_recids.append(recid) user_info = collect_user_info(uid) recids_to_remove = [] for recid in validated_recids: (auth_code, dummy) = check_user_can_view_record(user_info, recid) if auth_code: # User is not authorized to view record. # We should not remove items from the list while we parse it. # Better store them in another list and in the end remove them. #validated_recids.remove(recid) recids_to_remove.append(recid) try: raise InvenioWebBasketWarning(_('Sorry, you do not have sufficient rights to add record #%i.') % recid) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append(('WRN_WEBBASKET_NO_RIGHTS_TO_ADD_THIS_RECORD', recid)) try: raise InvenioWebBasketWarning(_('Some of the items were not added due to lack of sufficient rights.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') warnings_html = webbasket_templates.tmpl_warnings(exc.message, ln) #warnings_html = webbasket_templates.tmpl_warnings('WRN_WEBBASKET_NO_RIGHTS_TO_ADD_RECORDS', ln) for recid in recids_to_remove: validated_recids.remove(recid) elif colid > 0: # External records, no need to validate. validated_recids.extend(recids) elif colid == -1: # External source. es_warnings = [] if not es_title: try: raise InvenioWebBasketWarning(_('Please provide a title for the external source.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') es_warnings.append(exc.message) if not es_desc: try: raise InvenioWebBasketWarning(_('Please provide a description for the external source.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') es_warnings.append(exc.message) if not es_url: try: raise InvenioWebBasketWarning(_('Please provide a url for the external source.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') es_warnings.append(exc.message) else: (is_valid, status, dummy) = url_is_valid(es_url) if not is_valid: if str(status).startswith('0'): try: raise InvenioWebBasketWarning(_('The url you have provided is not valid.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') es_warnings.append(exc.message) #es_warnings.append('WRN_WEBBASKET_NO_VALID_URL_0') elif str(status).startswith('4'): try: raise InvenioWebBasketWarning(_('The url you have provided is not valid: The request contains bad syntax or cannot be fulfilled.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') es_warnings.append(exc.message) #es_warnings.append('WRN_WEBBASKET_NO_VALID_URL_4') elif str(status).startswith('5'): try: raise InvenioWebBasketWarning(_('The url you have provided is not valid: The server failed to fulfil an apparently valid request.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') es_warnings.append(exc.message) #es_warnings.append('WRN_WEBBASKET_NO_VALID_URL_5') elif not (es_url.startswith("http://") or es_url.startswith("https://")): es_url = "http://" + es_url if es_warnings: #warnings.extend(es_warnings) warnings_html += webbasket_templates.tmpl_warnings(es_warnings, ln) if not validated_recids: # in case there are no record ids select assume we want to add an # external source. colid = -1 # This part of code is under the current circumstances never ran, # since if there no validated_recids, colid is set to -1. # IDEA: colid should by default (i.e. when not set) be -2 and when local # recids are added we should use the 0 value. #if not validated_recids and colid >= 0: # warnings.append('WRN_WEBBASKET_NO_RECORD') # body += webbasket_templates.tmpl_warnings(warnings, ln) # if referer and not(referer.find(CFG_SITE_URL) == -1): # body += webbasket_templates.tmpl_back_link(referer, ln) # return (body, warnings) if b or (category and bskid): # if b was not defined we use category and bskid to construct it. if not b: b = category + "_" + str(bskid) # we extract the category and the bskid from the washed b POST variable # or the constracted b variable from category and bskid. (category, b_bskid, b_warnings) = wash_b_add(b) # if there were warnings it means there was a bad input. # Send the warning to the user and return the page. if b_warnings: #warnings.extend(b_warnings) warnings_html += webbasket_templates.tmpl_warnings(b_warnings, ln) if not b_warnings: (bskid, b_warnings) = wash_bskid(uid, category, b_bskid) if b_warnings: #warnings.extend(b_warnings) warnings_html += webbasket_templates.tmpl_warnings(b_warnings, ln) if not b_warnings: if not(__check_user_can_perform_action(uid, bskid, CFG_WEBBASKET_SHARE_LEVELS['ADDITM'])): try: raise InvenioWebBasketWarning(_('Sorry, you do not have sufficient rights on this basket.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_NO_RIGHTS') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) if not warnings_html: if ( colid >= 0 and not validated_recids ) or ( colid == -1 and ( not es_title or not es_desc or not es_url ) ): try: raise InvenioWebBasketWarning(_('No records to add.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) if not warnings_html and not wait: if colid == -1: es_title = es_title es_desc = nl2br(es_desc) added_items = db.add_to_basket(uid, validated_recids, colid, bskid, es_title, es_desc, es_url) if added_items: if (note_body and editor_type != 'ckeditor') or \ (editor_type == 'ckeditor' and \ remove_html_markup(note_body, '').replace('\n', '').replace('\r', '').strip()): if editor_type == 'ckeditor': # Here we remove the line feeds introduced by CKEditor (they # have no meaning for the user) and replace the HTML line # breaks by linefeeds, so that we are close to an input that # would be done without the CKEditor. That's much better if a # reply to a comment is made with a browser that does not # support CKEditor. note_title = '' note_body = note_body.replace('\n', '').replace('\r', '').replace('<br />', '\n') else: note_title = '' for recid in added_items: if not(db.save_note(uid, bskid, recid, note_title, note_body, reply_to=None)): # TODO: The note could not be saved. DB problem? pass if colid > 0: format_external_records(added_items, of="xm") return perform_request_add(uid=uid, recids=recids, category=category, bskid=bskid, colid=colid, successful_add=True, copy=copy, referer=referer) else: try: raise InvenioWebBasketWarning(_('Cannot add items to the selected basket. Invalid parameters.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_INVALID_ADD_TO_PARAMETERS') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) personal_basket_list = db.get_all_user_personal_basket_ids_by_topic(uid) group_basket_list = db.get_all_user_group_basket_ids_by_group_with_add_rights(uid) if not personal_basket_list and not group_basket_list: bskid = db.create_basket(uid=uid, basket_name=_('Untitled basket'), topic=_('Untitled topic')) try: raise InvenioWebBasketWarning(_('A default topic and basket have been automatically created. Edit them to rename them as you see fit.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_DEFAULT_TOPIC_AND_BASKET') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) if colid >= 0 and validated_recids: (body, navtrail) = perform_request_add(uid=uid, recids=validated_recids, category=CFG_WEBBASKET_CATEGORIES['PRIVATE'], bskid=bskid, colid=colid, referer=referer, ln=ln) body = warnings_html + body return (body, navtrail) else: personal_basket_list = db.get_all_user_personal_basket_ids_by_topic(uid) body = webbasket_templates.tmpl_add(recids=recids, category=category, bskid=bskid, colid=colid, es_title=es_title, es_desc=es_desc, es_url=es_url, note_body=note_body, personal_basket_list=personal_basket_list, group_basket_list=group_basket_list, copy=copy, referer=referer, ln=ln) body = warnings_html + body navtrail = create_webbasket_navtrail(uid, add_to_basket=True, ln=ln) return (body, navtrail) def perform_request_delete(uid, bskid, confirmed=0, category=CFG_WEBBASKET_CATEGORIES['PRIVATE'], selected_topic="", selected_group_id=0, ln=CFG_SITE_LANG): """Delete a given basket. @param uid: user id (user has to be owner of this basket) @param bskid: basket id @param confirmed: if 0 will return a confirmation page; if 1 will delete basket. @param category: category currently displayed @param selected_topic: topic currently displayed @param selected_group_id: if category is group, id of the group currently displayed @param ln: language""" _ = gettext_set_language(ln) body = '' #warnings = [] if not(db.check_user_owns_baskets(uid, [bskid])): try: raise InvenioWebBasketWarning(_('Sorry, you do not have sufficient rights on this basket.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append(('WRN_WEBBASKET_NO_RIGHTS',)) return body if confirmed: if not db.delete_basket(bskid): # TODO: The item was not deleted. DB problem? pass else: body = webbasket_templates.tmpl_confirm_delete(bskid, db.count_subscribers(uid, bskid), category, selected_topic, selected_group_id, ln) return body def delete_record(uid, bskid, recid): """Delete a given record in a given basket. @param uid: user id (user has to have sufficient rights on basket @param bskid: basket id @param recid: record id """ if __check_user_can_perform_action(uid, bskid, CFG_WEBBASKET_SHARE_LEVELS['DELITM']): db.delete_item(bskid, recid) def move_record(uid, bskid, recid, direction): """Move a record up or down in a basket (change score). @param uid: user id (user has to have manage rights over this basket) @param bskid: basket id @param recid: record we want to move @param direction: CFG_WEBBASKET_ACTIONS['UP'] or CFG_WEBBASKET_ACTIONS['DOWN'] """ if __check_user_can_perform_action(uid, bskid, CFG_WEBBASKET_SHARE_LEVELS['MANAGE']): db.move_item(bskid, recid, direction) def perform_request_edit(uid, bskid, topic="", new_name='', new_topic = '', new_topic_name='', groups=[], external='', ln=CFG_SITE_LANG): """Interface for management of basket. If names, groups or external is provided, will save new rights into database, else will provide interface. @param uid: user id (user has to have sufficient rights on this basket @param bskid: basket id to change rights on @param topic: topic currently used (int) @param new_name: new name of basket @param new_topic: topic in which to move basket (int), new_topic_name must be left blank @param new_topic_name: new topic in which to move basket (will overwrite param new_topic) @param groups: list of strings formed in this way: group_id + '_' + rights @param external: rights for everybody (can be 'NO') @param ln: language """ body = '' #warnings = [] # TODO: external rights must be washed, it can only be one of the following: # NO, READITM, READCMT, ADDCMT _ = gettext_set_language(ln) rights = db.get_max_user_rights_on_basket(uid, bskid) if rights != CFG_WEBBASKET_SHARE_LEVELS['MANAGE']: try: raise InvenioWebBasketWarning(_('Sorry, you do not have sufficient rights on this basket.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append(('WRN_WEBBASKET_NO_RIGHTS',)) return body bsk_name = db.get_basket_name(bskid) if not(groups) and not(external) and not(new_name) and not(new_topic) and not(new_topic_name): # display interface topics = map(lambda x: x[0], db.get_personal_topics_infos(uid)) groups_rights = db.get_groups_subscribing_to_basket(bskid) external_rights = '' if groups_rights and groups_rights[0][0] == 0: external_rights = groups_rights[0][2] groups_rights = groups_rights[1:] display_delete = db.check_user_owns_baskets(uid, bskid) display_general = display_delete if isGuestUser(uid): display_sharing = 0 else: display_sharing = 1 body = webbasket_templates.tmpl_edit(bskid=bskid, bsk_name=bsk_name, display_general=display_general, topics=topics, topic=topic, display_delete=display_delete, display_sharing=display_sharing, groups_rights=groups_rights, external_rights=external_rights, ln=ln) else: out_groups = {} if len(groups): for group in groups: (group_id, group_rights) = group.split('_') out_groups[group_id] = group_rights out_groups['0'] = external if not(isGuestUser(uid)): db.update_rights(bskid, out_groups) if new_name != bsk_name: db.rename_basket(bskid, new_name) if new_topic_name: db.move_baskets_to_topic(uid, bskid, new_topic_name) elif not (new_topic == "-1" or new_topic == topic): if db.check_user_owns_baskets(uid, bskid): topics = map(lambda x: x[0], db.get_personal_topics_infos(uid)) if new_topic in topics: new_topic_name = new_topic db.move_baskets_to_topic(uid, bskid, new_topic_name) else: # TODO: inform the admin #errors.append(('ERR_WEBBASKET_DB_ERROR')) pass else: topic = "" #warnings.append(('ERR_WEBBASKET_NOT_OWNER')) return body def perform_request_edit_topic(uid, topic='', new_name='', ln=CFG_SITE_LANG): """Interface for editing of topic. @param uid: user id (user has to have sufficient rights on this basket @param topic: topic to be edited @param new_name: new name of topic @param ln: language """ body = '' #warnings = [] #rights = db.get_max_user_rights_on_basket(uid, bskid) #if rights != CFG_WEBBASKET_SHARE_LEVELS['MANAGE']: # errors.append(('ERR_WEBBASKET_NO_RIGHTS',)) # return (body, errors, warnings) if not(new_name): # display interface #display_delete = db.check_user_owns_baskets(uid, bskid) #display_general = display_delete #if isGuestUser(uid): #display_sharing = 0 #else: #display_sharing = 1 display_general = True display_delete = True body = webbasket_templates.tmpl_edit_topic(display_general=display_general, topic=topic, display_delete=display_delete, ln=ln) else: if cgi.escape(new_name, True) != cgi.escape(topic, True): db.rename_topic(uid, topic, new_name) return body def perform_request_add_group(uid, bskid, topic="", group_id=0, ln=CFG_SITE_LANG): """If group id is specified, share basket bskid to this group with READITM rights; else return a page for selection of a group. @param uid: user id (selection only of groups user is member of) @param bskid: basket id @param topic: topic currently displayed @param group_id: id of group to share basket to @param ln: language """ if group_id: db.share_basket_with_group(bskid, group_id, CFG_WEBBASKET_SHARE_LEVELS['READITM']) else: groups = db.get_groups_user_member_of(uid) body = webbasket_templates.tmpl_add_group(bskid, topic, groups, ln) return body def perform_request_create_basket(req, uid, new_basket_name='', new_topic_name='', create_in_topic="-1", topic="-1", recids=[], colid=-1, es_title='', es_desc='', es_url='', ln=CFG_SITE_LANG): """if new_basket_name and topic infos are given create a basket and return topic number, else return body with warnings of basket creation form. @param req: request object for obtaining URL of the referring page @param uid: user id (int) @param new_basket_name: name of the basket to create (str) @param new_topic_name: name of new topic to create new basket in (str) @param create_in_topic: identification number of topic to create new basket in (int) @param topic: topic to preselect on the creation form. @pram ln: language """ warnings = [] warnings_html = "" _ = gettext_set_language(ln) if new_basket_name and (new_topic_name or create_in_topic != "-1"): #topics_infos = map(lambda x: x[0], db.get_personal_topics_infos(uid)) new_topic_name = new_topic_name.strip() if new_topic_name: topic = new_topic_name else: topic = create_in_topic bskid = db.create_basket(uid, new_basket_name, topic) #topics = map(lambda x: x[0], topics_infos) return (bskid, topic) else: referer = get_referer(req) # URL of the referring page url = CFG_SITE_URL + '/yourbaskets/create_basket' import string if string.find(referer, url) == 0: if not new_basket_name: try: raise InvenioWebBasketWarning(_('Please provide a name for the new basket.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning', req=req) warnings.append(exc.message) if (not new_topic_name and create_in_topic == "-1"): try: raise InvenioWebBasketWarning(_('Please select an existing topic or create a new one.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning', req=req) warnings.append(exc.message) topics = map(lambda x: x[0], db.get_personal_topics_infos(uid)) if topic in topics: create_in_topic = topic body = webbasket_templates.tmpl_create_basket(new_basket_name, new_topic_name, create_in_topic, topics, recids, colid, es_title, es_desc, es_url, ln) if warnings: warnings_html += webbasket_templates.tmpl_warnings(warnings, ln) body = warnings_html + body return body def perform_request_subscribe(uid, bskid, ln=CFG_SITE_LANG): """Subscribes user to the given public basket. Returns warnings if there were any.""" _ = gettext_set_language(ln) #warnings = [] warnings_html = "" if db.is_basket_public(bskid): if not db.subscribe(uid, bskid): try: raise InvenioWebBasketWarning(_('You cannot subscribe to this basket, you are the either owner or you have already subscribed.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_CAN_NOT_SUBSCRIBE') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) else: try: raise InvenioWebBasketWarning(_('The selected public basket does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_INVALID_OR_RESTRICTED_PUBLIC_BASKET') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) return warnings_html def perform_request_unsubscribe(uid, bskid, ln=CFG_SITE_LANG): """Unsubscribes user from the given public basket. Returns warnings if there were any.""" _ = gettext_set_language(ln) #warnings = [] warnings_html = "" if db.is_basket_public(bskid): if not db.unsubscribe(uid, bskid): try: raise InvenioWebBasketWarning(_('You cannot unsubscribe from this basket, you are the either owner or you have already unsubscribed.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_CAN_NOT_UNSUBSCRIBE') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) else: try: raise InvenioWebBasketWarning(_('The selected public basket does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') #warnings.append(exc.message) #warnings.append('WRN_WEBBASKET_INVALID_OR_RESTRICTED_PUBLIC_BASKET') warnings_html += webbasket_templates.tmpl_warnings(exc.message, ln) return warnings_html def check_user_can_comment(uid, bskid): """ Private function. check if a user can comment """ min_right = CFG_WEBBASKET_SHARE_LEVELS['ADDCMT'] rights = db.get_max_user_rights_on_basket(uid, bskid) if rights: if CFG_WEBBASKET_SHARE_LEVELS_ORDERED.index(rights) >= CFG_WEBBASKET_SHARE_LEVELS_ORDERED.index(min_right): return 1 return 0 def __check_user_can_perform_action(uid, bskid, rights): """ Private function, check if a user has sufficient rights""" min_right = rights rights = db.get_max_user_rights_on_basket(uid, bskid) if rights: if CFG_WEBBASKET_SHARE_LEVELS_ORDERED.index(rights) >= CFG_WEBBASKET_SHARE_LEVELS_ORDERED.index(min_right): return 1 return 0 def check_sufficient_rights(rights_user_has, rights_needed): """Private function, check if the rights are sufficient.""" try: out = CFG_WEBBASKET_SHARE_LEVELS_ORDERED.index(rights_user_has) >= \ CFG_WEBBASKET_SHARE_LEVELS_ORDERED.index(rights_needed) except ValueError: out = 0 return out def can_add_notes_to_public_basket_p(bskid): """ Private function. Checks if notes can be added to the given public basket.""" min_right = CFG_WEBBASKET_SHARE_LEVELS['ADDCMT'] rights = db.get_rights_on_public_basket(bskid) if rights: if CFG_WEBBASKET_SHARE_LEVELS_ORDERED.index(rights[0][0]) >= CFG_WEBBASKET_SHARE_LEVELS_ORDERED.index(min_right): return True return False def create_guest_warning_box(ln=CFG_SITE_LANG): """return a warning message about logging into system""" return webbasket_templates.tmpl_create_guest_warning_box(ln) def create_personal_baskets_selection_box(uid, html_select_box_name='baskets', selected_bskid=None, ln=CFG_SITE_LANG): """Return HTML box for basket selection. Only for personal baskets. @param uid: user id @param html_select_box_name: name used in html form @param selected_bskid: basket currently selected @param ln: language """ baskets = db.get_all_personal_baskets_names(uid) return webbasket_templates.tmpl_personal_baskets_selection_box( baskets, html_select_box_name, selected_bskid, ln) def create_basket_navtrail(uid, category=CFG_WEBBASKET_CATEGORIES['PRIVATE'], topic="", group=0, bskid=0, ln=CFG_SITE_LANG): """display navtrail for basket navigation. @param uid: user id (int) @param category: selected category (see CFG_WEBBASKET_CATEGORIES) @param topic: selected topic if personal baskets @param group: selected group id for displaying (int) @param bskid: basket id (int) @param ln: language""" _ = gettext_set_language(ln) out = '' if category == CFG_WEBBASKET_CATEGORIES['PRIVATE']: category_html = """ > <a class="navtrail" href="%s/yourbaskets/display?%s">%s</a>""" % \ (CFG_SITE_URL, 'category=' + category + '&ln=' + ln, _("Personal baskets")) out += category_html topics = map(lambda x: x[0], db.get_personal_topics_infos(uid)) if topic in topics: topic_html = """ > <a class="navtrail" href="%s/yourbaskets/display?%s">%s</a>""" % \ (CFG_SITE_URL, 'category=' + category + '&topic=' + \ urllib.quote(topic) + '&ln=' + ln, cgi.escape(topic)) out += topic_html if bskid: basket = db.get_public_basket_infos(bskid) if basket: basket_html = """ > <a class="navtrail" href="%s/yourbaskets/display?%s">%s</a>""" % \ (CFG_SITE_URL, 'category=' + category + '&topic=' + \ urllib.quote(topic) + '&ln=' + ln + '#bsk' + str(bskid), cgi.escape(basket[1])) out += basket_html elif category == CFG_WEBBASKET_CATEGORIES['GROUP']: category_html = """ > <a class="navtrail" href="%s/yourbaskets/display?%s">%s</a>""" % \ (CFG_SITE_URL, 'category=' + category + '&ln=' + ln, _("Group baskets")) out += category_html groups = db.get_group_infos(uid) if group: groups = filter(lambda x: x[0] == group, groups) if len(groups): group_html = """ > <a class="navtrail" href="%s/yourbaskets/display?%s">%s</a>""" % \ (CFG_SITE_URL, 'category=' + category + '&group=' + \ str(group) + '&ln=' + ln, cgi.escape(groups[0][1])) out += group_html if bskid: basket = db.get_public_basket_infos(bskid) if basket: basket_html = """ > <a class="navtrail" href="%s/yourbaskets/display?%s">%s</a>""" % \ (CFG_SITE_URL, 'category=' + category + '&group=' + \ str(group) + '&ln=' + ln + '#bsk' + str(bskid), cgi.escape(basket[1])) out += basket_html elif category == CFG_WEBBASKET_CATEGORIES['EXTERNAL']: category_html = """ > <a class="navtrail" href="%s/yourbaskets/display?%s">%s</a>""" % \ (CFG_SITE_URL, 'category=' + category + '&ln=' + ln, _("Others' baskets")) out += category_html if bskid: basket = db.get_public_basket_infos(bskid) if basket: basket_html = """ > <a class="navtrail" href="%s/yourbaskets/display?%s">""" % \ (CFG_SITE_URL, 'category=' + category + '&ln=' + ln + \ '#bsk' + str(bskid), cgi.escape(basket[1])) out += basket_html return out def create_webbasket_navtrail(uid, category="", topic="", group=0, bskid=0, public_basket=False, search_baskets=False, add_to_basket=False, ln=CFG_SITE_LANG): """Create the navtrail for navigation withing WebBasket. @param uid: user id (int) @param category: selected category (see CFG_WEBBASKET_CATEGORIES) @param topic: selected topic (str) @param group: selected group (int) @param bskid: selected basket id (int) @param ln: language""" _ = gettext_set_language(ln) out = """<a class="navtrail" href="%s/youraccount/display?ln=%s">%s</a>""" % \ (CFG_SITE_URL, ln, _("Your Account")) out += " > " out += """<a class="navtrail" href="%s/yourbaskets/display?ln=%s">%s</a>""" % \ (CFG_SITE_URL, ln, _("Your Baskets")) if public_basket: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/list_public_baskets?ln=%s">%s</a>""" % \ (CFG_SITE_URL, ln, _("List of public baskets")) if bskid: basket = db.get_basket_name(bskid) if basket: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/display_public?bskid=%i&ln=%s">%s</a>""" % \ (CFG_SITE_URL, bskid, ln, cgi.escape(basket, True)) elif search_baskets: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/search?ln=%s">%s</a>""" % \ (CFG_SITE_URL, ln, _("Search baskets")) elif add_to_basket: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/add?ln=%s">%s</a>""" % \ (CFG_SITE_URL, ln, _("Add to basket")) else: if category == CFG_WEBBASKET_CATEGORIES['PRIVATE']: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/display?category=%s&ln=%s">%s</a>""" % \ (CFG_SITE_URL, CFG_WEBBASKET_CATEGORIES['PRIVATE'], ln, _("Personal baskets")) if topic: topic_names = map(lambda x: x[0], db.get_personal_topics_infos(uid)) if topic in topic_names: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/display?category=%s&topic=%s&ln=%s">%s</a>""" % \ (CFG_SITE_URL, CFG_WEBBASKET_CATEGORIES['PRIVATE'], urllib.quote(topic), ln, cgi.escape(topic, True)) if bskid: basket = db.get_basket_name(bskid) if basket: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/display?category=%s&topic=%s&bskid=%i&ln=%s">%s</a>""" % \ (CFG_SITE_URL, CFG_WEBBASKET_CATEGORIES['PRIVATE'], urllib.quote(topic), bskid, ln, cgi.escape(basket, True)) elif category == CFG_WEBBASKET_CATEGORIES['GROUP']: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/display?category=%s&ln=%s">%s</a>""" % \ (CFG_SITE_URL, CFG_WEBBASKET_CATEGORIES['GROUP'], ln, _("Group baskets")) if group: group_names = map(lambda x: x[0] == group and x[1], db.get_group_infos(uid)) if group_names and group_names[0]: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/display?category=%s&group=%i&ln=%s">%s</a>""" % \ (CFG_SITE_URL, CFG_WEBBASKET_CATEGORIES['GROUP'], group, ln, cgi.escape(group_names[0], True)) if bskid: basket = db.get_basket_name(bskid) if basket: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/display?category=%s&topic=%s&bskid=%i&ln=%s">%s</a>""" % \ (CFG_SITE_URL, CFG_WEBBASKET_CATEGORIES['GROUP'], group, bskid, ln, cgi.escape(basket, True)) elif category == CFG_WEBBASKET_CATEGORIES['EXTERNAL']: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/display?category=%s&ln=%s">%s</a>""" % \ (CFG_SITE_URL, category, ln, _("Public baskets")) if bskid: basket = db.get_basket_name(bskid) if basket: out += " > " out += """<a class="navtrail" href="%s/yourbaskets/display?category=%s&topic=%s&bskid=%i&ln=%s">%s</a>""" % \ (CFG_SITE_URL, category, group, bskid, ln, cgi.escape(basket, True)) return out def account_list_baskets(uid, ln=CFG_SITE_LANG): """Display baskets informations on account page""" _ = gettext_set_language(ln) (personal, group, external) = db.count_baskets(uid) link = '<a href="%s">%s</a>' base_url = CFG_SITE_URL + '/yourbaskets/display?category=%s&ln=' + ln personal_text = personal if personal: url = base_url % CFG_WEBBASKET_CATEGORIES['PRIVATE'] personal_text = link % (url, personal_text) group_text = group if group: url = base_url % CFG_WEBBASKET_CATEGORIES['GROUP'] group_text = link % (url, group_text) external_text = external if external: url = base_url % CFG_WEBBASKET_CATEGORIES['EXTERNAL'] else: url = CFG_SITE_URL + '/yourbaskets/list_public_baskets?ln=' + ln external_text = link % (url, external_text) out = _("You have %(x_nb_perso)s personal baskets and are subscribed to %(x_nb_group)s group baskets and %(x_nb_public)s other users public baskets.") %\ {'x_nb_perso': personal_text, 'x_nb_group': group_text, 'x_nb_public': external_text} return out def page_start(req, of='xm'): """Set the content type and send the headers for the page.""" if of.startswith('x'): req.content_type = "text/xml" if of == 'xr': req.content_type = "application/rss+xml" req.send_http_header() req.write("""<?xml version="1.0" encoding="UTF-8"?>\n""") print_records_prologue(req, of) else: # assuming HTML by default req.content_type = "text/html" req.send_http_header() def page_end(req, of='xm'): """Print page footer""" if of.startswith('x'): print_records_epilogue(req, of) def perform_request_export_xml(body): """Export an xml representation of the selected baskets/items.""" return webbasket_templates.tmpl_export_xml(body) ################################ ### External items functions ### ################################ def format_external_records(recids, of='hb'): """Given a list of external records' recids, this function returns a list of tuples with each recid and the actual formatted record using the selected output format. It also stores the formatted record in the database for future use.""" # TODO: add a returnp variable to control whether we actually want anything # to be returned or not. For example when we just want to store the xml # formatted records for newly added items. # TODO: take care of external urls. Invent an xml format for them. # NOTE: this function is meant to format external records from other # libraries. It's not meant to handle custom external sources like urls # submitted manually by the user. These items are directly formatted and # stored by the add_to_basket database function. formatted_records = [] if type(recids) is not list: recids = [recids] existing_xml_formatted_records = db.get_external_records(recids, "xm") for existing_xml_formatted_record in existing_xml_formatted_records: xml_record = decompress(existing_xml_formatted_record[2]) xml_record_id = existing_xml_formatted_record[1] xml_record_colid = existing_xml_formatted_record[0] recids.remove(-xml_record_id) if of == "hb": if xml_record_colid > 0: htmlbrief_record = format_record(None, of, xml_record=xml_record) formatted_records.append((xml_record_id, htmlbrief_record)) elif of != "hb": #formatted_records.append((xml_record_id, xml_record)) formatted_records.append((xml_record_id, format_record([], of, xml_record=xml_record, on_the_fly=True))) # formatted_records.append((xml_record_id, repr(xml_record))) if formatted_records and of == "hb": db.store_external_records(formatted_records, of) records_grouped_by_collection = db.get_external_records_by_collection(recids) if records_grouped_by_collection: for records in records_grouped_by_collection: colid = records[2] if colid: external_records = fetch_and_store_external_records(records, of) formatted_records.extend(external_records) return formatted_records def fetch_and_store_external_records(records, of="hb"): """Function that fetches the formatted records for one collection and stores them into the database. It also calculates and stores the original external url for each record.""" results = [] formatted_records = [] if of == 'xm': re_controlfield = re.compile(r'<controlfield\b[^>]*>.*?</controlfield>', re.DOTALL + re.MULTILINE + re.IGNORECASE) re_blankline = re.compile(r'\s*\n', re.DOTALL + re.MULTILINE + re.IGNORECASE) # the locally saved external ids local_ext_ids = records[0].split(",") # the locally saved original external ids external_ids = records[1].split(",") collection_name = get_collection_name_by_id(records[2]) collection_engine_set = select_hosted_search_engines(collection_name) collection_engine = collection_engine_set.pop() external_ids_urls = collection_engine.build_record_urls(external_ids) external_urls = [external_id_url[1] for external_id_url in external_ids_urls] #external_urls_dict = {} #for (local_id, url) in zip(local_ext_ids, external_urls): #external_urls_dict[local_id] = url #db.store_external_urls(external_urls_dict) db.store_external_urls(zip(local_ext_ids, external_urls)) url = collection_engine.build_search_url(None, req_args=external_ids) pagegetters = [HTTPAsyncPageGetter(url)] def finished(pagegetter, dummy_data, dummy_time): """Function to be called when a page has been downloaded.""" results.append(pagegetter) finished_list = async_download(pagegetters, finish_function=finished, timeout=CFG_EXTERNAL_COLLECTION_TIMEOUT) if finished_list[0]: collection_engine.parser.parse_and_get_results(results[0].data, feedonly=True) (dummy, parsed_results_dict) = collection_engine.parser.parse_and_extract_records(of=of) for (local_ext_id, external_id) in zip(local_ext_ids, external_ids): formatted_record = parsed_results_dict[external_id] if of == 'xm': formatted_record = re_controlfield.sub('', formatted_record) formatted_record = re_blankline.sub('\n', formatted_record) formatted_records.append((int(local_ext_id), formatted_record)) db.store_external_records(formatted_records, of) else: for (local_ext_id, external_id) in zip(local_ext_ids, external_ids): formatted_records.append((int(local_ext_id), "There was a timeout when fetching the record.")) return formatted_records ############################### ### Miscellaneous functions ### ############################### def url_is_valid(url): """Returns (True, status, reason) if the url is valid or (False, status, reason) if different.""" common_errors_list = [400, 404, 500] url_tuple = urlsplit(url) if not url_tuple[0]: url = "http://" + url url_tuple = urlsplit(url) if not url_tuple[0] and not url_tuple[1]: return (False, 000, "Not Valid") # HTTPConnection had the timeout parameter introduced in python 2.6 # for the older versions we have to get and set the default timeout # In order to use a custom timeout pass it as an extra argument to this function #old_timeout = getdefaulttimeout() #setdefaulttimeout(timeout) conn = HTTPConnection(url_tuple[1]) #setdefaulttimeout(old_timeout) try: conn.request("GET", url_tuple[2]) except: return (False, 000, "Not Valid") response = conn.getresponse() status = response.status reason = response.reason if str(status).startswith('1') or str(status).startswith('2') or str(status).startswith('3'): return (True, status, reason) elif str(status).startswith('4') or str(status).startswith('5'): if status in common_errors_list: return (False, status, reason) else: return (True, status, reason) def nl2br(text): """Replace newlines (\n) found in text with line breaks (<br />).""" return '<br />'.join(text.split('\n')) def wash_b_search(b): """Wash the b GET variable for the search interface.""" _ = gettext_set_language(CFG_SITE_LANG) b = b.split('_', 1) b_category = b[0].upper() valid_categories = CFG_WEBBASKET_CATEGORIES.values() valid_categories.append('') if b_category not in valid_categories: try: raise InvenioWebBasketWarning(_('The category you have selected does not exist. Please select a valid category.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') return ("", "", exc.message) #return ("", "", ['WRN_WEBBASKET_INVALID_CATEGORY']) if len(b) == 2: if b_category == CFG_WEBBASKET_CATEGORIES['PRIVATE'] or b_category == CFG_WEBBASKET_CATEGORIES['GROUP']: return (b_category, b[1], None) # TODO: send a warning when the user has sent a second argument # specifying a category other than PRIVATE or GROUP #else: #return (b_category, "", ['WRN_WEBBASKET_']) return (b_category, "", None) def wash_b_add(b): """Wash the b POST variable for the add interface.""" _ = gettext_set_language(CFG_SITE_LANG) b = b.split('_', 1) b_category = b[0].upper() valid_categories = (CFG_WEBBASKET_CATEGORIES['PRIVATE'], CFG_WEBBASKET_CATEGORIES['GROUP']) if b_category not in valid_categories or len(b) != 2 or not b[1]: try: raise InvenioWebBasketWarning(_('Cannot add items to the selected basket. Invalid parameters.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') return ("", "", exc.message) return (b_category, b[1], None) def wash_category(category): """Wash the category.""" _ = gettext_set_language(CFG_SITE_LANG) category = category.upper() valid_categories = CFG_WEBBASKET_CATEGORIES.values() valid_categories.append('') if category not in valid_categories: try: raise InvenioWebBasketWarning(_('The category you have selected does not exist. Please select a valid category.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') return ("", "", exc.message) #return ("", ['WRN_WEBBASKET_INVALID_CATEGORY']) return (category, None) def wash_topic(uid, topic): """Wash the topic.""" _ = gettext_set_language(CFG_SITE_LANG) if not db.is_topic_valid(uid, topic): try: raise InvenioWebBasketWarning(_('The selected topic does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') return ("", "", exc.message) #return ("", ['WRN_WEBBASKET_INVALID_OR_RESTRICTED_TOPIC']) return (topic, None) def wash_group(uid, group): """Wash the topic.""" _ = gettext_set_language(ln=CFG_SITE_LANG) if not group.isdigit() or not db.is_group_valid(uid, group): try: raise InvenioWebBasketWarning(_('The selected group does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') return (0, exc.message) #return (0, ['WRN_WEBBASKET_INVALID_OR_RESTRICTED_GROUP']) return (int(group), None) def wash_bskid(uid, category, bskid): """Wash the bskid based on its category. This function expectes a washed category, either for personal or for group baskets.""" _ = gettext_set_language(CFG_SITE_LANG) if not bskid.isdigit(): try: raise InvenioWebBasketWarning(_('The selected basket does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') return (0, exc.message) #return (0, ['WRN_WEBBASKET_INVALID_OR_RESTRICTED_BASKET']) bskid = int(bskid) if category == CFG_WEBBASKET_CATEGORIES['PRIVATE'] and not db.is_personal_basket_valid(uid, bskid): try: raise InvenioWebBasketWarning(_('The selected basket does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') return (0, exc.message) #return (0, ['WRN_WEBBASKET_INVALID_OR_RESTRICTED_BASKET']) if category == CFG_WEBBASKET_CATEGORIES['GROUP'] and not db.is_group_basket_valid(uid, bskid): try: raise InvenioWebBasketWarning(_('The selected basket does not exist or you do not have access to it.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') return (0, exc.message) #return (0, ['WRN_WEBBASKET_INVALID_OR_RESTRICTED_BASKET']) return (bskid, None) def wash_of(of): """Wash the output format""" _ = gettext_set_language(CFG_SITE_LANG) list_of_accepted_formats = ['hb', 'xm', 'hx', 'xd', 'xe', 'xn', 'xw', 'xr', 'xp'] if of in list_of_accepted_formats: return (of, None) try: raise InvenioWebBasketWarning(_('The selected output format is not available or is invalid.')) except InvenioWebBasketWarning, exc: register_exception(stream='warning') return ('hb', exc.message) def __create_search_box(uid, category="", topic="", grpid=0, p="", n=0, ln=CFG_SITE_LANG): """Private function. Creates the search box and returns html code.""" topic_list = db.get_all_user_topics(uid) group_list = db.get_all_user_groups(uid) number_of_public_baskets = db.count_external_baskets(uid) search_box = webbasket_templates.tmpl_create_search_box(category, topic, grpid, topic_list, group_list, number_of_public_baskets, p, n, ln=ln) return search_box