diff --git a/INSTALL b/INSTALL
index f1ad87d6ea..d016a1df8d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -83,6 +83,9 @@ Contents
natively in UTF-8 mode by setting "default-character-set=utf8"
in various parts of your "my.cnf" file, such as in the
"[mysql]" part and elsewhere; but this is not really required.
+ Note also that you may encounter problems when MySQL is run in
+ "strict mode"; you may want to configure your "my.cnf" in order
+ to avoid using strict mode (such as `STRICT_ALL_TABLES`).
c) Redis server (may be on a remote machine) for user session
@@ -313,6 +316,7 @@ Contents
$ make install
$ make install-mathjax-plugin ## optional
$ make install-jquery-plugins ## optional
+ $ make install-font-awesome ## optional
$ make install-ckeditor-plugin ## optional
$ make install-pdfa-helper-files ## optional
$ make install-mediaelement ## optional
@@ -522,6 +526,16 @@ Contents
Note that `unzip' is needed when installing jquery plugins.
+ $ make install-font-awesome ## optional
+
+ This will automatically download and install Font Awesome,
+ the iconic font and CSS framework.
+
+ Note that in order to include Font Awesome in the HTML head
+ you have to set the CFG_WEBSTYLE_SUPPORT_FONTAWESOME to True
+
+ Note that `unzip' is needed when installing Font Awesome.
+
$ make install-ckeditor-plugin ## optional
This will automatically download and install in the proper
diff --git a/Makefile.am b/Makefile.am
index 6f44617c95..d8f4fb1e95 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,6 @@
# This file is part of Invenio.
-# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 CERN.
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012, 2013, 2014, 2015, 2016 CERN.
#
# Invenio is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
@@ -265,6 +266,38 @@ uninstall-jquery-plugins:
@echo "** The jquery plugins were successfully uninstalled. **"
@echo "***********************************************************"
+install-font-awesome:
+ @echo "***********************************************************"
+ @echo "** Installing Font Awesome, please wait... **"
+ @echo "***********************************************************"
+ rm -rf /tmp/font-awesome
+ mkdir /tmp/font-awesome
+ mkdir -p ${prefix}/var/www/static/css
+ mkdir -p ${prefix}/var/www/static/fonts
+ (cd /tmp/font-awesome && \
+ wget 'https://fortawesome.github.io/Font-Awesome/assets/font-awesome-4.5.0.zip' && \
+ unzip -u font-awesome-4.5.0.zip && \
+ mv font-awesome-4.5.0/css/font-awesome.min.css ${prefix}/var/www/static/css && \
+ mv font-awesome-4.5.0/fonts/* ${prefix}/var/www/static/fonts)
+ rm -rf /tmp/font-awesome
+ @echo "***********************************************************"
+ @echo "** Font Awesome was successfully installed. **"
+ @echo "** It is disabled by default. To enable it, edit **"
+ @echo "** CFG_WEBSTYLE_SUPPORT_FONTAWESOME in invenio.conf. **"
+ @echo "***********************************************************"
+
+uninstall-font-awesome:
+ @rm -vf ${prefix}/var/www/static/css/font-awesome.min.css
+ @rm -vf ${prefix}/var/www/static/fonts/FontAwesome.otf
+ @rm -vf ${prefix}/var/www/static/fonts/fontawesome-webfont.eot
+ @rm -vf ${prefix}/var/www/static/fonts/fontawesome-webfont.svg
+ @rm -vf ${prefix}/var/www/static/fonts/fontawesome-webfont.ttf
+ @rm -vf ${prefix}/var/www/static/fonts/fontawesome-webfont.woff
+ @rm -vf ${prefix}/var/www/static/fonts/fontawesome-webfont.woff2
+ @echo "***********************************************************"
+ @echo "** Font Awesome was successfully uninstalled. **"
+ @echo "***********************************************************"
+
install-ckeditor-plugin:
@echo "***********************************************************"
@echo "** Installing CKeditor plugin, please wait... **"
diff --git a/THANKS b/THANKS
index 1335b512ac..98ebc9d4ca 100644
--- a/THANKS
+++ b/THANKS
@@ -179,4 +179,8 @@ contributed by Yoav Goldberg , new version by
Jason Kirtland from Python cookbook.
+Some icons are used from the iconic font and CSS toolkit
+Font Awesome by Dave Gandy.
+
+
- end of file -
diff --git a/config/invenio.conf b/config/invenio.conf
index 408411ba6a..eccb9322f1 100644
--- a/config/invenio.conf
+++ b/config/invenio.conf
@@ -373,6 +373,10 @@ CFG_WEBSTYLE_CDSPAGEBOXRIGHTTOP =
# HTML right bottom box:
CFG_WEBSTYLE_CDSPAGEBOXRIGHTBOTTOM =
+# CFG_WEBSTYLE_SUPPORT_FONTAWESOME -- enables Font Awesome, the iconic
+# font and CSS framework.
+CFG_WEBSTYLE_SUPPORT_FONTAWESOME = False
+
# CFG_WEBSTYLE_HTTP_STATUS_ALERT_LIST -- when certain HTTP status
# codes are raised to the WSGI handler, the corresponding exceptions
# and error messages can be sent to the system administrator for
diff --git a/modules/bibdocfile/lib/bibdocfile.py b/modules/bibdocfile/lib/bibdocfile.py
index 12598b36ac..0cada52da5 100644
--- a/modules/bibdocfile/lib/bibdocfile.py
+++ b/modules/bibdocfile/lib/bibdocfile.py
@@ -59,6 +59,7 @@
import cgi
import sys
import copy
+import tarfile
if sys.hexversion < 0x2060000:
from md5 import md5
@@ -102,6 +103,7 @@
encode_for_xml
from invenio.urlutils import create_url, make_user_agent_string
from invenio.textutils import nice_size
+from invenio.webuser import collect_user_info
from invenio.access_control_engine import acc_authorize_action
from invenio.access_control_admin import acc_is_user_in_role, acc_get_role_id
from invenio.access_control_firerole import compile_role_definition, acc_firerole_check_user
@@ -123,7 +125,7 @@
CFG_BIBCATALOG_SYSTEM
from invenio.bibcatalog import BIBCATALOG_SYSTEM
from invenio.bibdocfile_config import CFG_BIBDOCFILE_ICON_SUBFORMAT_RE, \
- CFG_BIBDOCFILE_DEFAULT_ICON_SUBFORMAT
+ CFG_BIBDOCFILE_DEFAULT_ICON_SUBFORMAT, CFG_BIBDOCFILE_STREAM_ARCHIVE_FORMATS
from invenio.pluginutils import PluginContainer
import invenio.template
@@ -797,17 +799,22 @@ def get_xml_8564(self):
return out
- def get_total_size_latest_version(self):
+ def get_total_size_latest_version(self, user_info=None, subformat=None):
"""
Returns the total size used on disk by all the files belonging
to this record and corresponding to the latest version.
+ @param user_info: the user_info dictionary, used to check restrictions
+ @type: dict
+ @param subformat: if subformat is specified, it limits files
+ only to those from that specific subformat
+ @type subformat: string
@return: the total size.
@rtype: integer
"""
size = 0
for (bibdoc, _) in self.bibdocs.values():
- size += bibdoc.get_total_size_latest_version()
+ size += bibdoc.get_total_size_latest_version(user_info, subformat)
return size
def get_total_size(self):
@@ -1564,6 +1571,36 @@ def get_text(self, extract_text_if_necessary=True):
return " ".join(texts)
+ def stream_archive_of_latest_files(self, req, files_size=''):
+ """
+ Streams the tar archive with all files of a certain file size (that
+ are not restricted or hidden) to the user.
+ File size should be a string that can be compared with the output of
+ BibDocFile.get_subformat() function.
+
+ @param req: Apache Request Object
+ @type req: Apache Request Object
+ @param files_size: size of the files (they can be defined in
+ bibdocfile_config). Empty string means the original size.
+ @type files_size: string
+ """
+ # Get the internal size from the user-friendly file size name
+ internal_format = [f[1] for f in CFG_BIBDOCFILE_STREAM_ARCHIVE_FORMATS if f[0] == files_size]
+ if len(internal_format) < 1:
+ # Incorrect file size
+ return
+ internal_format = internal_format[0]
+ tarname = str(self.id) + "_" + files_size + '.tar'
+
+ # Select files that user can download (not hidden nor restricted)
+ user_info = collect_user_info(req)
+ req.content_type = "application/x-tar"
+ req.headers_out["Content-Disposition"] = 'attachment; filename="%s"' % tarname
+ tar = tarfile.open(fileobj=req, mode='w|')
+ for f in self.list_latest_files():
+ if f.get_subformat() == internal_format and f.is_restricted(user_info)[0] == 0 and not f.hidden:
+ tar.add(f.get_path(), arcname=f.get_full_name(), recursive=False)
+ tar.close()
class BibDoc(object):
"""
@@ -2801,12 +2838,28 @@ def _build_related_file_list(self):
cur_doc = BibDoc.create_instance(docid=docid, human_readable=self.human_readable)
self.related_files[doctype].append(cur_doc)
- def get_total_size_latest_version(self):
+ def get_total_size_latest_version(self, user_info=None, subformat=None):
"""Return the total size used on disk of all the files belonging
- to this bibdoc and corresponding to the latest version."""
+ to this bibdoc and corresponding to the latest version. Restricted
+ and hidden files are not counted, unless there is no user_info.
+ @param user_info: the user_info dictionary, used to check restrictions
+ @type: dict
+ @param subformat: if subformat is specified, it limits files
+ only to those from that specific subformat
+ @type subformat: string
+ """
ret = 0
+ all_files = False
+ # If we are calling this function without user_info, then we want to
+ # see all the files
+ if not user_info:
+ all_files = True
for bibdocfile in self.list_latest_files():
- ret += bibdocfile.get_size()
+ # First check for restrictions
+ if all_files or (bibdocfile.is_restricted(user_info)[0] == 0 and not bibdocfile.hidden):
+ # Then check if the format is correct
+ if subformat is None or bibdocfile.get_subformat() == subformat:
+ ret += bibdocfile.get_size()
return ret
def get_total_size(self):
diff --git a/modules/bibdocfile/lib/bibdocfile_config.py b/modules/bibdocfile/lib/bibdocfile_config.py
index 0caa8ddbd2..c07eb606ff 100644
--- a/modules/bibdocfile/lib/bibdocfile_config.py
+++ b/modules/bibdocfile/lib/bibdocfile_config.py
@@ -69,3 +69,12 @@
# CFG_BIBDOCFILE_DEFAULT_ICON_SUBFORMAT -- this is the default subformat used
# when creating new icons.
CFG_BIBDOCFILE_DEFAULT_ICON_SUBFORMAT = "icon"
+
+# CFG_BIBDOCFILE_STREAM_ARCHIVE_FORMATS -- a list (not dictionary, because
+# we want to preserve the order) that connects the different format sizes
+# (like 'small', 'medium', etc.) with internal format sizes (like 'icon-180', 'icon-640', etc.)
+CFG_BIBDOCFILE_STREAM_ARCHIVE_FORMATS = [
+ ('small', 'icon-180'),
+ ('medium', 'icon-640'),
+ ('large', 'icon-1440'),
+ ('original', '')]
diff --git a/modules/bibdocfile/lib/bibdocfile_webinterface.py b/modules/bibdocfile/lib/bibdocfile_webinterface.py
index 1547dd3ddf..198b72fb17 100644
--- a/modules/bibdocfile/lib/bibdocfile_webinterface.py
+++ b/modules/bibdocfile/lib/bibdocfile_webinterface.py
@@ -83,6 +83,12 @@ def _lookup(self, component, path):
def getfile(req, form):
args = wash_urlargd(form, bibdocfile_templates.files_default_urlargd)
ln = args['ln']
+ if filename[:9] == "allfiles-":
+ files_size = filename[9:]
+ # stream a tar package to the user
+ brd = BibRecDocs(self.recid)
+ brd.stream_archive_of_latest_files(req, files_size)
+ return
_ = gettext_set_language(ln)
diff --git a/modules/bibformat/lib/bibreformat.py b/modules/bibformat/lib/bibreformat.py
index 1571146adb..9c712dcbd3 100644
--- a/modules/bibformat/lib/bibreformat.py
+++ b/modules/bibformat/lib/bibreformat.py
@@ -353,7 +353,11 @@ def task_run_core():
if task_has_option("last"):
recids += outdated_caches(fmt, last_updated)
- if task_has_option('ignore_without'):
+ if task_has_option('ignore_without') or \
+ task_has_option('collection') or \
+ task_has_option('field') or \
+ task_has_option('pattern') or \
+ task_has_option('recids'):
without_fmt = intbitset()
else:
without_fmt = missing_caches(fmt)
diff --git a/modules/webaccess/doc/hacking/webaccess-api.webdoc b/modules/webaccess/doc/hacking/webaccess-api.webdoc
index f657c7ad42..dbec7eed81 100644
--- a/modules/webaccess/doc/hacking/webaccess-api.webdoc
+++ b/modules/webaccess/doc/hacking/webaccess-api.webdoc
@@ -23,7 +23,7 @@
Invenio Access Control Engine can be called from within your Python programs
via both a regular Python API and CLI.
-In addition the you get an explanation of the program flow.
+In addition to the above features, you also get an explanation of the program flow.
Contents:
1. Regular API
diff --git a/modules/websearch/lib/search_engine.py b/modules/websearch/lib/search_engine.py
index ab15175be8..eb78a0cc09 100644
--- a/modules/websearch/lib/search_engine.py
+++ b/modules/websearch/lib/search_engine.py
@@ -97,7 +97,8 @@
InvenioWebSearchReferstoLimitError, \
InvenioWebSearchCitedbyLimitError, \
CFG_WEBSEARCH_IDXPAIRS_FIELDS,\
- CFG_WEBSEARCH_IDXPAIRS_EXACT_SEARCH
+ CFG_WEBSEARCH_IDXPAIRS_EXACT_SEARCH, \
+ CFG_WEBSEARCH_BLACKLISTED_FORMATS
from invenio.search_engine_utils import (get_fieldvalues,
get_fieldvalues_alephseq_like,
record_exists)
@@ -1711,7 +1712,7 @@ def get_synonym_terms(term, kbr_name, match_type, use_memoise=False):
return dterms.keys()
-def wash_output_format(ouput_format):
+def wash_output_format(ouput_format, verbose=False, req=None):
"""Wash output format FORMAT. Currently only prevents input like
'of=9' for backwards-compatible format that prints certain fields
only. (for this task, 'of=tm' is preferred)"""
@@ -1719,6 +1720,12 @@ def wash_output_format(ouput_format):
# asked to print MARC tags, but not enough digits,
# so let's switch back to HTML brief default
return 'hb'
+ elif format in CFG_WEBSEARCH_BLACKLISTED_FORMATS:
+ if verbose:
+ write_warning("Selected format is not available through perform_request_search", req=req)
+ # Returning an empty list seems dangerous because you wouldn't know
+ # right away that the list is not supposed to be empty.
+ return 'hb'
else:
return ouput_format
@@ -5714,7 +5721,7 @@ def prs_wash_arguments(req=None, cc=CFG_SITE_NAME, c=None, p="", f="", rg=CFG_WE
"""
# wash output format:
- of = wash_output_format(of)
+ of = wash_output_format(of, verbose=verbose, req=req)
# wash all arguments requiring special care
p = wash_pattern(p)
diff --git a/modules/websearch/lib/search_engine_config.py b/modules/websearch/lib/search_engine_config.py
index 17d8daf1da..2bc848a427 100644
--- a/modules/websearch/lib/search_engine_config.py
+++ b/modules/websearch/lib/search_engine_config.py
@@ -50,6 +50,11 @@
# interfaces (0=simple, 1=advanced, 2=add-to-search):
CFG_WEBSEARCH_ENABLED_SEARCH_INTERFACES = [0,1,2]
+# CFG_WEBSEARCH_BLACKLISTED_FORMATS -- list of formats that will be refused
+# by perform_request_search:
+# * recstruct is an internal format thus should not be exposed
+CFG_WEBSEARCH_BLACKLISTED_FORMATS = ["recstruct", "wapaff", "wapdat"]
+
class InvenioWebSearchUnknownCollectionError(Exception):
"""Exception for bad collection."""
diff --git a/modules/websearch/lib/websearch_external_collections_getter_unit_tests.py b/modules/websearch/lib/websearch_external_collections_getter_unit_tests.py
index 8d55a05730..5ac036d9b7 100644
--- a/modules/websearch/lib/websearch_external_collections_getter_unit_tests.py
+++ b/modules/websearch/lib/websearch_external_collections_getter_unit_tests.py
@@ -51,7 +51,7 @@ def test_async_download(self):
## - test 1 bad IP: 1.2.3.4
## Return the list of errors.
checks = [
- {'url': 'http://invenio-software.org', 'content': 'About Invenio'},
+ {'url': 'http://invenio-software.org', 'content': 'Invenio'},
{'url': 'http://rjfreijoiregjreoijgoirg.fr'},
{'url': 'http://1.2.3.4/'}]
diff --git a/modules/webstyle/lib/webstyle_templates.py b/modules/webstyle/lib/webstyle_templates.py
index 316620ebaa..329214176b 100644
--- a/modules/webstyle/lib/webstyle_templates.py
+++ b/modules/webstyle/lib/webstyle_templates.py
@@ -1,5 +1,6 @@
# This file is part of Invenio.
-# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 CERN.
+# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
+# 2014, 2016 CERN.
#
# Invenio is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
@@ -38,6 +39,7 @@
CFG_SITE_URL, \
CFG_VERSION, \
CFG_WEBSTYLE_INSPECT_TEMPLATES, \
+ CFG_WEBSTYLE_SUPPORT_FONTAWESOME, \
CFG_WEBSTYLE_TEMPLATE_SKIN, \
CFG_INSPIRE_SITE, \
CFG_WEBLINKBACK_TRACKBACK_ENABLED
@@ -374,6 +376,7 @@ def tmpl_pageheader(self, req, ln=CFG_SITE_LANG, headertitle="",
%(metabase)s
+ %(font_awesome)s
@@ -460,6 +463,10 @@ def tmpl_pageheader(self, req, ln=CFG_SITE_LANG, headertitle="",
'canonical_and_alternate_urls' : self.tmpl_canonical_and_alternate_urls(uri),
'cssurl' : CFG_BASE_URL,
'cssskin' : CFG_WEBSTYLE_TEMPLATE_SKIN != 'default' and '_' + CFG_WEBSTYLE_TEMPLATE_SKIN or '',
+ 'font_awesome': (
+ '') if (
+ CFG_WEBSTYLE_SUPPORT_FONTAWESOME) else '',
'rssurl': rssurl,
'ln' : ln,
'ln_iso_639_a' : ln.split('_', 1)[0],
diff --git a/modules/websubmit/lib/functions/Stamp_Uploaded_Files.py b/modules/websubmit/lib/functions/Stamp_Uploaded_Files.py
index e8b5b42147..40c9cee7e6 100644
--- a/modules/websubmit/lib/functions/Stamp_Uploaded_Files.py
+++ b/modules/websubmit/lib/functions/Stamp_Uploaded_Files.py
@@ -302,8 +302,8 @@ def visit_for_stamping(visit_for_stamping_arguments, dirname, filenames):
'file_stamper_options' members.
@param dirname: (string) - the path to the directory in which the
files are to be stamped.
- @param filenames: (list) - the names of each file in dirname. An
- attempt will be made to stamp each of these files.
+ @param filenames: (list) - the names of each file and subdirectory in
+ dirname. An attempt will be made to stamp each of the files.
@Exceptions Raised:
+ InvenioWebSubmitFunctionWarning;
+ InvenioWebSubmitFunctionError;
@@ -345,6 +345,10 @@ def visit_for_stamping(visit_for_stamping_arguments, dirname, filenames):
path_to_subject_file = "%s/%s" % (dirname, file_to_stamp)
file_stamper_options['input-file'] = path_to_subject_file
+ if not os.path.isfile(path_to_subject_file):
+ # If it's not a file, we can't stamp it. Continue with next file
+ continue
+
## Just before attempting to stamp the file, log the dictionary of
## options (file_stamper_options) that will be passed to websubmit-
## file-stamper: