Additionally you might want to automatically generate sitemap.xml
files for your installation. For this just schedule:
$ bibexport -w sitemap -s1d
You will then need to add a line such as:
Sitemap: /sitemap-index.xml.gz
to your robots.txt file.
-
If you are using the WebLinkback module, you should run the following tasklets:
+
If you are using the WebLinkback module, you may want to run some of the following tasklets:
+# Delete rejected, broken and pending linkbacks whose URLs is on blacklist
sudo -u www-data /opt/invenio/bin/bibtasklet \
-N weblinkbackupdaterdeleteurlsonblacklist \
-T bst_weblinkback_updater \
-a "mode=1" \
-u admin -s1d -L '22:00-05:00'
+# Update page titles of new linkbacks
sudo -u www-data /opt/invenio/bin/bibtasklet \
-N weblinkbackupdaternewpages \
-T bst_weblinkback_updater \
-a "mode=2" \
-u admin -s1d -L '22:00-05:00'
+# Update page titles of old linkbacks
sudo -u www-data /opt/invenio/bin/bibtasklet \
-N weblinkbackupdateroldpages \
-T bst_weblinkback_updater \
-a "mode=3" \
-u admin -s7d -L '22:00-05:00'
+# Update manually set page titles
sudo -u www-data /opt/invenio/bin/bibtasklet \
-N weblinkbackupdatermanuallysettitles \
-T bst_weblinkback_updater \
-a "mode=4" \
-u admin -s7d -L '22:00-05:00'
+# Detect and disable broken linkbacks
sudo -u www-data /opt/invenio/bin/bibtasklet \
-N weblinkbackupdaterdetectbrokenlinkbacks \
-T bst_weblinkback_updater \
-a "mode=5" \
-u admin -s7d -L 'Sunday 01:00-05:00'
+
+# Send notification email for all pending linkbacks
+sudo -u www-data /opt/invenio/bin/bibtasklet \
+ -N weblinkbacknotifications \
+ -T bst_weblinkback_updater \
+ -a "mode=6" \
+ -u admin -s1d
Monitoring periodical daemon tasks
Note that the BibSched automated daemon stops as soon as some of
its tasks end with an error. You will be informed by email about this
incident. Nevertheless, it is a good idea to inspect the BibSched
queue from time to time anyway, say several times per day, to see what
is going on. This can be done by running the BibSched command-line
monitor:
$ bibsched
The monitor will permit you to stop/start the automated mode, to
delete the tasks that were wrongly submitted, to run some of the tasks
manually, etc. Note also that the BibSched daemon writes its log and
error files about its own operation, as well as on the operation of
its tasks, to the /opt/invenio/var/log directory.
Running alert engine
Invenio users may set up an automatic notification email alerts
so that they are automatically alerted about documents of their
interest by email, either daily, weekly, or monthly. It is the job of
the alert engine to do this. The alert engine has to be run every
day:
$ alertengine
You may want to set up an external cron job to call
alertengine each day, for example:
When you are adding new records to the system, the word frequency
ranking weights for old records aren't recalculated by default in
order to speed up the insertion of new records. This may influence a
bit the precision of word similarity searches. It is therefore
advised to expressely run bibrank in the recalculating mode once in a
while during a relatively quiet site operation day, by doing:
$ bibrank -R -w wrd -s 14d -L Sunday
You may want to do this either (i) periodically, say once per month
(see the previous section), or (ii) depending on the frequency of new
additions to the record database, say when the size grows by 2-3
percent.
Housekeeping: recalculating sorting weights
It is advised to run from time to time the rebalancing of the
sorting buckets. In order to speed up the process of insertion of
new records, the sorting buckets are not being recalculated,
but new records are being added at the end of the corresponding
bucket. This might create differences in the size of each bucket
which might have a small impact on the speed of sorting.
$ bibsort -R -s 7d -L 'Sunday 01:00-05:00'
The rebalancing might be run weekly or even daily.
Housekeeping: cleaning up the garbage
The tool inveniogc provides a garbage collector for
the database, temporary files, and the like.
If you choose to differentiate between guest users
(see CFG_WEBSESSION_DIFFERENTIATE_BETWEEN_GUESTS
in invenio.conf), then guest users can create a lot of
entries in Invenio tables that are related to their web sessions,
their search history, personal baskets, etc. This data has to be
garbage-collected periodically. You can run this, say every Sunday
between 01:00 and 05:00, via:
$ inveniogc -s 7d -L 'Sunday 01:00-05:00'
Different temporary log and err files are created
in /opt/invenio/var/log
and /opt/invenio/var/tmp directory that is good to
clean up from time to time. The previous command could be used to
clean those files, too, via:
$ inveniogc -s 7d -d -L 'Sunday 01:00-05:00'
The inveniogc tool can run other cleaning actions;
please refer to its help (inveniogc --help) for more
details.
Note that in the above section "Setting up periodical daemon
tasks", we have set up inveniogc with
argument -a in that example, meaning that it would run
all possible cleaning actions. Please modify this if it is not what
you want.
Housekeeping: backing up the database
You can launch a bibsched task called dbdump in order
to take regular snapshot of your database content into SQL dump files.
For example, to back up the database content
into /opt2/mysql-backups directory every night, keeping
at most 10 latest copies of the backup file, you would launch:
This will create files named
like invenio-dbdump-2009-03-10_22:10:28.sql in this
folder.
Note that you may use Invenio-independent MySQL backuping tools
like mysqldump, but these might generally lock all tables
during backup for consistency, hence it could happen that your site
might not be accessible during backuping time due to the user session
table being locked as well. The dbdump tool does not
lock all tables, therefore the site remains accessible to users while
the dump files are being created. Note that the dump files are kept
consistent with respect to the data, since dbdump runs
via bibsched, hence not allowing any other important
bibliographic task to run during the backup.
To load a dump file produced by dbdump into a running
Invenio instance later, you can use:
diff --git a/modules/webjournal/lib/elements/bfe_webjournal_trackback_auto_discovery.py b/modules/webjournal/lib/elements/bfe_webjournal_trackback_auto_discovery.py
index 5c1ecf35b..579c328b0 100644
--- a/modules/webjournal/lib/elements/bfe_webjournal_trackback_auto_discovery.py
+++ b/modules/webjournal/lib/elements/bfe_webjournal_trackback_auto_discovery.py
@@ -1,46 +1,48 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
## This file is part of Invenio.
## Copyright (C) 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.
"""
WebJournal Element - return trackback auto discovery tag
"""
import cgi
from invenio.webjournal_utils import parse_url_string
from invenio.weblinkback_templates import get_trackback_auto_discovery_tag
+from invenio.config import CFG_WEBLINKBACK_TRACKBACK_ENABLED
def format_element(bfo):
"""
Return trackback auto discovery tag if recid != -1, will return "" for recid == -1 like index pages
"""
- # Retrieve context (journal, issue and category) from URI
- args = parse_url_string(bfo.user_info['uri'])
- recid = args["recid"]
-
html = ""
- if recid != -1:
- html = get_trackback_auto_discovery_tag(recid)
+ if CFG_WEBLINKBACK_TRACKBACK_ENABLED:
+ # Retrieve context (journal, issue and category) from URI
+ args = parse_url_string(bfo.user_info['uri'])
+ recid = args["recid"]
+
+ if recid != -1:
+ html = get_trackback_auto_discovery_tag(recid)
return html
def escape_values(bfo):
"""
Called by BibFormat in order to check if output of this element
should be escaped.
"""
return 0
diff --git a/modules/weblinkback/lib/weblinkback.py b/modules/weblinkback/lib/weblinkback.py
index dfa107230..d8b3d6f64 100644
--- a/modules/weblinkback/lib/weblinkback.py
+++ b/modules/weblinkback/lib/weblinkback.py
@@ -1,313 +1,334 @@
# -*- coding: utf-8 -*-
## This file is part of Invenio.
## Copyright (C) 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.
"""WebLinkback - Handling Linkbacks"""
from invenio.config import CFG_SITE_URL, \
CFG_SITE_RECORD, \
- CFG_SITE_ADMIN_EMAIL
+ CFG_SITE_ADMIN_EMAIL, \
+ CFG_SITE_LANG
from invenio.weblinkback_config import CFG_WEBLINKBACK_TYPE, \
CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME, \
CFG_WEBLINKBACK_STATUS, \
CFG_WEBLINKBACK_ORDER_BY_INSERTION_TIME, \
CFG_WEBLINKBACK_LIST_TYPE, \
CFG_WEBLINKBACK_TRACKBACK_SUBSCRIPTION_ERROR_MESSAGE, \
CFG_WEBLINKBACK_PAGE_TITLE_STATUS, \
- CFG_WEBLINKBACK_BROKEN_COUNT
+ CFG_WEBLINKBACK_BROKEN_COUNT, \
+ CFG_WEBLINKBACK_LATEST_FACTOR
from invenio.weblinkback_dblayer import create_linkback, \
get_url_list, \
get_all_linkbacks, \
get_approved_latest_added_linkbacks, \
approve_linkback, \
get_urls_and_titles, \
update_url_title, \
set_url_broken, \
increment_broken_count, \
remove_linkback
from invenio.search_engine import check_user_can_view_record, \
guess_primary_collection_of_a_record
from invenio.access_control_engine import acc_authorize_action, \
acc_get_authorized_emails
from invenio.webuser import collect_user_info
from invenio.mailutils import send_email
-from invenio.bibformat import format_record
from invenio.urlutils import get_title_of_page
def check_user_can_view_linkbacks(user_info, recid):
"""
Check if the user is authorized to view linkbacks for a given recid.
Returns the same type as acc_authorize_action
"""
# check user cannot view the record itself
(auth_code, auth_msg) = check_user_can_view_record(user_info, recid)
if auth_code:
return (auth_code, auth_msg)
# check if user can view the linkbacks
record_primary_collection = guess_primary_collection_of_a_record(recid)
return acc_authorize_action(user_info, 'viewlinkbacks', authorized_if_no_roles=True, collection=record_primary_collection)
-def generate_redirect_url(recid, ln, action = None):
+def generate_redirect_url(recid, ln=CFG_SITE_LANG, action = None):
"""
Get redirect URL for an action
@param action: the action, must be defined in weblinkback_webinterface.py
@return "CFG_SITE_URL/CFG_SITE_RECORD/recid/linkbacks/action?ln=%s" if action != None,
otherwise CFG_SITE_URL/CFG_SITE_RECORD/recid/linkbacks?ln=%s
"""
result = "%s/%s/%s/linkbacks" % (CFG_SITE_URL, CFG_SITE_RECORD, recid)
if action != None:
return result + "/%s?ln=%s" % (action, ln)
else:
return result + "?ln=%s" % ln
def split_in_days(linkbacks):
"""
Split linkbacks in days
@param linkbacks: a list of this format: [(linkback_id,
origin_url,
recid,
additional_properties,
type,
status,
insert_time)]
in ascending or descending order by insert_time
@return a list of lists of linkbacks
"""
result = []
same_day_list = []
previous_date = None
current_date = None
for i in range(len(linkbacks)):
current_linkback = linkbacks[i]
previous_date = None
if i > 0:
previous_date = current_date
else:
previous_date = current_linkback[6]
current_date = current_linkback[6]
# same day --> same group
if (current_date.year == previous_date.year and
current_date.month == previous_date.month and
current_date.day == previous_date.day):
same_day_list.append(current_linkback)
else:
result.append(same_day_list)
same_day_list = []
same_day_list.append(current_linkback)
# add last group if non-empty
if same_day_list:
result.append(same_day_list)
return result
def create_trackback(recid, url, title, excerpt, blog_name, blog_id, source, user_info):
"""
Create a trackback
@param recid
"""
# copy optional arguments
argument_copy = {}
if title != CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME:
argument_copy['title'] = title
if excerpt != CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME:
argument_copy['excerpt'] = excerpt
if blog_name != CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME:
argument_copy['blog_name'] = blog_name
if blog_id != CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME:
argument_copy['id'] = blog_id
if source != CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME:
argument_copy['source'] = source
additional_properties = ""
if len(argument_copy) > 0:
additional_properties = argument_copy
return create_linkback(url, recid, additional_properties, CFG_WEBLINKBACK_TYPE['TRACKBACK'], user_info)
-def send_request_notification_to_all_linkback_moderators(recid, origin_url, linkback_type, ln):
+def send_pending_linkbacks_notification(linkback_type):
"""
- Send notification emails to all linkback moderators for linkback request
- @param recid
- @param origin_url: URL of the requestor
+ Send notification emails to all linkback moderators for all pending linkbacks
@param linkback_type: of CFG_WEBLINKBACK_LIST_TYPE
"""
- content = """There is a new %(linkback_type)s request for %(recordURL)s from %(origin_url)s which you should approve or reject.
- """ % {'linkback_type': linkback_type,
- 'recordURL': generate_redirect_url(recid, ln),
- 'origin_url': origin_url}
+ pending_linkbacks = get_all_linkbacks(linkback_type=CFG_WEBLINKBACK_TYPE['TRACKBACK'], status=CFG_WEBLINKBACK_STATUS['PENDING'])
+
+ if pending_linkbacks:
+ content = """There are %(count)s new %(linkback_type)s requests which you should approve or reject:
+ """ % {'count': len(pending_linkbacks),
+ 'linkback_type': linkback_type}
- html_content = """There is a new %(linkback_type)s request for %(record)s (%(recordURL)s) from %(title)s (%(origin_url)s) which you should approve or reject.
- """ % {'linkback_type': linkback_type,
- 'record': format_record(recID=recid, of='hs', ln=ln),
- 'recordURL': generate_redirect_url(recid, ln),
- 'origin_url': origin_url,
- 'title': origin_url}
+ for pending_linkback in pending_linkbacks:
+ content += """
+ For %(recordURL)s from %(origin_url)s.
+ """ % {'recordURL': generate_redirect_url(pending_linkback[2]),
+ 'origin_url': pending_linkback[1]}
- for email in acc_get_authorized_emails('moderatelinkbacks', collection = guess_primary_collection_of_a_record(recid)):
- send_email(CFG_SITE_ADMIN_EMAIL, email, 'New ' + linkback_type + ' request', content, html_content)
+ for email in acc_get_authorized_emails('moderatelinkbacks'):
+ send_email(CFG_SITE_ADMIN_EMAIL, email, 'Pending ' + linkback_type + ' requests', content)
def infix_exists_for_url_in_list(url, list_type):
"""
Check if an infix of a url exists in a list
@param url
@param list_type, of CFG_WEBLINKBACK_LIST_TYPE
@return True, False
"""
urls = get_url_list(list_type)
for current_url in urls:
if current_url in url:
return True
return False
+def get_latest_linkbacks_to_accessible_records(rg, linkbacks, user_info):
+ result = []
+ for linkback in linkbacks:
+ (auth_code, auth_msg) = check_user_can_view_record(user_info, linkback[2]) # pylint: disable=W0612
+ if not auth_code:
+ result.append(linkback)
+ if len(result) == rg:
+ break
+ return result
+
+
def perform_request_display_record_linbacks(req, recid, show_admin, weblinkback_templates, ln): # pylint: disable=W0613
"""
Display linkbacks of a record
@param recid
@param argd
@param show_admin: True, False --> show admin parts to approve/reject linkbacks pending requests
@param weblinkback_templates: template object reference
"""
out = weblinkback_templates.tmpl_linkbacks_general(recid=recid,
ln=ln)
if show_admin:
pending_linkbacks = get_all_linkbacks(recid, CFG_WEBLINKBACK_STATUS['PENDING'], CFG_WEBLINKBACK_ORDER_BY_INSERTION_TIME['DESC'])
out += weblinkback_templates.tmpl_linkbacks_admin(pending_linkbacks=pending_linkbacks,
recid=recid,
ln=ln)
approved_linkbacks = get_all_linkbacks(recid, CFG_WEBLINKBACK_STATUS['APPROVED'], CFG_WEBLINKBACK_ORDER_BY_INSERTION_TIME['DESC'])
out += weblinkback_templates.tmpl_linkbacks(approved_linkbacks=approved_linkbacks,
ln=ln)
return out
-def perform_request_display_approved_latest_added_linkbacks(rg, ln, weblinkback_templates):
+def perform_request_display_approved_latest_added_linkbacks_to_accessible_records(rg, ln, user_info, weblinkback_templates):
"""
- Display approved latest added linbacks
+ Display approved latest added linbacks to accessible records
@param rg: count of linkbacks to display
@param weblinkback_templates: template object reference
"""
- latest_linkbacks = get_approved_latest_added_linkbacks(rg)
+ latest_linkbacks = get_approved_latest_added_linkbacks(rg * CFG_WEBLINKBACK_LATEST_FACTOR)
+ latest_linkbacks = get_latest_linkbacks_to_accessible_records(rg, latest_linkbacks, user_info)
latest_linkbacks_in_days = split_in_days(latest_linkbacks)
out = weblinkback_templates.tmpl_get_latest_linkbacks_top(rg, ln)
out += ' '
out += weblinkback_templates.tmpl_get_latest_linkbacks(latest_linkbacks_in_days, ln)
return out
def perform_sendtrackback(req, recid, url, title, excerpt, blog_name, blog_id, source, ln):
"""
Send trackback
@param recid: recid
"""
# assume unsuccessful request
status = 400
xml_response = ''
xml_error_response = """1%s
"""
blacklist_match = infix_exists_for_url_in_list(url, CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'])
whitelist_match = infix_exists_for_url_in_list(url, CFG_WEBLINKBACK_LIST_TYPE['WHITELIST'])
# faulty request, url argument not set
if url in (CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME, None, ''):
xml_response += xml_error_response % CFG_WEBLINKBACK_TRACKBACK_SUBSCRIPTION_ERROR_MESSAGE['BAD_ARGUMENT']
# request refused: whitelist match has precedence over blacklist match
elif blacklist_match and not whitelist_match:
xml_response += xml_error_response % CFG_WEBLINKBACK_TRACKBACK_SUBSCRIPTION_ERROR_MESSAGE['BLACKLIST']
# request accepted: will be either approved automatically or pending
else:
status = 200
linkback_id = create_trackback(recid, url, title, excerpt, blog_name, blog_id, source, collect_user_info(req))
# approve request automatically from url in whitelist
if whitelist_match:
approve_linkback(linkback_id, collect_user_info(req))
- # send request notification email to moderators
- else:
- send_request_notification_to_all_linkback_moderators(recid, url, CFG_WEBLINKBACK_TYPE['TRACKBACK'], ln)
xml_response += ''
# send response
req.set_content_type("text/xml; charset=utf-8")
req.set_status(status)
req.send_http_header()
req.write(xml_response)
+def perform_sendtrackback_disabled(req):
+ status = 404
+ xml_response = """
+ 1
+ Trackback facility disabled
+ """
+ req.set_content_type("text/xml; charset=utf-8")
+ req.set_status(status)
+ req.send_http_header()
+ req.write(xml_response)
+
+
def update_linkbacks(mode):
"""
Update titles of pages that link to the instance
@param mode: 1 update page titles of new linkbacks
2 update page titles of old linkbacks
3 update manually set page titles
4 detect and disable broken linkbacks
"""
if mode in (1, 2, 3):
if mode == 1:
urls_and_titles = get_urls_and_titles(CFG_WEBLINKBACK_PAGE_TITLE_STATUS['NEW'])
elif mode == 2:
urls_and_titles = get_urls_and_titles(CFG_WEBLINKBACK_PAGE_TITLE_STATUS['OLD'])
elif mode == 3:
urls_and_titles = get_urls_and_titles(CFG_WEBLINKBACK_PAGE_TITLE_STATUS['MANUALLY_SET'])
for (url, title, manual_set, broken_count) in urls_and_titles: # pylint: disable=W0612
new_title = get_title_of_page(url)
# Only accept valid titles
if new_title != None:
update_url_title(url, new_title)
elif mode == 4:
urls_and_titles = get_urls_and_titles()
for (url, title, manual_set, broken_count) in urls_and_titles: # pylint: disable=W0612
new_title = get_title_of_page(url)
# Broken one detected
if new_title == None:
increment_broken_count(url)
if broken_count + 1 == CFG_WEBLINKBACK_BROKEN_COUNT:
set_url_broken(url)
def delete_linkbacks_on_blacklist():
"""
Delete all rejected, broken and pending linkbacks whose URL on in the blacklist
"""
linkbacks = list(get_all_linkbacks(status=CFG_WEBLINKBACK_STATUS['PENDING']))
linkbacks.extend(list(get_all_linkbacks(status=CFG_WEBLINKBACK_STATUS['REJECTED'])))
linkbacks.extend(list(get_all_linkbacks(status=CFG_WEBLINKBACK_STATUS['BROKEN'])))
for linkback in linkbacks:
if infix_exists_for_url_in_list(linkback[1], CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST']):
remove_linkback(linkback[0])
diff --git a/modules/weblinkback/lib/weblinkback_config.py b/modules/weblinkback/lib/weblinkback_config.py
index 452dba92e..287af1c53 100644
--- a/modules/weblinkback/lib/weblinkback_config.py
+++ b/modules/weblinkback/lib/weblinkback_config.py
@@ -1,62 +1,64 @@
# -*- coding: utf-8 -*-
##
## This file is part of Invenio.
## Copyright (C) 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.
"""WebLinkback - Configuration Parameters"""
CFG_WEBLINKBACK_STATUS = {'APPROVED': 'approved',
'PENDING': 'pending',
'REJECTED': 'rejected',
'INSERTED': 'inserted',
'BROKEN': 'broken'}
CFG_WEBLINKBACK_TYPE = {'TRACKBACK': 'trackback',
'REFBACK': 'refback',
'PINGBACK': 'pingback'}
CFG_WEBLINKBACK_LIST_TYPE = {'WHITELIST': 'whitelist',
'BLACKLIST': 'blacklist'}
CFG_WEBLINKBACK_ORDER_BY_INSERTION_TIME = {'ASC': 'ASC',
'DESC': 'DESC'}
CFG_WEBLINKBACK_ADMIN_MODERATION_ACTION = {'REJECT': 'reject',
'APPROVE': 'approve',
'INSERT': 'insert',
'DELETE': 'delete'}
CFG_WEBLINKBACK_ACTION_RETURN_CODE = {'OK': 0,
'INVALID_ACTION': 1,
'DUPLICATE': 2,
'BAD_INPUT': 3}
CFG_WEBLINKBACK_PAGE_TITLE_STATUS = {'NEW': 'n',
'OLD': 'o',
'MANUALLY_SET': 'm'}
CFG_WEBLINKBACK_LATEST_COUNT_VALUES = (10, 20, 50, 100, 200)
CFG_WEBLINKBACK_LATEST_COUNT_DEFAULT = 10
CFG_WEBLINKBACK_BROKEN_COUNT = 5
CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME = 'default'
CFG_WEBLINKBACK_TRACKBACK_SUBSCRIPTION_ERROR_MESSAGE= {'BAD_ARGUMENT': 'Refused: URL argument not set',
'BLACKLIST': 'Refused: URL in blacklist'}
CFG_WEBLINKBACK_DEFAULT_USER = 0
+
+CFG_WEBLINKBACK_LATEST_FACTOR = 3
diff --git a/modules/weblinkback/lib/weblinkback_dblayer.py b/modules/weblinkback/lib/weblinkback_dblayer.py
index beca277e3..d73211587 100644
--- a/modules/weblinkback/lib/weblinkback_dblayer.py
+++ b/modules/weblinkback/lib/weblinkback_dblayer.py
@@ -1,414 +1,419 @@
# -*- coding: utf-8 -*-
##
## This file is part of Invenio.
## Copyright (C) 2011, 2012 CERN.
##
## Invenio is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 2 of the
## License, or (at your option) any later version.
##
## Invenio is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Invenio; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""WebLinkback - Database Layer"""
from invenio.dbquery import run_sql
from invenio.weblinkback_config import CFG_WEBLINKBACK_STATUS, \
CFG_WEBLINKBACK_ORDER_BY_INSERTION_TIME, \
CFG_WEBLINKBACK_DEFAULT_USER, \
CFG_WEBLINKBACK_PAGE_TITLE_STATUS
+from invenio.textutils import xml_entities_to_utf8
-def get_all_linkbacks(recid=None, status=None, order=CFG_WEBLINKBACK_ORDER_BY_INSERTION_TIME["ASC"]):
+def get_all_linkbacks(recid=None, status=None, order=CFG_WEBLINKBACK_ORDER_BY_INSERTION_TIME["ASC"], linkback_type=None):
"""
Get all linkbacks
@param recid: of one record, of all if None
@param status: with a certain status, of all if None
@param order: order by insertion time either "ASC" or "DESC"
+ @param linkback_type: of a certain type, of all if None
@return [(linkback_id,
origin_url,
recid,
additional_properties,
linkback_type,
linkback_status,
insert_time)]
in order by id
"""
header_sql = """SELECT id,
origin_url,
id_bibrec,
additional_properties,
type,
status,
insert_time
FROM lnkENTRY"""
- middle_sql = ""
+ conditions = []
order_sql = "ORDER by id %s" % order
- params = ()
+ params = []
- if not recid:
- middle_sql = " WHERE status=%s "
- params = (status, )
- if not status:
- middle_sql = " WHERE id_bibrec=%s "
- params = (recid, )
- if recid and status:
- middle_sql = " WHERE id_bibrec=%s AND status=%s "
- params = (recid, status, )
+ def add_condition(column, value):
+ if value:
+ if not conditions:
+ conditions.append('WHERE %s=%%s' % column)
+ else:
+ conditions.append('AND %s=%%s' % column)
+ params.append(value)
- return run_sql(header_sql + middle_sql + order_sql, params)
+ add_condition('id_bibrec', recid)
+ add_condition('status', status)
+ add_condition('type', linkback_type)
+
+ return run_sql(header_sql + ' ' + ' '.join(conditions) + ' ' + order_sql, tuple(params))
def approve_linkback(linkbackid, user_info):
"""
Approve linkback
@param linkbackid: linkback id
@param user_info: user info
"""
update_linkback_status(linkbackid, CFG_WEBLINKBACK_STATUS['APPROVED'], user_info)
def reject_linkback(linkbackid, user_info):
"""
Reject linkback
@param linkbackid: linkback id
@param user_info: user info
"""
update_linkback_status(linkbackid, CFG_WEBLINKBACK_STATUS['REJECTED'], user_info)
def update_linkback_status(linkbackid, new_status, user_info = None):
"""
Update status of a linkback
@param linkbackid: linkback id
@param new_status: new status
@param user_info: user info
"""
if user_info == None:
user_info = {}
user_info['uid'] = CFG_WEBLINKBACK_DEFAULT_USER
run_sql("""UPDATE lnkENTRY
SET status=%s
WHERE id=%s
""", (new_status, linkbackid))
logid = run_sql("""INSERT INTO lnkLOG (id_user, action, log_time)
VALUES
(%s, %s, NOW());
SELECT LAST_INSERT_ID();
""", (user_info['uid'], new_status))
run_sql("""INSERT INTO lnkENTRYLOG (id_lnkENTRY , id_lnkLOG)
VALUES
(%s, %s);
""", (linkbackid, logid))
def create_linkback(origin_url, recid, additional_properties, linkback_type, user_info):
"""
Create linkback
@param origin_url: origin URL,
@param recid: recid
@param additional_properties: additional properties
@param linkback_type: linkback type
@param user_info: user info
@return id of the created linkback
"""
linkbackid = run_sql("""INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time)
VALUES
(%s, %s, %s, %s, %s, NOW());
SELECT LAST_INSERT_ID();
""", (origin_url, recid, str(additional_properties), linkback_type, CFG_WEBLINKBACK_STATUS['PENDING']))
logid = run_sql("""INSERT INTO lnkLOG (id_user, action, log_time)
VALUES
(%s, %s, NOW());
SELECT LAST_INSERT_ID();
""", (user_info['uid'], CFG_WEBLINKBACK_STATUS['INSERTED']))
run_sql("""INSERT INTO lnkENTRYLOG (id_lnkENTRY, id_lnkLOG)
VALUES
(%s, %s);
""", (linkbackid, logid))
# add url title entry if necessary
if len(run_sql("""SELECT url
FROM lnkENTRYURLTITLE
WHERE url=%s
""", (origin_url, ))) == 0:
manual_set_title = 0
title = ""
if additional_properties != "" and 'title' in additional_properties.keys():
manual_set_title = 1
title = additional_properties['title']
run_sql("""INSERT INTO lnkENTRYURLTITLE (url, title, manual_set)
VALUES
(%s, %s, %s)
""", (origin_url, title, manual_set_title))
return linkbackid
def get_approved_latest_added_linkbacks(count):
"""
Get approved latest added linkbacks
@param count: count of the linkbacks
@return [(linkback_id,
origin_url,
recid,
additional_properties,
type,
status,
insert_time)]
in descending order by insert_time
"""
return run_sql("""SELECT id,
origin_url,
id_bibrec,
additional_properties,
type,
status,
insert_time
FROM lnkENTRY
WHERE status=%s
ORDER BY insert_time DESC
LIMIT %s
""", (CFG_WEBLINKBACK_STATUS['APPROVED'], count))
def get_url_list(list_type):
"""
@param list_type: of CFG_WEBLINKBACK_LIST_TYPE
@return (url0, ..., urln) in ascending order by url
"""
result = run_sql("""SELECT url
FROM lnkADMINURL
WHERE list=%s
ORDER by url ASC
""", (list_type, ))
return tuple(url[0] for (url) in result)
def get_urls():
"""
Get all URLs and the corresponding listType
@return ((url, CFG_WEBLINKBACK_LIST_TYPE), ..., (url, CFG_WEBLINKBACK_LIST_TYPE)) in ascending order by url
"""
return run_sql("""SELECT url, list
FROM lnkADMINURL
ORDER by url ASC
""")
def url_exists(url, list_type=None):
"""
Check if url exists
@param url
@param list_type: specific list of CFG_WEBLINKBACK_LIST_TYPE, all if None
@return True or False
"""
header_sql = """SELECT url
FROM lnkADMINURL
WHERE url=%s
"""
optional_sql = " AND list=%s"
result = None
if list_type:
result = run_sql(header_sql + optional_sql, (url, list_type))
else:
result = run_sql(header_sql, (url, ))
if result != ():
return True
else:
return False
def add_url_to_list(url, list_type, user_info):
"""
Add a URL to a list
@param url: unique URL string for all lists
@param list_type: of CFG_WEBLINKBACK_LIST_TYPE
@param user_info: user info
@return id of the created url
"""
urlid = run_sql("""INSERT INTO lnkADMINURL (url, list)
VALUES
(%s, %s);
SELECT LAST_INSERT_ID();
""", (url, list_type))
logid = run_sql("""INSERT INTO lnkLOG (id_user, action, log_time)
VALUES
(%s, %s, NOW());
SELECT LAST_INSERT_ID();
""", (user_info['uid'], CFG_WEBLINKBACK_STATUS['INSERTED']))
run_sql("""INSERT INTO lnkADMINURLLOG (id_lnkADMINURL, id_lnkLOG)
VALUES
(%s, %s);
""", (urlid, logid))
return urlid
def remove_url(url):
"""
Remove a URL from list
@param url: unique URL string for all lists
"""
# get ids
urlid = run_sql("""SELECT id
FROM lnkADMINURL
WHERE url=%s
""", (url, ))[0][0]
logids = run_sql("""SELECT log.id
FROM lnkLOG log
JOIN lnkADMINURLLOG url_log
ON log.id=url_log.id_lnkLOG
WHERE url_log.id_lnkADMINURL=%s
""", (urlid, ))
# delete url and url log
run_sql("""DELETE FROM lnkADMINURL
WHERE id=%s;
DELETE FROM lnkADMINURLLOG
WHERE id_lnkADMINURL=%s
""", (urlid, urlid))
# delete log
for logid in logids:
run_sql("""DELETE FROM lnkLOG
WHERE id=%s
""", (logid[0], ))
def get_urls_and_titles(title_status=None):
"""
Get URLs and their corresponding title
@param old_new: of CFG_WEBLINKBACK_PAGE_TITLE_STATUS or None
@return ((url, title, manual_set),...), all rows of the table if None
"""
top_query = """SELECT url, title, manual_set, broken_count
FROM lnkENTRYURLTITLE
WHERE
"""
where_sql = ""
if title_status == CFG_WEBLINKBACK_PAGE_TITLE_STATUS['NEW']:
where_sql = " title='' AND manual_set=0 AND"
elif title_status == CFG_WEBLINKBACK_PAGE_TITLE_STATUS['OLD']:
where_sql = " title<>'' AND manual_set=0 AND"
elif title_status == CFG_WEBLINKBACK_PAGE_TITLE_STATUS['MANUALLY_SET']:
where_sql = " manual_set=1 AND"
where_sql += " broken=0"
return run_sql(top_query + where_sql)
def update_url_title(url, title):
"""
Update the corresponding title of a URL
@param url: URL
@param title: new title
"""
run_sql("""UPDATE lnkENTRYURLTITLE
SET title=%s,
manual_set=0,
broken_count=0,
broken=0
WHERE url=%s
""", (title, url))
def remove_url_title(url):
"""
Remove URL title
@param url: URL
"""
run_sql("""DELETE FROM lnkENTRYURLTITLE
WHERE url=%s
""", (url, ))
def set_url_broken(url):
"""
Set URL broken
@param url: URL
"""
linkbackids = run_sql("""SELECT id
FROM lnkENTRY
WHERE origin_url=%s
""", (url, ))
run_sql("""UPDATE lnkENTRYURLTITLE
SET title=%s,
broken=1
WHERE url=%s
""", (CFG_WEBLINKBACK_STATUS['BROKEN'], url))
# update all linkbacks
for linkbackid in linkbackids:
update_linkback_status(linkbackid[0], CFG_WEBLINKBACK_STATUS['BROKEN'])
def get_url_title(url):
"""
Get URL title or URL if title does not exist (empty string)
@param url: URL
@return title or URL if titles does not exist (empty string)
"""
title = run_sql("""SELECT title
FROM lnkENTRYURLTITLE
WHERE url=%s and title<>"" and broken=0
""", (url, ))
+ res = url
if len(title) != 0:
- return title[0][0]
- else:
- return url
+ res = title[0][0]
+
+ return xml_entities_to_utf8(res)
def increment_broken_count(url):
"""
Increment broken count a URL
@param url: URL
"""
run_sql("""UPDATE lnkENTRYURLTITLE
SET broken_count=broken_count+1
WHERE url=%s
""", (url, ))
def remove_linkback(linkbackid):
"""
Remove a linkback database
@param linkbackid: unique URL string for all lists
"""
# get ids
logids = run_sql("""SELECT log.id
FROM lnkLOG log
JOIN lnkENTRYLOG entry_log
ON log.id=entry_log.id_lnkLOG
WHERE entry_log.id_lnkENTRY=%s
""", (linkbackid, ))
# delete linkback entry and entry log
run_sql("""DELETE FROM lnkENTRY
WHERE id=%s;
DELETE FROM lnkENTRYLOG
WHERE id_lnkENTRY=%s
""", (linkbackid, linkbackid))
# delete log
for logid in logids:
run_sql("""DELETE FROM lnkLOG
WHERE id=%s
""", (logid[0], ))
diff --git a/modules/weblinkback/lib/weblinkback_regression_tests.py b/modules/weblinkback/lib/weblinkback_regression_tests.py
index e08bf652f..89c8ea963 100644
--- a/modules/weblinkback/lib/weblinkback_regression_tests.py
+++ b/modules/weblinkback/lib/weblinkback_regression_tests.py
@@ -1,898 +1,942 @@
# -*- coding: utf-8 -*-
##
## This file is part of Invenio.
## Copyright (C) 2011, 2012, 2013 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.
"""WebLinkback - Regression Test Suite"""
import unittest
from invenio.config import CFG_SITE_URL, \
- CFG_SITE_RECORD
+ CFG_SITE_RECORD, \
+ CFG_WEBLINKBACK_TRACKBACK_ENABLED
from invenio.dbquery import CFG_DATABASE_NAME
from invenio.testutils import make_test_suite, \
run_test_suite, \
test_web_page_content, \
merge_error_messages
from invenio.dbquery import run_sql
try:
from mock import patch
HAS_MOCK = True
except ImportError:
HAS_MOCK = False
from invenio.weblinkback_dblayer import get_all_linkbacks, \
approve_linkback, \
reject_linkback, \
get_approved_latest_added_linkbacks, \
get_url_list, \
add_url_to_list, \
remove_url, \
url_exists, \
get_url_title, \
get_urls_and_titles, \
remove_linkback, \
set_url_broken,\
update_url_title
from invenio.weblinkback import create_trackback, \
delete_linkbacks_on_blacklist, \
update_linkbacks
from invenio.weblinkback_config import CFG_WEBLINKBACK_STATUS, \
CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME, \
CFG_WEBLINKBACK_LIST_TYPE, \
CFG_WEBLINKBACK_TYPE, \
CFG_WEBLINKBACK_PAGE_TITLE_STATUS
def get_max_auto_increment_id(table):
return run_sql("SELECT Auto_increment FROM information_schema.tables WHERE table_name=%s AND table_schema=%s", (table, CFG_DATABASE_NAME))[0][0] - 1
def remove_test_data():
run_sql("DELETE FROM lnkENTRY")
run_sql("DELETE FROM lnkENTRYURLTITLE")
run_sql("DELETE FROM lnkENTRYLOG")
run_sql("DELETE FROM lnkLOG")
run_sql("DELETE FROM lnkADMINURL")
run_sql("DELETE FROM lnkADMINURLLOG")
class WebLinkbackWebPagesAvailabilityTest(unittest.TestCase):
"""Test WebLinkback web pages whether they are up or not"""
- def test_your_baskets_pages_availability(self):
+ def test_linkback_pages_availability(self):
"""weblinkback - availability of /linkbacks pages"""
error_messages = []
baseurl = CFG_SITE_URL + '/%s/10/linkbacks/' % CFG_SITE_RECORD
_exports = ['', 'display', 'index', 'approve', 'reject']
for url in [baseurl + page for page in _exports]:
error_messages.extend(test_web_page_content(url))
baseurl = CFG_SITE_URL + '/linkbacks/'
error_messages.extend(test_web_page_content(baseurl))
if error_messages:
self.fail(merge_error_messages(error_messages))
def test_weblinkback_admin_interface_availability(self):
"""weblinkback - availability of WebLinkback Admin interface pages"""
baseurl = CFG_SITE_URL + '/admin/weblinkback/weblinkbackadmin.py/'
_exports = ['', 'lists', 'linkbacks']
error_messages = []
for url in [baseurl + page for page in _exports]:
# first try as guest:
error_messages.extend(test_web_page_content(url,
username='guest',
expected_text='Authorization failure'))
# then try as admin:
error_messages.extend(test_web_page_content(url,
username='admin'))
if error_messages:
self.fail(merge_error_messages(error_messages))
return
class WebLinkbackDatabaseTest(unittest.TestCase):
"""Test WebLinkback database layer"""
def setUp(self):
"""Insert test data"""
self.insert_time = []
self.user_info = {'uid': 0}
self.remove_test_data()
# recid 41
run_sql("INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time) VALUES ('URL1', 41, NULL, %s, %s, NOW())", (CFG_WEBLINKBACK_TYPE['TRACKBACK'], CFG_WEBLINKBACK_STATUS['PENDING']))
last_linkback_entryid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
self.insert_time.append(run_sql("SELECT NOW()")[0][0])
run_sql("INSERT INTO lnkLOG (id_user, action, log_time) VALUES (NULL, %s, %s)", (CFG_WEBLINKBACK_STATUS['INSERTED'], self.insert_time[0]))
last_logid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkENTRYLOG (id_lnkENTRY, id_lnkLOG) VALUES (%s, %s)", (last_linkback_entryid, last_logid))
run_sql("INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time) VALUES ('URL2', 41, NULL, %s, %s, NOW())", (CFG_WEBLINKBACK_TYPE['TRACKBACK'], CFG_WEBLINKBACK_STATUS['PENDING']))
last_linkback_entryid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkLOG (id_user, action, log_time) VALUES (NULL, %s, NOW())", (CFG_WEBLINKBACK_STATUS['INSERTED'], ))
last_logid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkENTRYLOG (id_lnkENTRY, id_lnkLOG) VALUES (%s, %s)", (last_linkback_entryid, last_logid))
run_sql("INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time) VALUES ('URL3', 41, NULL, %s, %s, NOW())", (CFG_WEBLINKBACK_TYPE['TRACKBACK'], CFG_WEBLINKBACK_STATUS['PENDING']))
last_linkback_entryid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkLOG (id_user, action, log_time) VALUES (NULL, %s, NOW())", (CFG_WEBLINKBACK_STATUS['INSERTED'], ))
last_logid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkENTRYLOG (id_lnkENTRY, id_lnkLOG) VALUES (%s, %s)", (last_linkback_entryid, last_logid))
run_sql("INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time) VALUES ('URL4', 41, NULL, %s, %s, NOW())", (CFG_WEBLINKBACK_TYPE['TRACKBACK'], CFG_WEBLINKBACK_STATUS['PENDING']))
last_linkback_entryid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkLOG (id_user, action, log_time) VALUES (NULL, %s, NOW())", (CFG_WEBLINKBACK_STATUS['INSERTED'], ))
last_logid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkENTRYLOG (id_lnkENTRY, id_lnkLOG) VALUES (%s, %s)", (last_linkback_entryid, last_logid))
# recid 42
run_sql("INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time) VALUES ('URL5', 42, NULL, %s, %s, NOW())", (CFG_WEBLINKBACK_TYPE['TRACKBACK'], CFG_WEBLINKBACK_STATUS['PENDING']))
last_linkback_entryid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
self.insert_time.append(run_sql("SELECT NOW()")[0][0])
run_sql("INSERT INTO lnkLOG (id_user, action, log_time) VALUES (NULL, %s, %s)", (CFG_WEBLINKBACK_STATUS['INSERTED'], self.insert_time[1]))
last_logid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkENTRYLOG (id_lnkENTRY, id_lnkLOG) VALUES (%s, %s)", (last_linkback_entryid, last_logid))
run_sql("INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time) VALUES ('URL6', 42, NULL, %s, %s, NOW())", (CFG_WEBLINKBACK_TYPE['TRACKBACK'], CFG_WEBLINKBACK_STATUS['PENDING']))
last_linkback_entryid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkLOG (id_user, action, log_time) VALUES (NULL, %s, %s)", (CFG_WEBLINKBACK_STATUS['INSERTED'], self.insert_time[1]))
last_logid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkENTRYLOG (id_lnkENTRY, id_lnkLOG) VALUES (%s, %s)", (last_linkback_entryid, last_logid))
run_sql("INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time) VALUES ('URL7', 42, NULL, %s, %s, NOW())", (CFG_WEBLINKBACK_TYPE['TRACKBACK'], CFG_WEBLINKBACK_STATUS['PENDING']))
last_linkback_entryid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkLOG (id_user, action, log_time) VALUES (NULL, %s, %s)", (CFG_WEBLINKBACK_STATUS['INSERTED'], self.insert_time[1]))
last_logid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkENTRYLOG (id_lnkENTRY, id_lnkLOG) VALUES (%s, %s)", (last_linkback_entryid, last_logid))
run_sql("INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time) VALUES ('URL8', 42, NULL, %s, %s, NOW())", (CFG_WEBLINKBACK_TYPE['TRACKBACK'], CFG_WEBLINKBACK_STATUS['PENDING']))
last_linkback_entryid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkLOG (id_user, action, log_time) VALUES (NULL, %s, %s)", (CFG_WEBLINKBACK_STATUS['INSERTED'], self.insert_time[1]))
last_logid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkENTRYLOG (id_lnkENTRY, id_lnkLOG) VALUES (%s, %s)", (last_linkback_entryid, last_logid))
run_sql("INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time) VALUES ('URL1', 42, NULL, %s, %s, NOW())", (CFG_WEBLINKBACK_TYPE['TRACKBACK'], CFG_WEBLINKBACK_STATUS['PENDING']))
last_linkback_entryid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkLOG (id_user, action, log_time) VALUES (NULL, %s, %s)", (CFG_WEBLINKBACK_STATUS['INSERTED'], self.insert_time[1]))
last_logid = run_sql("SELECT LAST_INSERT_ID()")[0][0]
run_sql("INSERT INTO lnkENTRYLOG (id_lnkENTRY, id_lnkLOG) VALUES (%s, %s)", (last_linkback_entryid, last_logid))
def tearDown(self):
"""Remove test data"""
self.remove_test_data()
def remove_test_data(self):
"""Clean tables"""
self._max_id_lnkENTRY = get_max_auto_increment_id('lnkENTRY')
self._max_id_lnkADMINURL = get_max_auto_increment_id('lnkADMINURL')
self._max_id_lnkLOG = get_max_auto_increment_id('lnkLOG')
remove_test_data()
def get_all_from_table(self, tableName):
return run_sql("SELECT * FROM %s" % tableName) # kwalitee: disable=sql
def test_get_all_linkbacks1(self):
"""weblinkback - get all linkbacks for lnkENTRY and with a certain status"""
self.assertEqual(0, len(get_all_linkbacks(recid=5, status=CFG_WEBLINKBACK_STATUS['PENDING'])))
self.assertEqual(4, len(get_all_linkbacks(recid=41, status=CFG_WEBLINKBACK_STATUS['PENDING'])))
self.assertEqual(0, len(get_all_linkbacks(recid=41, status=CFG_WEBLINKBACK_STATUS['INSERTED'])))
self.assertEqual(5, len(get_all_linkbacks(recid=42, status=CFG_WEBLINKBACK_STATUS['PENDING'])))
self.assertEqual(0, len(get_all_linkbacks(recid=42, status=CFG_WEBLINKBACK_STATUS['APPROVED'])))
url = CFG_SITE_URL + '/%s/41/linkbacks/' % CFG_SITE_RECORD
expected_texts = ('Linkbacks to review: 4', 'Linkbacks: 0', 'URL1', 'URL2', 'URL3', 'URL4')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
url = CFG_SITE_URL + '/%s/42/linkbacks/' % CFG_SITE_RECORD
expected_texts = ('Linkbacks to review: 5', 'Linkbacks: 0', 'URL5', 'URL6', 'URL7', 'URL8', 'URL1')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
def test_get_all_linkbacks2(self):
"""weblinkback - get all linkbacks with a certain status"""
self.assertEqual(9, len(get_all_linkbacks(status=CFG_WEBLINKBACK_STATUS['PENDING'])))
self.assertEqual(0, len(get_all_linkbacks(status=CFG_WEBLINKBACK_STATUS['APPROVED'])))
def test_approve_linkback(self):
"""weblinkback - approve linkback"""
linkback = get_all_linkbacks(41)[0]
linkbackid = linkback[0]
linkback_status = linkback[5]
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_status)
approve_linkback(linkbackid, self.user_info)
linkback = get_all_linkbacks(recid=41)[0]
linkback_status = linkback[5]
self.assertEqual(CFG_WEBLINKBACK_STATUS['APPROVED'], linkback_status)
url = CFG_SITE_URL + '/%s/41/linkbacks/' % CFG_SITE_RECORD
expected_texts = ('Linkbacks to review: 3', 'Linkbacks: 1')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
def test_reject_linkback(self):
"""weblinkback - reject linkback"""
linkback = get_all_linkbacks(recid=42)[1]
linkbackid = linkback[0]
linkback_status = linkback[5]
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_status)
reject_linkback(linkbackid, self.user_info)
linkback = get_all_linkbacks(recid=42)[1]
linkback_status = linkback[5]
self.assertEqual(CFG_WEBLINKBACK_STATUS['REJECTED'], linkback_status)
url = CFG_SITE_URL + '/%s/42/linkbacks/' % CFG_SITE_RECORD
expected_texts = ('Linkbacks to review: 4', 'Linkbacks: 0')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
def test_create_linkback1(self):
"""weblinkback - create linkback"""
recid = 42
argd = {'url': 'URL',
'title': CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME,
'excerpt': CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME,
'blog_name': 'Test Blog',
'id': CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME,
'source': CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME,
}
linkbackid = create_trackback(recid, argd['url'], argd['title'], argd['excerpt'], argd['blog_name'], argd['id'], argd['source'], self.user_info)
self.assertEqual(10 + self._max_id_lnkENTRY, linkbackid)
linkback = get_all_linkbacks(recid=recid)[5]
self.assertEqual(linkbackid, linkback[0])
self.assertEqual(argd['url'], linkback[1])
self.assertEqual(recid, linkback[2])
self.assertEqual(str({'blog_name': argd['blog_name']}), linkback[3])
self.assertEqual(CFG_WEBLINKBACK_TYPE['TRACKBACK'], linkback[4])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback[5])
url = CFG_SITE_URL + '/%s/42/linkbacks/' % CFG_SITE_RECORD
expected_texts = ('Linkbacks to review: 6', 'Linkbacks: 0')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
approve_linkback(linkbackid, self.user_info)
linkback = get_all_linkbacks(recid=recid)[5]
self.assertEqual(linkbackid, linkback[0])
self.assertEqual(argd['url'], linkback[1])
self.assertEqual(recid, linkback[2])
self.assertEqual(str({'blog_name': argd['blog_name']}), linkback[3])
self.assertEqual(CFG_WEBLINKBACK_TYPE['TRACKBACK'], linkback[4])
self.assertEqual(CFG_WEBLINKBACK_STATUS['APPROVED'], linkback[5])
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
self.assertEqual(1, len(url_titles))
self.assertEqual(argd['url'], url_titles[0][1])
self.assertEqual("", url_titles[0][2])
self.assertEqual(0, url_titles[0][3])
self.assertEqual(argd['url'], get_url_title(argd['url']))
self.assertEqual(0, len(get_urls_and_titles(CFG_WEBLINKBACK_PAGE_TITLE_STATUS['OLD'])))
self.assertEqual(1, len(get_urls_and_titles(CFG_WEBLINKBACK_PAGE_TITLE_STATUS['NEW'])))
self.assertEqual(0, len(get_urls_and_titles(CFG_WEBLINKBACK_PAGE_TITLE_STATUS['MANUALLY_SET'])))
url = CFG_SITE_URL + '/%s/42/linkbacks/' % CFG_SITE_RECORD
expected_texts = ('Linkbacks to review: 5', 'Linkbacks: 1')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
self.assertEqual(10, len(self.get_all_from_table("lnkENTRY")))
self.assertEqual(11, len(self.get_all_from_table("lnkENTRYLOG")))
remove_linkback(linkbackid)
self.assertEqual(9, len(self.get_all_from_table("lnkENTRY")))
self.assertEqual(9, len(self.get_all_from_table("lnkENTRYLOG")))
def test_create_linkback2(self):
"""weblinkback - create linkback with URL title"""
recid = 42
argd = {'url': 'URL',
'title': 'My title',
'excerpt': CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME,
'blog_name': 'Test Blog',
'id': CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME,
'source': CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME,
}
linkbackid = create_trackback(recid, argd['url'], argd['title'], argd['excerpt'], argd['blog_name'], argd['id'], argd['source'], self.user_info)
self.assertEqual(10 + self._max_id_lnkENTRY, linkbackid)
linkback = get_all_linkbacks(recid=recid)[5]
self.assertEqual(linkbackid, linkback[0])
self.assertEqual(argd['url'], linkback[1])
self.assertEqual(recid, linkback[2])
self.assertEqual(CFG_WEBLINKBACK_TYPE['TRACKBACK'], linkback[4])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback[5])
url = CFG_SITE_URL + '/%s/42/linkbacks/' % CFG_SITE_RECORD
expected_texts = ('Linkbacks to review: 6', 'Linkbacks: 0')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
approve_linkback(linkbackid, self.user_info)
linkback = get_all_linkbacks(recid=recid)[5]
self.assertEqual(linkbackid, linkback[0])
self.assertEqual(argd['url'], linkback[1])
self.assertEqual(recid, linkback[2])
self.assertEqual(CFG_WEBLINKBACK_TYPE['TRACKBACK'], linkback[4])
self.assertEqual(CFG_WEBLINKBACK_STATUS['APPROVED'], linkback[5])
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
self.assertEqual(1, len(url_titles))
self.assertEqual(argd['url'], url_titles[0][1])
self.assertEqual(argd['title'], url_titles[0][2])
self.assertEqual(1, url_titles[0][3])
self.assertEqual(argd['title'], get_url_title(argd['url']))
self.assertEqual(0, len(get_urls_and_titles(CFG_WEBLINKBACK_PAGE_TITLE_STATUS['OLD'])))
self.assertEqual(0, len(get_urls_and_titles(CFG_WEBLINKBACK_PAGE_TITLE_STATUS['NEW'])))
self.assertEqual(1, len(get_urls_and_titles(CFG_WEBLINKBACK_PAGE_TITLE_STATUS['MANUALLY_SET'])))
url = CFG_SITE_URL + '/%s/42/linkbacks/' % CFG_SITE_RECORD
expected_texts = ('Linkbacks to review: 5', 'Linkbacks: 1')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
def test_send_trackback(self):
"""weblinkback - create linkback through /sendtrackback"""
url = CFG_SITE_URL + '/%s/42/linkbacks/sendtrackback?url=http://www.google.ch' % CFG_SITE_RECORD
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text='',
unexpected_text=''))
url = CFG_SITE_URL + '/%s/42/linkbacks/sendtrackback' % CFG_SITE_RECORD
self.assertNotEqual([], test_web_page_content(url,
username='admin'))
url = CFG_SITE_URL + '/%s/42/linkbacks/sendtrackback?url' % CFG_SITE_RECORD
self.assertNotEqual([], test_web_page_content(url,
username='admin'))
url = CFG_SITE_URL + '/%s/42/linkbacks/sendtrackback?url=' % CFG_SITE_RECORD
self.assertNotEqual([], test_web_page_content(url,
username='admin'))
add_url_to_list('google', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
url = CFG_SITE_URL + '/%s/42/linkbacks/sendtrackback?url=http://www.google.ch' % CFG_SITE_RECORD
self.assertNotEqual([], test_web_page_content(url,
username='admin'))
def test_get_approved_latest_added_linkback(self):
"""weblinkback - get approved latest added linkbacks"""
for linkbackid in (1, 2, 5, 6, 7):
approve_linkback(linkbackid + self._max_id_lnkENTRY, self.user_info)
reject_linkback(4 + self._max_id_lnkENTRY, self.user_info)
self.assertEqual(0, len(get_approved_latest_added_linkbacks(0)))
self.assertEqual(1, len(get_approved_latest_added_linkbacks(1)))
self.assertEqual(2, len(get_approved_latest_added_linkbacks(2)))
self.assertEqual(3, len(get_approved_latest_added_linkbacks(3)))
self.assertEqual(4, len(get_approved_latest_added_linkbacks(4)))
self.assertEqual(5, len(get_approved_latest_added_linkbacks(5)))
approved_linkbacks = get_approved_latest_added_linkbacks(6)
self.assertEqual(5, len(approved_linkbacks))
self.assertEqual(1 + self._max_id_lnkENTRY, approved_linkbacks[0][0])
self.assertEqual(2 + self._max_id_lnkENTRY, approved_linkbacks[1][0])
self.assertEqual(5 + self._max_id_lnkENTRY, approved_linkbacks[2][0])
self.assertEqual(6 + self._max_id_lnkENTRY, approved_linkbacks[3][0])
self.assertEqual(7 + self._max_id_lnkENTRY, approved_linkbacks[4][0])
url = CFG_SITE_URL + '/linkbacks/'
expected_texts = ('URL1', 'URL2', 'URL5', 'URL6', 'URL7')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
unexpected_texts = ('URL3', 'URL4', 'URL8')
for text in unexpected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
unexpected_text=text))
def test_url_add(self):
"""weblinkback - test add URL to list"""
add_url_to_list('url1', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
add_url_to_list('url2', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
add_url_to_list('url3', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
admin_url_table = self.get_all_from_table('lnkADMINURL')
admin_url_log_table = self.get_all_from_table('lnkADMINURLLOG')
log_table = self.get_all_from_table('lnkLOG')
self.assertEqual(3, len(admin_url_table))
self.assertEqual(3, len(admin_url_log_table))
self.assertEqual(12, len(log_table))
url = CFG_SITE_URL + '/admin/weblinkback/weblinkbackadmin.py/lists'
expected_texts = ('url1', 'url2', 'url3')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
def test_url_remove(self):
"""weblinkback - test remove URL rom list"""
add_url_to_list('url1', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
add_url_to_list('url2', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
remove_url('url2')
# creating a different log, might detect a bug in the logging ids
approve_linkback(1 + self._max_id_lnkENTRY, self.user_info)
add_url_to_list('url3', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
admin_url_table = self.get_all_from_table('lnkADMINURL')
admin_url_log_table = self.get_all_from_table('lnkADMINURLLOG')
logTable = self.get_all_from_table('lnkLOG')
self.assertEqual(2, len(admin_url_table))
self.assertEqual(2, len(admin_url_log_table))
# there are more logs due to the inserted linkbacks in setUp()
self.assertEqual(12, len(logTable))
self.assertEqual(1 + self._max_id_lnkADMINURL, admin_url_table[0][0])
# there are more logs due to the inserted linkbacks in setUp()
self.assertEqual(1 + self._max_id_lnkADMINURL, admin_url_log_table[0][0])
self.assertEqual(10 + self._max_id_lnkLOG, admin_url_log_table[0][1])
self.assertEqual(3 + self._max_id_lnkADMINURL, admin_url_table[1][0])
# there are more logs due to the inserted linkbacks in setUp()
self.assertEqual(3 + self._max_id_lnkADMINURL, admin_url_log_table[1][0])
# 9 linkbacks inserted (9)
# 2 urls inserted (11)
# 1 url removed (11) (log id 10 removed)
# 1 linkback approved (12)
# 1 url inserted (13)
self.assertEqual(13 + self._max_id_lnkLOG, admin_url_log_table[1][1])
url = CFG_SITE_URL + '/admin/weblinkback/weblinkbackadmin.py/lists'
expected_texts = ('url1', 'url3')
for text in expected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
expected_text=text))
unexpected_texts = ('url2', )
for text in unexpected_texts:
self.assertEqual([], test_web_page_content(url,
username='admin',
unexpected_text=text))
def test_url_lists(self):
"""weblinkback - test URL lists"""
add_url_to_list('url1', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
add_url_to_list('url2', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
add_url_to_list('url3', CFG_WEBLINKBACK_LIST_TYPE['WHITELIST'], self.user_info)
self.assertEqual(('url1', 'url2'), get_url_list(CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST']))
self.assertEqual(('url3', ), get_url_list(CFG_WEBLINKBACK_LIST_TYPE['WHITELIST']))
remove_url('url2')
remove_url('url3')
self.assertEqual(('url1', ), get_url_list(CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST']))
self.assertEqual(tuple(), get_url_list(CFG_WEBLINKBACK_LIST_TYPE['WHITELIST']))
def test_url_exists(self):
"""weblinkback - test URL existence"""
add_url_to_list('url1', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
add_url_to_list('url2', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
add_url_to_list('url3', CFG_WEBLINKBACK_LIST_TYPE['WHITELIST'], self.user_info)
self.assertTrue(url_exists('url1'))
self.assertTrue(url_exists('url1', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST']))
self.assertFalse(url_exists('url1', CFG_WEBLINKBACK_LIST_TYPE['WHITELIST']))
remove_url('url1')
self.assertFalse(url_exists('url1'))
self.assertFalse(url_exists('url1', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST']))
self.assertFalse(url_exists('url1', CFG_WEBLINKBACK_LIST_TYPE['WHITELIST']))
self.assertTrue(url_exists('url3'))
self.assertFalse(url_exists('url3', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST']))
self.assertTrue(url_exists('url3', CFG_WEBLINKBACK_LIST_TYPE['WHITELIST']))
def test_set_url_broken(self):
"""weblinkback - test set URL broken"""
add_url_to_list('URL1', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
set_url_broken('URL1')
entry_table = self.get_all_from_table('lnkENTRY')
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], entry_table[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], entry_table[8][5])
self.assertEqual(9, len(self.get_all_from_table("lnkENTRY")))
self.assertEqual(11, len(self.get_all_from_table("lnkENTRYLOG")))
def test_delete_linkbacks_on_blacklist(self):
"""weblinkback - test delete linkbacks on blacklist"""
for linkbackid in (1, 2, 3, 4):
approve_linkback(linkbackid + self._max_id_lnkENTRY, self.user_info)
for linkbackid in (5, 6):
reject_linkback(linkbackid + self._max_id_lnkENTRY, self.user_info)
add_url_to_list('RL1', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
add_url_to_list('URL5', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
add_url_to_list('RL7', CFG_WEBLINKBACK_LIST_TYPE['BLACKLIST'], self.user_info)
set_url_broken('URL1')
entry_table = self.get_all_from_table('lnkENTRY')
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], entry_table[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], entry_table[8][5])
self.assertEqual(9, len(self.get_all_from_table("lnkENTRY")))
self.assertEqual(17, len(self.get_all_from_table("lnkENTRYLOG")))
self.assertEqual(20, len(self.get_all_from_table("lnkLOG")))
delete_linkbacks_on_blacklist()
self.assertEqual(5, len(self.get_all_from_table("lnkENTRY")))
self.assertEqual(9, len(self.get_all_from_table("lnkENTRYLOG")))
self.assertEqual(12, len(self.get_all_from_table("lnkLOG")))
+ def test_url_xml_entity_removal(self):
+ """weblinkback - URL XML entity removal"""
+ url = 'This is a test'
+ run_sql("INSERT INTO lnkENTRYURLTITLE ( url, title) VALUES ('URL1', %s)", (url,))
+ self.assertEqual('This is a\xc2\xa0test', get_url_title(url))
+
+ url = 'This “is” “”test”"'
+ run_sql("INSERT INTO lnkENTRYURLTITLE ( url, title) VALUES ('URL2', %s)", (url,))
+ self.assertEqual('This \xe2\x80\x9cis\xe2\x80\x9d \xc2\xa0\xe2\x80\x9c\xe2\x80\x9dtest\xe2\x80\x9d"', get_url_title(url))
+
+ def test_get_pending_trackbacks(self):
+ """weblinkback - get all pending trackbacks"""
+ pending_trackbacks = get_all_linkbacks(linkback_type=CFG_WEBLINKBACK_TYPE['TRACKBACK'], status=CFG_WEBLINKBACK_STATUS['PENDING'])
+ self.assertEqual(9, len(pending_trackbacks))
+ for pending_trackback in pending_trackbacks:
+ approve_linkback(pending_trackback[0], self.user_info)
+ pending_trackbacks = get_all_linkbacks(linkback_type=CFG_WEBLINKBACK_TYPE['TRACKBACK'], status=CFG_WEBLINKBACK_STATUS['PENDING'])
+ self.assertEqual(0, len(pending_trackbacks))
+
+ recid = 42
+ argd = {'url': 'URL',
+ 'title': 'My title',
+ 'excerpt': CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME,
+ 'blog_name': 'Test Blog',
+ 'id': CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME,
+ 'source': CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME,
+ }
+ linkbackid1 = create_trackback(recid, argd['url'], argd['title'], argd['excerpt'], argd['blog_name'], argd['id'], argd['source'], self.user_info)
+ create_trackback(recid, argd['url'], argd['title'], argd['excerpt'], argd['blog_name'], argd['id'], argd['source'], self.user_info)
+
+ pending_trackbacks = get_all_linkbacks(linkback_type=CFG_WEBLINKBACK_TYPE['TRACKBACK'], status=CFG_WEBLINKBACK_STATUS['PENDING'])
+ self.assertEqual(2, len(pending_trackbacks))
+ approve_linkback(linkbackid1, self.user_info)
+ pending_trackbacks = get_all_linkbacks(linkback_type=CFG_WEBLINKBACK_TYPE['TRACKBACK'], status=CFG_WEBLINKBACK_STATUS['PENDING'])
+ self.assertEqual(1, len(pending_trackbacks))
+
+ create_trackback(recid, argd['url'], argd['title'], argd['excerpt'], argd['blog_name'], argd['id'], argd['source'], self.user_info)
+ run_sql("INSERT INTO lnkENTRY (origin_url, id_bibrec, additional_properties, type, status, insert_time) VALUES ('URLN', 41, NULL, %s, %s, NOW())", (CFG_WEBLINKBACK_TYPE['PINGBACK'], CFG_WEBLINKBACK_STATUS['PENDING']))
+ pending_trackbacks = get_all_linkbacks(linkback_type=CFG_WEBLINKBACK_TYPE['TRACKBACK'], status=CFG_WEBLINKBACK_STATUS['PENDING'])
+ self.assertEqual(2, len(pending_trackbacks))
+
def get_title_of_page_mock1(url=""): # pylint: disable=W0613
return "MOCK_TITLE1"
def get_title_of_page_mock2(url=""): # pylint: disable=W0613
return "MOCK_TITLE2"
def get_title_of_page_mock_broken(url=""): # pylint: disable=W0613
return None
class WebLinkbackUpdaterTest(unittest.TestCase):
"""Test WebLinkback updater"""
def setUp(self):
"""Insert test data"""
self.user_info = {'uid': 0}
self.remove_test_data()
def tearDown(self):
"""Remove test data"""
self.remove_test_data()
def remove_test_data(self):
"""Clean tables"""
self._max_id_lnkENTRY = get_max_auto_increment_id('lnkENTRY')
remove_test_data()
def get_all_from_table(self, tableName):
return run_sql("SELECT * FROM %s" % tableName) # kwalitee: disable=sql
if HAS_MOCK:
def test_update_titles_of_new_linkbacks(self):
"""weblinkback - test update titles of new linkbacks"""
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.au&title=Google' % CFG_SITE_RECORD, username='admin'))
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.at' % CFG_SITE_RECORD, username='admin'))
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.co.za&title=Google' % CFG_SITE_RECORD, username='admin'))
p = patch('invenio.weblinkback.get_title_of_page', get_title_of_page_mock1)
p.start()
update_linkbacks(1)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
self.assertEqual("Google", url_titles[0][2])
self.assertEqual(get_title_of_page_mock1(), url_titles[1][2])
self.assertEqual("Google", url_titles[2][2])
p.stop()
if HAS_MOCK:
def test_update_titles_of_old_linkbacks(self):
"""weblinkback - test update titles of old linkbacks"""
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.au&title=Google' % CFG_SITE_RECORD, username='admin'))
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.at' % CFG_SITE_RECORD, username='admin'))
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.co.za&title=Google' % CFG_SITE_RECORD, username='admin'))
update_url_title("http://www.google.au", "Google AU")
p = patch('invenio.weblinkback.get_title_of_page', get_title_of_page_mock1)
p.start()
update_linkbacks(2)
url_entries = self.get_all_from_table("lnkENTRYURLTITLE")
self.assertEqual(get_title_of_page_mock1(), url_entries[0][2])
self.assertEqual("", url_entries[1][2])
self.assertEqual("Google", url_entries[2][2])
update_linkbacks(1)
p.stop()
p = patch('invenio.weblinkback.get_title_of_page', get_title_of_page_mock2)
p.start()
update_linkbacks(2)
url_entries = self.get_all_from_table("lnkENTRYURLTITLE")
self.assertEqual(get_title_of_page_mock2(), url_entries[0][2])
self.assertEqual(get_title_of_page_mock2(), url_entries[1][2])
self.assertEqual("Google", url_entries[2][2])
p.stop()
if HAS_MOCK:
def test_update_manually_set_page_titles(self):
"""weblinkback - test update manually set page titles"""
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.au&title=Google' % CFG_SITE_RECORD, username='admin'))
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.at' % CFG_SITE_RECORD, username='admin'))
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.co.za&title=Google' % CFG_SITE_RECORD, username='admin'))
p = patch('invenio.weblinkback.get_title_of_page', get_title_of_page_mock1)
p.start()
update_linkbacks(3)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
self.assertEqual(get_title_of_page_mock1(), url_titles[0][2])
self.assertEqual("", url_titles[1][2])
self.assertEqual(get_title_of_page_mock1(), url_titles[2][2])
p.stop()
if HAS_MOCK:
def test_detect_and_disable_broken_linkbacks(self):
"""weblinkback - test detect and disable broken linkbacks"""
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.au&title=Google' % CFG_SITE_RECORD, username='admin'))
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.at' % CFG_SITE_RECORD, username='admin'))
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.co.za&title=GoogleCOZA' % CFG_SITE_RECORD, username='admin'))
self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/%s/41/linkbacks/sendtrackback?url=http://www.google.co.za&title=Google' % CFG_SITE_RECORD, username='admin'))
run_sql("""INSERT INTO lnkENTRYURLTITLE (url, title, manual_set, broken_count)
VALUES
(%s, %s, %s, %s)
""", ("http://www.google.de", "Google DE", 0, 3))
p = patch('invenio.weblinkback.get_title_of_page', get_title_of_page_mock_broken)
p.start()
update_linkbacks(4)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
linkback_entries = self.get_all_from_table("lnkENTRY")
self.assertEqual("Google", url_titles[0][2])
self.assertEqual(1, url_titles[0][4])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[0][5])
self.assertEqual("", url_titles[1][2])
self.assertEqual(1, url_titles[1][4])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[1][5])
self.assertEqual("GoogleCOZA", url_titles[2][2])
self.assertEqual(1, url_titles[2][4])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[3][5])
self.assertEqual("Google DE", url_titles[3][2])
self.assertEqual(4, url_titles[3][4])
update_linkbacks(4)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
linkback_entries = self.get_all_from_table("lnkENTRY")
self.assertEqual("Google", url_titles[0][2])
self.assertEqual(2, url_titles[0][4])
self.assertEqual(0, url_titles[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[0][5])
self.assertEqual("", url_titles[1][2])
self.assertEqual(2, url_titles[1][4])
self.assertEqual(0, url_titles[1][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[1][5])
self.assertEqual("GoogleCOZA", url_titles[2][2])
self.assertEqual(2, url_titles[2][4])
self.assertEqual(0, url_titles[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[3][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[3][2])
self.assertEqual(5, url_titles[3][4])
self.assertEqual(1, url_titles[3][5])
update_linkbacks(4)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
linkback_entries = self.get_all_from_table("lnkENTRY")
self.assertEqual("Google", url_titles[0][2])
self.assertEqual(3, url_titles[0][4])
self.assertEqual(0, url_titles[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[0][5])
self.assertEqual("", url_titles[1][2])
self.assertEqual(3, url_titles[1][4])
self.assertEqual(0, url_titles[1][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[1][5])
self.assertEqual("GoogleCOZA", url_titles[2][2])
self.assertEqual(3, url_titles[2][4])
self.assertEqual(0, url_titles[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[3][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[3][2])
self.assertEqual(5, url_titles[3][4])
self.assertEqual(1, url_titles[3][5])
p.stop()
p = patch('invenio.weblinkback.get_title_of_page', get_title_of_page_mock1)
p.start()
update_linkbacks(1)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
linkback_entries = self.get_all_from_table("lnkENTRY")
self.assertEqual("Google", url_titles[0][2])
self.assertEqual(3, url_titles[0][4])
self.assertEqual(0, url_titles[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[0][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[1][2])
self.assertEqual(0, url_titles[1][4])
self.assertEqual(0, url_titles[1][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[1][5])
self.assertEqual("GoogleCOZA", url_titles[2][2])
self.assertEqual(3, url_titles[2][4])
self.assertEqual(0, url_titles[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[3][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[3][2])
self.assertEqual(5, url_titles[3][4])
self.assertEqual(1, url_titles[3][5])
approve_linkback(4 + self._max_id_lnkENTRY, self.user_info)
update_linkbacks(3)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
linkback_entries = self.get_all_from_table("lnkENTRY")
self.assertEqual(get_title_of_page_mock1(), url_titles[0][2])
self.assertEqual(0, url_titles[0][4])
self.assertEqual(0, url_titles[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[0][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[1][2])
self.assertEqual(0, url_titles[1][4])
self.assertEqual(0, url_titles[1][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[1][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[2][2])
self.assertEqual(0, url_titles[2][4])
self.assertEqual(0, url_titles[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['APPROVED'], linkback_entries[3][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[3][2])
self.assertEqual(5, url_titles[3][4])
self.assertEqual(1, url_titles[3][5])
p.stop()
p = patch('invenio.weblinkback.get_title_of_page', get_title_of_page_mock_broken)
p.start()
update_linkbacks(4)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
linkback_entries = self.get_all_from_table("lnkENTRY")
self.assertEqual(get_title_of_page_mock1(), url_titles[0][2])
self.assertEqual(1, url_titles[0][4])
self.assertEqual(0, url_titles[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[0][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[1][2])
self.assertEqual(1, url_titles[1][4])
self.assertEqual(0, url_titles[1][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[1][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[2][2])
self.assertEqual(1, url_titles[2][4])
self.assertEqual(0, url_titles[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['APPROVED'], linkback_entries[3][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[3][2])
self.assertEqual(5, url_titles[3][4])
self.assertEqual(1, url_titles[3][5])
reject_linkback(1 + self._max_id_lnkENTRY, self.user_info)
reject_linkback(3 + self._max_id_lnkENTRY, self.user_info)
update_linkbacks(4)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
linkback_entries = self.get_all_from_table("lnkENTRY")
self.assertEqual(get_title_of_page_mock1(), url_titles[0][2])
self.assertEqual(2, url_titles[0][4])
self.assertEqual(0, url_titles[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['REJECTED'], linkback_entries[0][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[1][2])
self.assertEqual(2, url_titles[1][4])
self.assertEqual(0, url_titles[1][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[1][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[2][2])
self.assertEqual(2, url_titles[2][4])
self.assertEqual(0, url_titles[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['REJECTED'], linkback_entries[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['APPROVED'], linkback_entries[3][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[3][2])
self.assertEqual(5, url_titles[3][4])
self.assertEqual(1, url_titles[3][5])
update_linkbacks(4)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
linkback_entries = self.get_all_from_table("lnkENTRY")
self.assertEqual(get_title_of_page_mock1(), url_titles[0][2])
self.assertEqual(3, url_titles[0][4])
self.assertEqual(0, url_titles[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['REJECTED'], linkback_entries[0][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[1][2])
self.assertEqual(3, url_titles[1][4])
self.assertEqual(0, url_titles[1][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[1][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[2][2])
self.assertEqual(3, url_titles[2][4])
self.assertEqual(0, url_titles[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['REJECTED'], linkback_entries[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['APPROVED'], linkback_entries[3][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[3][2])
self.assertEqual(5, url_titles[3][4])
self.assertEqual(1, url_titles[3][5])
update_linkbacks(4)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
linkback_entries = self.get_all_from_table("lnkENTRY")
self.assertEqual(get_title_of_page_mock1(), url_titles[0][2])
self.assertEqual(4, url_titles[0][4])
self.assertEqual(0, url_titles[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['REJECTED'], linkback_entries[0][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[1][2])
self.assertEqual(4, url_titles[1][4])
self.assertEqual(0, url_titles[1][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['PENDING'], linkback_entries[1][5])
self.assertEqual(get_title_of_page_mock1(), url_titles[2][2])
self.assertEqual(4, url_titles[2][4])
self.assertEqual(0, url_titles[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['REJECTED'], linkback_entries[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['APPROVED'], linkback_entries[3][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[3][2])
self.assertEqual(5, url_titles[3][4])
self.assertEqual(1, url_titles[3][5])
update_linkbacks(4)
url_titles = self.get_all_from_table("lnkENTRYURLTITLE")
linkback_entries = self.get_all_from_table("lnkENTRY")
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[0][2])
self.assertEqual(5, url_titles[0][4])
self.assertEqual(1, url_titles[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], linkback_entries[0][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[1][2])
self.assertEqual(5, url_titles[1][4])
self.assertEqual(1, url_titles[1][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], linkback_entries[1][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[2][2])
self.assertEqual(5, url_titles[2][4])
self.assertEqual(1, url_titles[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], linkback_entries[2][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], linkback_entries[3][5])
self.assertEqual(CFG_WEBLINKBACK_STATUS['BROKEN'], url_titles[3][2])
self.assertEqual(5, url_titles[3][4])
self.assertEqual(1, url_titles[3][5])
p.stop()
-
-TEST_SUITE = make_test_suite(WebLinkbackWebPagesAvailabilityTest,
- WebLinkbackDatabaseTest,
- WebLinkbackUpdaterTest)
+if CFG_WEBLINKBACK_TRACKBACK_ENABLED:
+ TEST_SUITE = make_test_suite(WebLinkbackWebPagesAvailabilityTest,
+ WebLinkbackDatabaseTest,
+ WebLinkbackUpdaterTest)
+else:
+ TEST_SUITE = make_test_suite()
if __name__ == "__main__":
run_test_suite(TEST_SUITE, warn_user=True)
diff --git a/modules/weblinkback/lib/weblinkback_templates.py b/modules/weblinkback/lib/weblinkback_templates.py
index c2dd31514..9142bd50a 100644
--- a/modules/weblinkback/lib/weblinkback_templates.py
+++ b/modules/weblinkback/lib/weblinkback_templates.py
@@ -1,284 +1,287 @@
# -*- coding: utf-8 -*-
## Comments and reviews for records.
## This file is part of Invenio.
## Copyright (C) 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.
"""WebLinkback - Web Templates"""
from invenio.weblinkback_dblayer import get_all_linkbacks, \
get_url_title
from invenio.weblinkback_config import CFG_WEBLINKBACK_STATUS, \
CFG_WEBLINKBACK_LATEST_COUNT_VALUES, \
CFG_WEBLINKBACK_ACTION_RETURN_CODE
from invenio.weblinkback import generate_redirect_url
from invenio.messages import gettext_set_language
from invenio.dateutils import convert_datetext_to_dategui
from invenio.config import CFG_SITE_RECORD, \
CFG_SITE_URL, \
CFG_WEBCOMMENT_USE_MATHJAX_IN_COMMENTS
from invenio.htmlutils import get_mathjax_header
from invenio.bibformat import format_record
import cgi
class Template:
def tmpl_linkbacks_general(self, recid, ln):
"""
Display general linkback information
"""
_ = gettext_set_language(ln)
+ url = get_trackback_url(recid)
out = '
'
out += _("Trackback URL: ")
- out += get_trackback_url(recid)
+ out += '%s' % (url, url)
out += '
'
+ out += '
Trackbacks are used in blog systems to refer to external content. Please copy and paste this trackback URL to the appropriate field of your blog post if you want to refer to this record.
'
+ out += ' '
return out
def tmpl_linkbacks(self, approved_linkbacks, ln):
"""
Display the approved linkbacks of a record
@param approved_linkbacks: approved linkbacks to display
"""
_ = gettext_set_language(ln)
out = self.tmpl_linkbacks_count(approved_linkbacks, ln)
if approved_linkbacks:
out += self.tmpl_linkback_tuple(approved_linkbacks, ln)
return out
def tmpl_linkbacks_admin(self, pending_linkbacks, recid, ln):
"""
Display the pending linkbacks of a record and admin approve/reject features
@param pending_linkbacks: pending linkbacks
"""
_ = gettext_set_language(ln)
out = ''
out += self.tmpl_linkbacks_count(pending_linkbacks, ln, _('to review'))
out += self.tmpl_linkback_tuple_admin(url_approve_prefix=generate_redirect_url(recid, ln, 'approve'),
url_reject_prefix=generate_redirect_url(recid, ln, 'reject'),
linkbacks=pending_linkbacks,
ln=ln)
return out
def tmpl_linkbacks_count(self, linkbacks, ln, additional_text = ''):
"""
Display the count of linkbacks plus an additional text in a grey field
@param linkbacks: collection of linkbacks
@param additional_text: additional text to be display
"""
_ = gettext_set_language(ln)
middle_text = ""
if additional_text != "":
middle_text = " " + additional_text
return self.tmpl_heading(cgi.escape(_('Linkbacks%s: %s')) % (middle_text, len(linkbacks)))
def tmpl_heading(self, text):
"""
Display a text in a grey field
@param text: text
"""
return '''
%s
''' % text
def tmpl_linkback_tuple(self, linkbacks, ln):
"""
Display a linkback
@param linkbacks: collection of linkbacks: [(linkback_id,
origin_url,
recid,
additional_properties,
type,
status,
insert_time)]
"""
_ = gettext_set_language(ln)
out = '
'
for current_linkback in linkbacks:
url = current_linkback[1]
out += '''
''' % {
'type': current_linkback[4],
'origin_url': cgi.escape(url),
'page_title': cgi.escape(get_url_title(url)),
'submit_date': '(submitted on ' + convert_datetext_to_dategui(str(current_linkback[6])) + ')'}
out += '
'
return out
def tmpl_linkback_tuple_admin(self, url_approve_prefix, url_reject_prefix, linkbacks, ln):
"""
Display linkbacks with admin approve/reject features
@param linkbacks: collection of linkbacks: [(linkback_id,
origin_url,
recid,
additional_properties,
type,
status,
insert_time)]
"""
_ = gettext_set_language(ln)
out = ''
for current_linkback in linkbacks:
linkbackid = current_linkback[0]
url = current_linkback[1]
out += '
'
out += '
%s
' % (_('Submitted on') + ' ' + convert_datetext_to_dategui(str(current_linkback[6])) + ':')
out += ' '
out += '
'
out += '''(%(type)s) %(page_title)s''' % {
'type': current_linkback[4],
'origin_url': cgi.escape(url),
'page_title': cgi.escape(get_url_title(url))}
out += '
'
out += ' '
out += '
'
out += ''
out += '''%s''' % (url_approve_prefix, linkbackid, _("Approve"))
out += ' | '
out += '''%s''' % (url_reject_prefix, linkbackid, _("Reject"))
out += ''
out += '
'
out += '
'
return out
def tmpl_get_mathjaxheader_jqueryheader(self):
mathjaxheader = ''
if CFG_WEBCOMMENT_USE_MATHJAX_IN_COMMENTS:
mathjaxheader = get_mathjax_header()
jqueryheader = '''
''' % {'CFG_SITE_URL': CFG_SITE_URL}
return (mathjaxheader, jqueryheader)
def tmpl_get_latest_linkbacks_top(self, current_value, ln):
"""
Top elements to select the count of approved latest added linkbacks to display
@param current_value: current value option will be selected if it exists
"""
_ = gettext_set_language(ln)
result = """
""" % _("Refresh")
return result
def tmpl_get_latest_linkbacks(self, latest_linkbacks, ln):
"""
Display approved latest added linkbacks to display
@param latest_linkbacks: a list of lists of linkbacks
"""
result = ''
for i in range(len(latest_linkbacks)):
day_group = latest_linkbacks[i]
date = day_group[0][6]
date_day_month = convert_datetext_to_dategui(str(date))[:6]
result += self.tmpl_heading(date_day_month)
for j in range(len(day_group)):
current_linkback = day_group[j]
link_type = current_linkback[4]
url = str(current_linkback[1])
recordid = current_linkback[2]
result += '(%s) ' % link_type
result += ''
result += '%s links to ' % (cgi.escape(url), cgi.escape(get_url_title(url)))
result += format_record(recID=recordid, of='hs', ln=ln)
result += ''
result += ' '
result += ' '
return result
def tmpl_admin_index(self, ln):
"""
Index page of admin interface
"""
_ = gettext_set_language(ln)
out = ''
pending_linkback_count = len(get_all_linkbacks(status=CFG_WEBLINKBACK_STATUS['PENDING']))
stat_pending_text = ""
if pending_linkback_count > 0:
stat_pending_text = ' ('
if pending_linkback_count == 1:
stat_pending_text += "%s pending linkback request" % pending_linkback_count
elif pending_linkback_count > 1:
stat_pending_text += "%s pending linkback requests"% pending_linkback_count
stat_pending_text += ')'
out += '
' % \
{'siteURL': CFG_SITE_URL,
'ln': ln,
'returnCode': CFG_WEBLINKBACK_ACTION_RETURN_CODE['OK'],
'label': _("Linkback Whitelist/Blacklist Manager")}
out += ''
from invenio.bibrankadminlib import addadminbox
return addadminbox('%s'% _("Menu"), [out])
def get_trackback_url(recid):
return '%s/%s/%s/linkbacks/sendtrackback' % (CFG_SITE_URL, CFG_SITE_RECORD, recid)
def get_trackback_auto_discovery_tag(recid):
return '' \
% cgi.escape(get_trackback_url(recid), True)
diff --git a/modules/weblinkback/lib/weblinkback_webinterface.py b/modules/weblinkback/lib/weblinkback_webinterface.py
index 4cc98d73e..bae03f805 100644
--- a/modules/weblinkback/lib/weblinkback_webinterface.py
+++ b/modules/weblinkback/lib/weblinkback_webinterface.py
@@ -1,255 +1,262 @@
# -*- coding: utf-8 -*-
## Comments and reviews for records.
## This file is part of Invenio.
## Copyright (C) 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.
"""WebLinkback - Web Interface"""
from invenio.messages import gettext_set_language
from invenio.webinterface_handler import wash_urlargd, WebInterfaceDirectory
from invenio.webuser import getUid, collect_user_info, page_not_authorized
from invenio.weblinkback import check_user_can_view_linkbacks, \
perform_sendtrackback, \
perform_request_display_record_linbacks, \
- perform_request_display_approved_latest_added_linkbacks
+ perform_request_display_approved_latest_added_linkbacks_to_accessible_records, \
+ perform_sendtrackback_disabled
from invenio.weblinkback_dblayer import approve_linkback, \
reject_linkback
from invenio.weblinkback_config import CFG_WEBLINKBACK_LATEST_COUNT_DEFAULT, \
CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME
from invenio.urlutils import redirect_to_url, make_canonical_urlargd
from invenio.config import CFG_SITE_URL, \
CFG_SITE_SECURE_URL, \
CFG_SITE_LANG, \
- CFG_SITE_RECORD
+ CFG_SITE_RECORD, \
+ CFG_WEBLINKBACK_TRACKBACK_ENABLED
from invenio.search_engine import guess_primary_collection_of_a_record, \
create_navtrail_links, \
get_colID
from invenio.webpage import pageheaderonly, pagefooteronly
from invenio.websearchadminlib import get_detailed_page_tabs
from invenio.access_control_engine import acc_authorize_action
import invenio.template
webstyle_templates = invenio.template.load('webstyle')
websearch_templates = invenio.template.load('websearch')
weblinkback_templates = invenio.template.load('weblinkback')
class WebInterfaceRecordLinkbacksPages(WebInterfaceDirectory):
"""Define the set of record/number/linkbacks pages."""
_exports = ['', 'display', 'index', 'approve', 'reject', 'sendtrackback']
def __init__(self, recid = -1):
self.recid = recid
def index(self, req, form):
"""
Redirect to display function
"""
return self.display(req, form)
def display(self, req, form):
"""
Display the linkbacks of a record and admin approve/reject features
"""
argd = wash_urlargd(form, {})
_ = gettext_set_language(argd['ln'])
# Check authorization
uid = getUid(req)
user_info = collect_user_info(req)
(auth_code, auth_msg) = check_user_can_view_linkbacks(user_info, self.recid)
if auth_code and user_info['email'] == 'guest':
# Ask to login
target = CFG_SITE_SECURE_URL + '/youraccount/login' + \
make_canonical_urlargd({'ln': argd['ln'],
'referer': CFG_SITE_URL + user_info['uri']}, {})
return redirect_to_url(req, target)
elif auth_code:
return page_not_authorized(req,
referer="../",
uid=uid,
text=auth_msg,
ln=argd['ln'])
show_admin = False
(auth_code, auth_msg) = acc_authorize_action(req, 'moderatelinkbacks', collection = guess_primary_collection_of_a_record(self.recid))
if not auth_code:
show_admin = True
body = perform_request_display_record_linbacks(req, self.recid, show_admin, weblinkback_templates=weblinkback_templates, ln=argd['ln'])
title = websearch_templates.tmpl_record_page_header_content(req, self.recid, argd['ln'])[0]
# navigation, tabs, top and bottom part
navtrail = create_navtrail_links(cc=guess_primary_collection_of_a_record(self.recid), ln=argd['ln'])
if navtrail:
navtrail += ' > '
navtrail += ''% (CFG_SITE_URL, CFG_SITE_RECORD, self.recid, argd['ln'])
navtrail += title
navtrail += ''
navtrail += ' > Linkbacks'
mathjaxheader, jqueryheader = weblinkback_templates.tmpl_get_mathjaxheader_jqueryheader()
unordered_tabs = get_detailed_page_tabs(get_colID(guess_primary_collection_of_a_record(self.recid)),
self.recid,
ln=argd['ln'])
ordered_tabs_id = [(tab_id, values['order']) for (tab_id, values) in unordered_tabs.iteritems()]
ordered_tabs_id.sort(lambda x, y: cmp(x[1], y[1]))
link_ln = ''
if argd['ln'] != CFG_SITE_LANG:
link_ln = '?ln=%s' % argd['ln']
tabs = [(unordered_tabs[tab_id]['label'], \
'%s/%s/%s/%s%s' % (CFG_SITE_URL, CFG_SITE_RECORD, self.recid, tab_id, link_ln), \
tab_id in ['linkbacks'],
unordered_tabs[tab_id]['enabled']) \
for (tab_id, values) in ordered_tabs_id
if unordered_tabs[tab_id]['visible'] == True]
top = webstyle_templates.detailed_record_container_top(self.recid,
tabs,
argd['ln'])
bottom = webstyle_templates.detailed_record_container_bottom(self.recid,
tabs,
argd['ln'])
return pageheaderonly(title=title,
navtrail=navtrail,
uid=uid,
verbose=1,
metaheaderadd = mathjaxheader + jqueryheader,
req=req,
language=argd['ln'],
navmenuid='search',
navtrail_append_title_p=0) + \
websearch_templates.tmpl_search_pagestart(argd['ln']) + \
top + body + bottom + \
websearch_templates.tmpl_search_pageend(argd['ln']) + \
pagefooteronly(language=argd['ln'], req=req)
# Return the same page whether we ask for /CFG_SITE_RECORD/123/linkbacks or /CFG_SITE_RECORD/123/linkbacks/
__call__ = index
def approve(self, req, form):
"""
Approve a linkback
"""
argd = wash_urlargd(form, {'linkbackid': (int, -1)})
authorization = self.check_authorization_moderatelinkbacks(req, argd)
if not authorization:
approve_linkback(argd['linkbackid'], collect_user_info(req))
return self.display(req, form)
else:
return authorization
def reject(self, req, form):
"""
Reject a linkback
"""
argd = wash_urlargd(form, {'linkbackid': (int, -1)})
authorization = self.check_authorization_moderatelinkbacks(req, argd)
if not authorization:
reject_linkback(argd['linkbackid'], collect_user_info(req))
return self.display(req, form)
else:
return authorization
def check_authorization_moderatelinkbacks(self, req, argd):
"""
Check if user has authorization moderate linkbacks
@return if yes: nothing, if guest: login redirect, otherwise page_not_authorized
"""
# Check authorization
uid = getUid(req)
user_info = collect_user_info(req)
(auth_code, auth_msg) = acc_authorize_action(req, 'moderatelinkbacks', collection = guess_primary_collection_of_a_record(self.recid))
if auth_code and user_info['email'] == 'guest':
# Ask to login
target = CFG_SITE_SECURE_URL + '/youraccount/login' + \
make_canonical_urlargd({'ln': argd['ln'],
'referer': CFG_SITE_URL + user_info['uri']}, {})
return redirect_to_url(req, target)
elif auth_code:
return page_not_authorized(req,
referer="../",
uid=uid,
text=auth_msg,
ln=argd['ln'])
def sendtrackback(self, req, form):
"""
Send a new trackback
"""
- argd = wash_urlargd(form, {'url': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
- 'title': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
- 'excerpt': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
- 'blog_name': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
- 'id': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
- 'source': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
- })
-
- perform_sendtrackback(req, self.recid, argd['url'], argd['title'], argd['excerpt'], argd['blog_name'], argd['id'], argd['source'], argd['ln'])
+ if CFG_WEBLINKBACK_TRACKBACK_ENABLED:
+ argd = wash_urlargd(form, {'url': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
+ 'title': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
+ 'excerpt': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
+ 'blog_name': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
+ 'id': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
+ 'source': (str, CFG_WEBLINKBACK_SUBSCRIPTION_DEFAULT_ARGUMENT_NAME),
+ })
+
+ perform_sendtrackback(req, self.recid, argd['url'], argd['title'], argd['excerpt'], argd['blog_name'], argd['id'], argd['source'], argd['ln'])
+ else:
+ perform_sendtrackback_disabled(req)
class WebInterfaceRecentLinkbacksPages(WebInterfaceDirectory):
"""Define the set of global /linkbacks pages."""
_exports = ['', 'display', 'index']
def index(self, req, form):
"""
Redirect to display function
"""
return self.display(req, form)
def display(self, req, form):
"""
Display approved latest added linkbacks of the invenio instance
"""
argd = wash_urlargd(form, {'rg': (int, CFG_WEBLINKBACK_LATEST_COUNT_DEFAULT)})
# count must be positive
if argd['rg'] < 0:
argd['rg'] = -argd['rg']
_ = gettext_set_language(argd['ln'])
- body = perform_request_display_approved_latest_added_linkbacks(argd['rg'], argd['ln'], weblinkback_templates=weblinkback_templates)
+ user_info = collect_user_info(req)
+
+ body = perform_request_display_approved_latest_added_linkbacks_to_accessible_records(argd['rg'], argd['ln'], user_info, weblinkback_templates=weblinkback_templates)
navtrail = 'Recent Linkbacks'
mathjaxheader, jqueryheader = weblinkback_templates.tmpl_get_mathjaxheader_jqueryheader()
return pageheaderonly(title=navtrail,
navtrail=navtrail,
verbose=1,
metaheaderadd = mathjaxheader + jqueryheader,
req=req,
language=argd['ln'],
navmenuid='search',
navtrail_append_title_p=0) + \
websearch_templates.tmpl_search_pagestart(argd['ln']) + \
body + \
websearch_templates.tmpl_search_pageend(argd['ln']) + \
pagefooteronly(language=argd['ln'], req=req)
# Return the same page whether we ask for /linkbacks or /linkbacks/
__call__ = index
diff --git a/modules/webstyle/lib/webstyle_templates.py b/modules/webstyle/lib/webstyle_templates.py
index 99a0439d9..30af32a96 100644
--- a/modules/webstyle/lib/webstyle_templates.py
+++ b/modules/webstyle/lib/webstyle_templates.py
@@ -1,1018 +1,1020 @@
## This file is part of Invenio.
-## Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 CERN.
+## Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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.
"""
WebStyle templates. Customize the look of pages of Invenio
"""
__revision__ = \
"$Id$"
import time
import cgi
import traceback
import urllib
import sys
import string
from invenio.config import \
CFG_SITE_RECORD, \
CFG_SITE_LANG, \
CFG_SITE_NAME, \
CFG_SITE_NAME_INTL, \
CFG_SITE_SUPPORT_EMAIL, \
CFG_SITE_SECURE_URL, \
CFG_SITE_URL, \
CFG_VERSION, \
CFG_WEBSTYLE_INSPECT_TEMPLATES, \
CFG_WEBSTYLE_TEMPLATE_SKIN, \
- CFG_INSPIRE_SITE
+ CFG_INSPIRE_SITE, \
+ CFG_WEBLINKBACK_TRACKBACK_ENABLED
from invenio.messages import gettext_set_language, language_list_long, is_language_rtl
from invenio.urlutils import make_canonical_urlargd, create_html_link, \
get_canonical_and_alternates_urls
from invenio.dateutils import convert_datecvs_to_datestruct, \
convert_datestruct_to_dategui
from invenio.bibformat import format_record
from invenio import template
websearch_templates = template.load('websearch')
class Template:
def tmpl_navtrailbox_body(self, ln, title, previous_links,
separator, prolog, epilog):
"""Create navigation trail box body
Parameters:
- 'ln' *string* - The language to display
- 'title' *string* - page title;
- 'previous_links' *string* - the trail content from site title until current page (both ends exclusive)
- 'prolog' *string* - HTML code to prefix the navtrail item with
- 'epilog' *string* - HTML code to suffix the navtrail item with
- 'separator' *string* - HTML code that separates two navtrail items
Output:
- text containing the navtrail
Note: returns empty string for Home page. (guessed by title).
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
if title == CFG_SITE_NAME_INTL.get(ln, CFG_SITE_NAME):
# return empty string for the Home page
return out
else:
out += create_html_link(CFG_SITE_URL, {'ln': ln},
_("Home"), {'class': 'navtrail'})
if previous_links:
if out:
out += separator
out += previous_links
if title:
if out:
out += separator
if title == CFG_SITE_NAME_INTL.get(ln, CFG_SITE_NAME): # hide site name, print Home instead
out += cgi.escape(_("Home"))
else:
out += cgi.escape(title)
return cgi.escape(prolog) + out + cgi.escape(epilog)
def tmpl_page(self, req=None, ln=CFG_SITE_LANG, description="",
keywords="", userinfobox="", useractivities_menu="",
adminactivities_menu="", navtrailbox="",
pageheaderadd="", boxlefttop="", boxlefttopadd="",
boxleftbottom="", boxleftbottomadd="",
boxrighttop="", boxrighttopadd="",
boxrightbottom="", boxrightbottomadd="",
titleprologue="", title="", titleepilogue="",
body="", lastupdated=None, pagefooteradd="", uid=0,
secure_page_p=0, navmenuid="", metaheaderadd="",
rssurl=CFG_SITE_URL+"/rss",
show_title_p=True, body_css_classes=None,
show_header=True, show_footer=True):
"""Creates a complete page
Parameters:
- 'ln' *string* - The language to display
- 'description' *string* - description goes to the metadata in the header of the HTML page,
not yet escaped for HTML
- 'keywords' *string* - keywords goes to the metadata in the header of the HTML page,
not yet escaped for HTML
- 'userinfobox' *string* - the HTML code for the user information box
- 'useractivities_menu' *string* - the HTML code for the user activities menu
- 'adminactivities_menu' *string* - the HTML code for the admin activities menu
- 'navtrailbox' *string* - the HTML code for the navigation trail box
- 'pageheaderadd' *string* - additional page header HTML code
- 'boxlefttop' *string* - left-top box HTML code
- 'boxlefttopadd' *string* - additional left-top box HTML code
- 'boxleftbottom' *string* - left-bottom box HTML code
- 'boxleftbottomadd' *string* - additional left-bottom box HTML code
- 'boxrighttop' *string* - right-top box HTML code
- 'boxrighttopadd' *string* - additional right-top box HTML code
- 'boxrightbottom' *string* - right-bottom box HTML code
- 'boxrightbottomadd' *string* - additional right-bottom box HTML code
- 'title' *string* - the title of the page, not yet escaped for HTML
- 'titleprologue' *string* - what to print before page title
- 'titleepilogue' *string* - what to print after page title
- 'body' *string* - the body of the page
- 'lastupdated' *string* - when the page was last updated
- 'uid' *int* - user ID
- 'pagefooteradd' *string* - additional page footer HTML code
- 'secure_page_p' *int* (0 or 1) - are we to use HTTPS friendly page elements or not?
- 'navmenuid' *string* - the id of the navigation item to highlight for this page
- 'metaheaderadd' *string* - list of further tags to add to the part of the page
- 'rssurl' *string* - the url of the RSS feed for this page
- 'show_title_p' *int* (0 or 1) - do we display the page title in the body of the page?
- 'body_css_classes' *list* - list of classes to add to the body tag
- 'show_header' *boolean* - tells whether page header should be displayed or not
- 'show_footer' *boolean* - tells whether page footer should be displayed or not
Output:
- HTML code of the page
"""
# load the right message language
_ = gettext_set_language(ln)
out = ''
if show_header:
out += self.tmpl_pageheader(req,
ln = ln,
headertitle = title,
description = description,
keywords = keywords,
metaheaderadd = metaheaderadd,
userinfobox = userinfobox,
useractivities_menu = useractivities_menu,
adminactivities_menu = adminactivities_menu,
navtrailbox = navtrailbox,
pageheaderadd = pageheaderadd,
uid=uid,
secure_page_p = secure_page_p,
navmenuid=navmenuid,
rssurl=rssurl,
body_css_classes=body_css_classes)
out += """
' or '',
'titleepilogue' : titleepilogue,
'body' : body,
}
if show_footer:
out += self.tmpl_pagefooter(req, ln = ln,
lastupdated = lastupdated,
pagefooteradd = pagefooteradd)
return out
def tmpl_pageheader(self, req, ln=CFG_SITE_LANG, headertitle="",
description="", keywords="", userinfobox="",
useractivities_menu="", adminactivities_menu="",
navtrailbox="", pageheaderadd="", uid=0,
secure_page_p=0, navmenuid="admin", metaheaderadd="",
rssurl=CFG_SITE_URL+"/rss", body_css_classes=None):
- from invenio.weblinkback_templates import get_trackback_auto_discovery_tag
- # Embed a link in the header to subscribe trackbacks
- # TODO: This hack must be replaced with the introduction of the new web framework
- uri = req.unparsed_uri
- recordIndexInURI = uri.find('/' + CFG_SITE_RECORD + '/')
- headerLinkbackTrackbackLink = ''
- # substring found --> offer trackback link in header
- if recordIndexInURI != -1:
- recid = uri[recordIndexInURI:len(uri)].split('/')[2].split("?")[0] #recid might end with ? for journal records
- headerLinkbackTrackbackLink = get_trackback_auto_discovery_tag(recid)
-
"""Creates a page header
Parameters:
- 'ln' *string* - The language to display
- 'headertitle' *string* - the title of the HTML page, not yet escaped for HTML
- 'description' *string* - description goes to the metadata in the header of the HTML page,
not yet escaped for HTML
- 'keywords' *string* - keywords goes to the metadata in the header of the HTML page,
not yet escaped for HTML
- 'userinfobox' *string* - the HTML code for the user information box
- 'useractivities_menu' *string* - the HTML code for the user activities menu
- 'adminactivities_menu' *string* - the HTML code for the admin activities menu
- 'navtrailbox' *string* - the HTML code for the navigation trail box
- 'pageheaderadd' *string* - additional page header HTML code
- 'uid' *int* - user ID
- 'secure_page_p' *int* (0 or 1) - are we to use HTTPS friendly page elements or not?
- 'navmenuid' *string* - the id of the navigation item to highlight for this page
- 'metaheaderadd' *string* - list of further tags to add to the part of the page
- 'rssurl' *string* - the url of the RSS feed for this page
- 'body_css_classes' *list* - list of classes to add to the body tag
Output:
- HTML code of the page headers
"""
# load the right message language
_ = gettext_set_language(ln)
if body_css_classes is None:
body_css_classes = []
body_css_classes.append(navmenuid)
+ uri = req.unparsed_uri
+ headerLinkbackTrackbackLink = ''
+ if CFG_WEBLINKBACK_TRACKBACK_ENABLED:
+ from invenio.weblinkback_templates import get_trackback_auto_discovery_tag
+ # Embed a link in the header to subscribe trackbacks
+ # TODO: This hack must be replaced with the introduction of the new web framework
+ recordIndexInURI = uri.find('/' + CFG_SITE_RECORD + '/')
+ # substring found --> offer trackback link in header
+ if recordIndexInURI != -1:
+ recid = uri[recordIndexInURI:len(uri)].split('/')[2].split("?")[0] #recid might end with ? for journal records
+ headerLinkbackTrackbackLink = get_trackback_auto_discovery_tag(recid)
+
if CFG_WEBSTYLE_INSPECT_TEMPLATES:
inspect_templates_message = '''
CFG_WEBSTYLE_INSPECT_TEMPLATES debugging mode is enabled. Please
hover your mouse pointer over any region on the page to see which
template function generated it.
' % \
{'personalize_selected': navmenuid.startswith('admin') and "selected" or "",
'adminactivities': adminactivities_menu}) or '
',
'pageheaderadd' : pageheaderadd,
'body_css_classes' : body_css_classes and ' class="%s"' % ' '.join(body_css_classes) or '',
'search_selected': navmenuid == 'search' and "selected" or "",
'submit_selected': navmenuid == 'submit' and "selected" or "",
'personalize_selected': navmenuid.startswith('your') and "selected" or "",
'help_selected': navmenuid == 'help' and "selected" or "",
'msg_search' : _("Search"),
'msg_submit' : _("Submit"),
'msg_personalize' : _("Personalize"),
'msg_help' : _("Help"),
'unAPIurl' : cgi.escape('%s/unapi' % CFG_SITE_URL),
'linkbackTrackbackLink': headerLinkbackTrackbackLink,
'inspect_templates_message' : inspect_templates_message
}
return out
def tmpl_canonical_and_alternate_urls(self, url):
"""
Return the snippet of HTML to be put within the HTML HEAD tag in order
to declare the canonical and language alternate URLs of a page.
"""
canonical_url, alternate_urls = get_canonical_and_alternates_urls(url)
out = """ \n""" % cgi.escape(canonical_url, True)
for ln, alternate_url in alternate_urls.iteritems():
ln = ln.replace('_', '-') ## zh_CN -> zh-CN
out += """ \n""" % (ln, cgi.escape(alternate_url, True))
return out
def tmpl_pagefooter(self, req=None, ln=CFG_SITE_LANG, lastupdated=None,
pagefooteradd=""):
"""Creates a page footer
Parameters:
- 'ln' *string* - The language to display
- 'lastupdated' *string* - when the page was last updated
- 'pagefooteradd' *string* - additional page footer HTML code
Output:
- HTML code of the page headers
"""
# load the right message language
_ = gettext_set_language(ln)
if lastupdated and lastupdated != '$Date$':
if lastupdated.startswith("$Date: ") or \
lastupdated.startswith("$Id: "):
lastupdated = convert_datestruct_to_dategui(\
convert_datecvs_to_datestruct(lastupdated),
ln=ln)
msg_lastupdated = _("Last updated") + ": " + lastupdated
else:
msg_lastupdated = ""
out = """
""" % {
'siteurl': CFG_SITE_URL,
'sitesecureurl': CFG_SITE_SECURE_URL,
'ln': ln,
'langlink': '?ln=' + ln,
'sitename': CFG_SITE_NAME_INTL.get(ln, CFG_SITE_NAME),
'sitesupportemail': CFG_SITE_SUPPORT_EMAIL,
'msg_search': _("Search"),
'msg_submit': _("Submit"),
'msg_personalize': _("Personalize"),
'msg_help': _("Help"),
'msg_poweredby': _("Powered by"),
'msg_maintainedby': _("Maintained by"),
'msg_lastupdated': msg_lastupdated,
'languagebox': self.tmpl_language_selection_box(req, ln),
'version': CFG_VERSION,
'pagefooteradd': pagefooteradd,
}
return out
def tmpl_language_selection_box(self, req, language=CFG_SITE_LANG):
"""Take URLARGS and LANGUAGE and return textual language
selection box for the given page.
Parameters:
- 'req' - The mod_python request object
- 'language' *string* - The selected language
"""
# load the right message language
_ = gettext_set_language(language)
# Work on a copy in order not to bork the arguments of the caller
argd = {}
if req and req.args:
argd.update(cgi.parse_qs(req.args))
parts = []
for (lang, lang_namelong) in language_list_long():
if lang == language:
parts.append('%s' % lang_namelong)
else:
# Update the 'ln' argument in the initial request
argd['ln'] = lang
if req and req.uri:
args = urllib.quote(req.uri, '/:?') + make_canonical_urlargd(argd, {})
else:
args = ""
parts.append(create_html_link(args,
{}, lang_namelong,
{'class': "langinfo"}))
if len(parts) > 1:
return _("This site is also available in the following languages:") + \
" " + ' '.join(parts)
else:
## There is only one (or zero?) languages configured,
## so there so need to display language alternatives.
return ""
def tmpl_error_box(self, ln, title, verbose, req, errors):
"""Produces an error box.
Parameters:
- 'title' *string* - The title of the error box
- 'ln' *string* - The selected language
- 'verbose' *bool* - If lots of information should be displayed
- 'req' *object* - the request object
- 'errors' list of tuples (error_code, error_message)
"""
# load the right message language
_ = gettext_set_language(ln)
info_not_available = _("N/A")
if title is None:
if errors:
title = _("Error") + ': %s' % errors[0][1]
else:
title = _("Internal Error")
browser_s = _("Browser")
if req:
try:
if req.headers_in.has_key('User-Agent'):
browser_s += ': ' + req.headers_in['User-Agent']
else:
browser_s += ': ' + info_not_available
host_s = req.hostname
page_s = req.unparsed_uri
client_s = req.remote_ip
except: # FIXME: bad except
browser_s += ': ' + info_not_available
host_s = page_s = client_s = info_not_available
else:
browser_s += ': ' + info_not_available
host_s = page_s = client_s = info_not_available
error_s = ''
sys_error_s = ''
traceback_s = ''
if verbose >= 1:
if sys.exc_info()[0]:
sys_error_s = '\n' + _("System Error") + ': %s %s\n' % \
(sys.exc_info()[0], sys.exc_info()[1])
if errors:
errs = ''
for error_tuple in errors:
try:
errs += "%s%s : %s\n " % (' '*6, error_tuple[0],
error_tuple[1])
except:
errs += "%s%s\n" % (' '*6, error_tuple)
errs = errs[6:-2] # get rid of trainling ','
error_s = _("Error") + ': %s")' % errs + "\n"
else:
error_s = _("Error") + ': ' + info_not_available
if verbose >= 9:
traceback_s = '\n' + _("Traceback") + ': \n%s' % \
string.join(traceback.format_tb(sys.exc_info()[2]),
"\n")
out = """
""" % {
'title' : cgi.escape(title).replace('"', '"'),
'time_label': _("Time"),
'client_label': _("Client"),
'send_error_label': \
_("Please send an error report to the administrator."),
'send_label': _("Send error report"),
'sys1' : cgi.escape(str((sys.exc_info()[0] or ''))).replace('"', '"'),
'sys2' : cgi.escape(str((sys.exc_info()[1] or ''))).replace('"', '"'),
'contact' : \
_("Please contact %s quoting the following information:") % \
('' + \
CFG_SITE_SUPPORT_EMAIL + ''),
'host' : cgi.escape(host_s),
'page' : cgi.escape(page_s),
'time' : time.strftime("%d/%b/%Y:%H:%M:%S %z"),
'browser' : cgi.escape(browser_s).replace('"', '"'),
'client' : cgi.escape(client_s).replace('"', '"'),
'error' : cgi.escape(error_s).replace('"', '"'),
'traceback' : cgi.escape(traceback_s).replace('"', '"'),
'sys_error' : cgi.escape(sys_error_s).replace('"', '"'),
'siteurl' : CFG_SITE_URL,
'referer' : page_s!=info_not_available and \
("http://" + host_s + page_s) or \
info_not_available
}
return out
def detailed_record_container_top(self, recid, tabs, ln=CFG_SITE_LANG,
show_similar_rec_p=True,
creationdate=None,
modificationdate=None, show_short_rec_p=True,
citationnum=-1, referencenum=-1, discussionnum=-1):
"""Prints the box displayed in detailed records pages, with tabs at the top.
Returns content as it is if the number of tabs for this record
is smaller than 2
Parameters:
@param recid: int - the id of the displayed record
@param tabs: ** - the tabs displayed at the top of the box.
@param ln: *string* - the language of the page in which the box is displayed
@param show_similar_rec_p: *bool* print 'similar records' link in the box
@param creationdate: *string* - the creation date of the displayed record
@param modificationdate: *string* - the last modification date of the displayed record
@param show_short_rec_p: *boolean* - prints a very short version of the record as reminder.
@param citationnum: show (this) number of citations in the citations tab
@param referencenum: show (this) number of references in the references tab
@param discussionnum: show (this) number of comments/reviews in the discussion tab
"""
from invenio.search_engine import record_public_p
# load the right message language
_ = gettext_set_language(ln)
# Prepare restriction flag
restriction_flag = ''
if not record_public_p(recid):
restriction_flag = '
%s
' % _("Restricted")
# If no tabs, returns nothing (excepted if restricted)
if len(tabs) <= 1:
return restriction_flag
# Build the tabs at the top of the page
out_tabs = ''
if len(tabs) > 1:
first_tab = True
for (label, url, selected, enabled) in tabs:
addnum = ""
if (citationnum > -1) and url.count("/citation") == 1:
addnum = "(" + str(citationnum) + ")"
if (referencenum > -1) and url.count("/references") == 1:
addnum = "(" + str(referencenum) + ")"
if (discussionnum > -1) and url.count("/comments") == 1:
addnum = "(" + str(discussionnum) + ")"
css_class = []
if selected:
css_class.append('on')
if first_tab:
css_class.append('first')
first_tab = False
if not enabled:
css_class.append('disabled')
css_class = ' class="%s"' % ' '.join(css_class)
if not enabled:
out_tabs += '
''' % out_tabs
# Add the clip icon and the brief record reminder if necessary
record_brief = ''
if show_short_rec_p:
record_brief = format_record(recID=recid, of='hs', ln=ln)
record_brief = '''
%(record_brief)s
''' % {'record_brief': record_brief}
# Print the content
out = """
%(tabs)s
%(record_brief)s
""" % {'tabs':out_tabs,
'record_brief':record_brief}
out = restriction_flag + out
return out
def detailed_record_container_bottom(self, recid, tabs, ln=CFG_SITE_LANG,
show_similar_rec_p=True,
creationdate=None,
modificationdate=None, show_short_rec_p=True):
"""Prints the box displayed in detailed records pages, with tabs at the top.
Returns content as it is if the number of tabs for this record
is smaller than 2
Parameters:
- recid *int* - the id of the displayed record
- tabs ** - the tabs displayed at the top of the box.
- ln *string* - the language of the page in which the box is displayed
- show_similar_rec_p *bool* print 'similar records' link in the box
- creationdate *string* - the creation date of the displayed record
- modificationdate *string* - the last modification date of the displayed record
- show_short_rec_p *boolean* - prints a very short version of the record as reminder.
"""
# If no tabs, returns nothing
if len(tabs) <= 1:
return ''
# load the right message language
_ = gettext_set_language(ln)
similar = ""
if show_similar_rec_p and not CFG_INSPIRE_SITE:
similar = create_html_link(
websearch_templates.build_search_url(p='recid:%d' % \
recid,
rm='wrd',
ln=ln),
{}, _("Similar records"),{'class': "moreinfo"})
out = """
%(dates)s
%(similar)s
""" % {'similar' : similar,
'dates' : creationdate and '
%(dates)s
' % {
'dates': _("Record created %(x_date_creation)s, last modified %(x_date_modification)s") % \
{'x_date_creation': creationdate,
'x_date_modification': modificationdate},
} or ''
}
return out
def detailed_record_mini_panel(self, recid, ln=CFG_SITE_LANG,
format='hd',
files='',
reviews='',
actions=''):
"""Displays the actions dock at the bottom of the detailed record
pages.
Parameters:
- recid *int* - the id of the displayed record
- ln *string* - interface language code
- format *string* - the format used to display the record
- files *string* - the small panel representing the attached files
- reviews *string* - the small panel representing the reviews
- actions *string* - the small panel representing the possible user's action
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
%(files)s
%(reviews)s
%(actions)s
""" % {
'siteurl': CFG_SITE_URL,
'ln':ln,
'recid':recid,
'files': files,
'reviews':reviews,
'actions': actions,
}
return out
def tmpl_error_page(self, ln=CFG_SITE_LANG, status="", admin_was_alerted=True):
"""
Display an error page.
- status *string* - the HTTP status.
"""
_ = gettext_set_language(ln)
out = """
%(message)s
%(alerted)s
%(doubts)s
""" % {
'status' : status,
'message' : _("The server encountered an error while dealing with your request."),
'alerted' : admin_was_alerted and _("The system administrators have been alerted.") or '',
'doubts' : _("In case of doubt, please contact %(x_admin_email)s.") % {'x_admin_email' : '%(admin)s' % {'admin' : CFG_SITE_SUPPORT_EMAIL}}
}
return out
def tmpl_warning_message(self, ln, msg):
"""
Produces a warning message for the specified text
Parameters:
- 'ln' *string* - The language to display the interface in
- 'msg' *string* - The message to display
"""
# load the right message language
_ = gettext_set_language(ln)
return """
%s
""" % msg
def tmpl_write_warning(self, msg, type='', prologue='', epilogue=''):
"""
Returns formatted warning message.
Parameters:
- 'msg' *string* - The message string
- 'type' *string* - the warning type
- 'prologue' *string* - HTML code to display before the warning
- 'epilogue' *string* - HTML code to display after the warning
"""
out = '\n%s' % (prologue)
if type:
out += '%s: ' % type
out += '%s%s' % (msg, epilogue)
return out