Skip to content

Commit

Permalink
Merge e860135 into 6370063
Browse files Browse the repository at this point in the history
  • Loading branch information
karenc committed Apr 11, 2016
2 parents 6370063 + e860135 commit 7e4961e
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 15 deletions.
15 changes: 13 additions & 2 deletions cnxarchive/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def _read_sql_file(name):
'get-in-book-search': _read_sql_file('get-in-book-search'),
'get-in-book-search-full-page': _read_sql_file(
'get-in-book-search-full-page'),
'get-collated-content': _read_sql_file('get-collated-content'),
}


Expand Down Expand Up @@ -227,11 +228,11 @@ def get_module_ident_from_ident_hash(ident_hash, cursor):
return module_ident


def get_tree(ident_hash, cursor):
def get_tree(ident_hash, cursor, as_collated=False):
"""Return a JSON representation of the binder tree for ``ident_hash``."""
uuid, version = split_ident_hash(ident_hash)
cursor.execute(SQL['get-tree-by-uuid-n-version'],
(uuid, version,))
(uuid, version, as_collated,))
try:
tree = cursor.fetchone()[0]
except TypeError: # NoneType
Expand All @@ -243,6 +244,16 @@ def get_tree(ident_hash, cursor):
return tree


def get_collated_content(ident_hash, context_ident_hash, cursor):
"""Return collated content for ``ident_hash``."""
cursor.execute(SQL['get-collated-content'],
(ident_hash, context_ident_hash,))
try:
return cursor.fetchone()[0]
except TypeError: # NoneType
return


def get_module_uuid(plpy, moduleid):
"""Retrieve page uuid from legacy moduleid."""
plan = plpy.prepare("SELECT uuid FROM modules WHERE moduleid = $1;",
Expand Down
15 changes: 15 additions & 0 deletions cnxarchive/sql/get-collated-content.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- ###
-- Copyright (c) 2016, Rice University
-- This software is subject to the provisions of the GNU Affero General
-- Public License version 3 (AGPLv3).
-- See LICENCE.txt for details.
-- ###

-- arguments[positional]: ident_hash:string; context_ident_hash:string
SELECT f.file
FROM files AS f
LEFT JOIN collated_file_associations cfa ON cfa.fileid = f.fileid
LEFT JOIN modules m ON m.module_ident = cfa.item
LEFT JOIN modules context ON context.module_ident = cfa.context
WHERE m.uuid || '@' || concat_ws('.', m.major_version, m.minor_version) = %s AND
context.uuid || '@' || concat_ws('.', context.major_version, context.minor_version) = %s
4 changes: 2 additions & 2 deletions cnxarchive/sql/get-tree-by-uuid-n-version.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
-- See LICENCE.txt for details.
-- ###

-- arguments[positional]: id:string; version:string;
SELECT tree_to_json(%s, %s, FALSE)::json;
-- arguments[positional]: id:string; version:string; as_collated:boolean
SELECT tree_to_json(%s, %s, %s)::json;
1 change: 1 addition & 0 deletions cnxarchive/sql/search/query.sql
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ FROM
derived_weighted_query_results AS wqr
WHERE
wqr.module_ident = lm.module_ident
AND lm.portal_type != 'CompositeModule'
{filters}
{groupby}
ORDER BY {sorts}
Expand Down
27 changes: 23 additions & 4 deletions cnxarchive/tests/data/data.sql

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion cnxarchive/tests/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,6 @@ def test_module(self, cursor):

cursor.execute('SELECT COUNT(*) FROM modules')
old_n_modules = cursor.fetchone()[0]
self.assertEqual(old_n_modules, 19)

# Insert a new version of an existing module
cursor.execute('''\
Expand Down
108 changes: 104 additions & 4 deletions cnxarchive/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,12 +494,46 @@ def test_derived_collection(self):
self.assertEqual(content['parent'][key],
COLLECTION_DERIVED_METADATA['parent'][key])

def test_content_collated_collection(self):
uuid = 'e79ffde3-7fb4-4af3-9ec8-df648b391597'
version = '6.1'

# Build the request environment.
self.request.matchdict = {'ident_hash': '{}@{}'.format(uuid, version)}
self.request.matched_route = mock.Mock()
self.request.matched_route.name = 'content'

# Call the view.
from ..views import get_content
content = get_content(self.request).json_body

# Check the tree.
self.assertEqual({
u'id': u'{}@{}'.format(uuid, version),
u'shortId': u'55_943-0@6.1',
u'title': u'College Physics',
u'contents': [
{u'id': u'209deb1f-1a46-4369-9e0d-18674cf58a3e@7',
u'shortId': u'IJ3rHxpG@7',
u'title': u'Preface'},
{u'id': u'174c4069-2743-42e9-adfe-4c7084f81fc5@1',
u'shortId': u'F0xAaSdD@1',
u'title': u'Collated page'},
],
}, content['tree'])

@testing.db_connect
def _create_empty_subcollections(self, cursor):
cursor.execute("INSERT INTO trees VALUES (91, 53, NULL, 'Empty Subcollections', 1)")
cursor.execute("INSERT INTO trees VALUES (92, 91, NULL, 'empty 1', 1)")
cursor.execute("INSERT INTO trees VALUES (93, 91, NULL, 'empty 2', 2)")
cursor.execute("INSERT INTO trees VALUES (94, 53, NULL, 'Empty Subcollection', 3)")
cursor.execute("""\
INSERT INTO trees (nodeid, parent_id, title, childorder, is_collated)
VALUES (9100, 91, 'Empty Subcollections', 1, true);
INSERT INTO trees (nodeid, parent_id, title, childorder, is_collated)
VALUES (9200, 9100, 'empty 1', 1, true);
INSERT INTO trees (nodeid, parent_id, title, childorder, is_collated)
VALUES (9300, 9100, 'empty 2', 2, true);
INSERT INTO trees (nodeid, parent_id, title, childorder, is_collated)
VALUES (9400, 91, 'Empty Subcollection', 4, true);
""")

def test_empty_subcollection_content(self):
self._create_empty_subcollections()
Expand Down Expand Up @@ -551,6 +585,11 @@ def test_empty_subcollection_content(self):
u'shortId': u'IJ3rHxpG@7',
u'title': u'Preface',
},
{
u'id': u'174c4069-2743-42e9-adfe-4c7084f81fc5@1',
u'shortId': u'F0xAaSdD@1',
u'title': u'Collated page',
},
{
u'id': u'subcol',
u'shortId': u'subcol',
Expand Down Expand Up @@ -616,6 +655,25 @@ def test_module_content(self):
# Check the content is the html file.
self.assertTrue(content_text.find('<html') >= 0)

def test_content_composite_module(self):
# Test for retrieving a a composite module.
uuid = '174c4069-2743-42e9-adfe-4c7084f81fc5'
version = '1'

# Build the request environment.
self.request.matchdict = {'ident_hash': '{}@{}'.format(uuid, version)}
self.request.matched_route = mock.Mock()
self.request.matched_route.name = 'content'

from ..views import get_content

content = get_content(self.request).json_body

# Check the content.
self.assertEqual(
'<html><body>test collated content</body></html>',
content['content'])

def test_content_without_version(self):
uuid = 'ae3e18de-638d-4738-b804-dc69cd4db3a3'

Expand Down Expand Up @@ -696,6 +754,48 @@ def test_content_not_found_w_invalid_uuid(self):
self.assertRaises(IdentHashShortId, get_content,
self.request)

def test_content_collated_page_inside_book(self):
book_uuid = 'e79ffde3-7fb4-4af3-9ec8-df648b391597'
book_version = '6.1'
page_uuid = '209deb1f-1a46-4369-9e0d-18674cf58a3e'
page_version = '7'

# Build the request.
self.request.matchdict = {
'ident_hash': '{}@{}'.format(book_uuid, book_version),
'page_ident_hash': '{}@{}'.format(page_uuid, page_version),
'separator': ':',
}
self.request.matched_route = mock.Mock()
self.request.matched_route.name = 'content'

# Call the view.
from ..views import get_content
content = get_content(self.request).json_body

self.assertEqual(
'<html><body>Page content after collation</body></html>\n',
content['content'])

def test_content_uncollated_page(self):
page_uuid = '209deb1f-1a46-4369-9e0d-18674cf58a3e'
page_version = '7'

# Build the request.
self.request.matchdict = {
'ident_hash': '{}@{}'.format(page_uuid, page_version),
}
self.request.matched_route = mock.Mock()
self.request.matched_route.name = 'content'

# Call the view.
from ..views import get_content
content = get_content(self.request).json_body

self.assertNotEqual(
'<html><body>Page content after collation</body></html>\n',
content['content'])

def test_content_page_inside_book_version_mismatch(self):
book_uuid = 'e79ffde3-7fb4-4af3-9ec8-df648b391597'
book_version = '7.1'
Expand Down
1 change: 1 addition & 0 deletions cnxarchive/utils/mimetype.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
MIMETYPES = (MODULE_MIMETYPE, COLLECTION_MIMETYPE, FOLDER_MIMETYPE,)
PORTALTYPE_TO_MIMETYPE_MAPPING = {
'Module': MODULE_MIMETYPE,
'CompositeModule': MODULE_MIMETYPE,
'Collection': COLLECTION_MIMETYPE,
}

Expand Down
16 changes: 14 additions & 2 deletions cnxarchive/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from . import cache
# FIXME double import
from . import database
from .database import SQL, get_tree
from .database import SQL, get_tree, get_collated_content
from .search import (
DEFAULT_PER_PAGE, QUERY_TYPES, DEFAULT_QUERY_TYPE,
Query,
Expand Down Expand Up @@ -299,13 +299,24 @@ def _get_content_json(ident_hash=None):
result = get_content_metadata(id, version, cursor)
if result['mediaType'] == COLLECTION_MIMETYPE:
# Grab the collection tree.
result['tree'] = get_tree(ident_hash, cursor)
result['tree'] = get_tree(ident_hash, cursor, as_collated=True)
if not result['tree']:
# If collated tree is not available, get the uncollated
# tree.
result['tree'] = get_tree(ident_hash, cursor)

if page_ident_hash:
for id_ in flatten_tree_to_ident_hashes(result['tree']):
id, version = split_ident_hash(id_)
if id == p_id and (
version == p_version or not p_version):
content = get_collated_content(
id_, ident_hash, cursor)
if content:
result = get_content_metadata(
p_id, p_version, cursor)
result['content'] = content[:]
return result
raise httpexceptions.HTTPFound(request.route_path(
request.matched_route.name,
ident_hash=join_ident_hash(id, version)))
Expand Down Expand Up @@ -886,6 +897,7 @@ def sitemap(request):
'[^0-9a-z]+', ' ', 'g')), ' +', '-', 'g'),
revised
FROM latest_modules
WHERE portal_type != 'CompositeModule'
ORDER BY revised DESC LIMIT 50000""")
res = cursor.fetchall()
for ident_hash, page_name, revised in res:
Expand Down

0 comments on commit 7e4961e

Please sign in to comment.