Commit 72bd01db authored by Merret Buurman's avatar Merret Buurman
Browse files

Splitted logic for cmip6 into several modules in cmip6 package.

parent 8738fe23
from django.template import loader
import requests
import json
import xml.etree.ElementTree as ET
def get_html_string(request, prefix, suffix):
handle_values, json_record = _get_handle_values(prefix+'/'+suffix)
agg_level = _extract_agg_level(handle_values)
context = _get_handle_info_depending_on_aggregation_level(agg_level, handle_values, json_record)
template = _get_template_depending_on_aggregation_level(agg_level)
return template.render(context, request)
def _get_template_depending_on_aggregation_level(aggregation_level):
if aggregation_level.lower() == 'file':
return loader.get_template('landingpage/cmip6_file.html')
elif aggregation_level.lower() == 'dataset':
return loader.get_template('landingpage/cmip6_dataset.html')
else:
return loader.get_template('landingpage/cmip6_fallback.html')
def _get_handle_values(handle):
resp = requests.get('https://hdl.handle.net/api/handles/'+handle)
# TODO Put URL in config
# TODO ONE DAY - MAKE THIS AJAX???
# StackOverflow
# http://stackoverflow.com/questions/7699796/how-do-you-get-django-to-make-a-restful-call
# My opinion is to get the client to make the requests where possible; making your webserver block for an external call isn't very scalable or nice in general. However, be aware that AJAX requests must be made to the same domain (you can't do cross domain AJAX requests without using iframes, jsonp, or other trickery).
# TODO USE PYHANDLE HERE TO CATCH ERRORS
entries = json.loads(resp.content)['values']
values_dict = dict(
handle=handle
)
for entry in entries:
key = str(entry['type'])
val = str(entry['data']['value'])
values_dict[key] = val
return values_dict, entries
def _get_handle_info_depending_on_aggregation_level(agg_level, values, json_record):
if agg_level.lower() == 'file':
return _get_handle_info_for_file(values, json_record)
elif agg_level.lower() == 'dataset':
return _get_handle_info_for_dataset(values, json_record)
else:
return _get_dict_generic(values, json_record)
def _extract_agg_level(values_dict):
return values_dict['AGGREGATION_LEVEL']
def _get_handle_info_for_file(values, json_record):
context = {}
if 'FILENAME' in values:
context['file_name'] = values['FILENAME']
if 'FILESIZE' in values:
context['file_size'] = values['FILESIZE']
if 'CHECKSUM' in values:
context['checksum'] = values['CHECKSUM']
if 'CHECKSUM_METHOD' in values:
context['checksum_method'] = values['CHECKSUM_METHOD']
if 'URL_ORIGINAL_DATA' in values:
field_string = values['URL_ORIGINAL_DATA']
list_of_originals = _extract_url_info_from_field(field_string)
context['urls_original'] = list_of_originals
if 'URL_REPLICAS' in values:
context['urls_replicas'] = values['URL_REPLICAS']
if 'IS_PART_OF' in values or 'PARENT' in values: # TODO remove 'PARENT'
if 'IS_PART_OF' in values:
parent_list = values['IS_PART_OF'].split(';')
context['parents_list'] = parent_list
infodict, any_replaced = _get_parent_info(parent_list)
context['parents_info'] = infodict
context['any_parent_replaced'] = any_replaced
elif 'PARENT' in values:
parent_list = values['PARENT'].split(';')
context['parents_list'] = parent_list
infodict, any_replaced = _get_parent_info(parent_list)
context['parents_info'] = infodict
context['any_parent_replaced'] = any_replaced
context['content'] = json_record
context['values'] = values
context['handle'] = values['handle']
# TODO add replicas
return context
def _extract_url_info_from_field(field_string):
field_xml = ET.fromstring(field_string)
list_of_originals = []
temp_url_list = []
locations = field_xml.findall('location')
for location in locations:
url = location.get('href')
if url not in temp_url_list:
temp_url_list.append(url)
list_of_originals.append(dict(
host=location.get('host'),
url=url
))
return list_of_originals
def _get_handle_info_for_dataset(values):
return {}
def _get_dict_generic(values):
return {}
def _get_parent_info(list_of_parent_handles):
list_of_parent_info = []
any_replaced = False
for handle in list_of_parent_handles:
# Gather info:
handle_values, temp = _get_handle_values(handle)
aggregation_level = handle_values['AGGREGATION_LEVEL'].lower()
drs_id = handle_values['DRS_ID']
vers_num = handle_values['VERSION_NUMBER']
replaced = False
if 'REPLACED_BY' in handle_values:
newer = handle_values['REPLACED_BY']
any_replaced = True
if not newer == handle:
replaced = True
# Assemble info:
info = dict(
handle = handle,
level = aggregation_level,
drs = drs_id,
version = vers_num,
replaced = replaced
)
list_of_parent_info.append(info)
return list_of_parent_info, any_replaced
from django.template import loader
import requests
import json
import xml.etree.ElementTree as ET
import filelevel
from landingpage.handle import retrieval, cmip6parser
def get_html_string(request, prefix, suffix):
json_record = retrieval.get_handle_record_json(prefix+'/'+suffix)
agg_level = cmip6parser.get_aggregation_level(json_record)
context = _get_context_for_aggregation_level(agg_level, json_record)
template = _get_template_for_aggregation_level(agg_level)
return template.render(context, request)
def _get_template_for_aggregation_level(aggregation_level):
if aggregation_level.lower() == 'file':
return filelevel.get_template()
elif aggregation_level.lower() == 'dataset':
return loader.get_template('landingpage/cmip6_dataset.html') # TODO
else:
return loader.get_template('landingpage/cmip6_fallback.html') # TODO
def _get_context_for_aggregation_level(agg_level, json_record):
if agg_level.lower() == 'file':
return filelevel.get_context(json_record)
elif agg_level.lower() == 'dataset':
return _get_handle_info_for_dataset(json_record) # TODO
else:
return _get_dict_generic(json_record) # TODO
def _get_handle_info_for_dataset(values):
return {}
def _get_dict_generic(values):
return {}
from django.template import loader
import xml.etree.ElementTree as ET
import landingpage.handle.cmip6parser as parser
#
# API of this module:
#
def get_context(json_record):
return _get_context(json_record)
def get_template():
return _get_template()
def _get_template():
return loader.get_template('landingpage/cmip6_file.html')
#
# Logic of this module:
#
def _get_context(json_record):
context = {}
context['content'] = json_record
context['handle'] = json_record['handle']
context['values'] = parser.get_all_entries_as_dict(json_record)
# file name
val = parser.get_filename_from_record(json_record)
if val is not None:
context['filename'] = val
# file size
val = parser.get_filesize_from_record(json_record)
if val is not None:
context['filesize'] = val
# checksum
val = parser.get_checksum_from_record(json_record)
if val is not None:
context['checksum'] = val
# checksum method
val = parser.get_checksum_method_from_record(json_record)
if val is not None:
context['checksum_method'] = val
# file size
val = parser.get_filesize_from_record(json_record)
if val is not None:
context['filesize'] = val
# URLS original
val = parser.get_urls_original_from_record(json_record)
if val is not None:
context['urls_original'] = val
# URLS replicas
val = parser.get_urls_replicas_from_record(json_record)
if val is not None:
context['urls_replicas'] = val
# Aggregation (formerly known as parent)
val1 = parser.get_list_of_aggregation_handles_from_record(json_record)
if val1 is not None:
context['list_of_aggregation_handles'] = val1
val2,val3 = parser.get_list_of_aggregation_records_from_record(val1)
if val2 is not None:
context['list_of_aggregation_records'] = val2
context['any_parent_replaced'] = val3
return context
<html>
<link rel="stylesheet" href="/static/styles.css" type="text/css">
<head>
<title>CMIP6 Landing Page</title>
</head>
<body>
<div class="header">
<div class="container2">
<h1 class="header-heading">CMIP6 Handle! </h1>
</div>
</div>
<p>Yo!</p>
{% if handle_list %}
<ul>
{% for handle in handle_list %}
<li><a href="http://hdl.handle.net/{{ handle }}/">{{ handle }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No handles are available.</p>
{% endif %}
</body>
</html>
\ No newline at end of file
......@@ -2,28 +2,72 @@
{% block content %}
<!--
The context object needs the following objects:
Simple values:
* filename
* handle [*]
* filesize
* checksum
* checksum_method
* any_parent_replaced (Boolean): To indicate if we have to insert the note about replaced datasets
Complex objects:
* urls_original: List of dicts. Every dict needs:
* host [*]
* url [*]
* urls_replicas: List of dicts. Every dict needs:
* host [*]
* url [*]
* list_of_aggregation_handles: List of strings (handles).
These handles can be retrieved from the file handle record, but it is very little information.
The user needs to click on them to know what they are, if they are up-to-date, etc.
Alternative: list_of_aggregation_records
* list_of_aggregation_records: List of dicts.
This contains more info, which is extracted from the records of the aggregation handles, so more
calls to retrieve handle records are needed. Maybe one day this could be done on user's request only.
Every dict needs:
* level (e.g. "dataset") [*]
* version [*]
* drs [*]
* handle [*]
* replaced (True or False) [*]
[*] I do not check the existence of these, so if they don't exist, the page may break.
-->
<div class="section">
<h1><em>{{file_name}}</em> (file)</h1>
<!--p id="intro">This is the information page of the persistent identifier of the CMIP6 file {{file_name}}.</p-->
{% if filename %}
<h1><em>{{filename}}</em> (file)</h1>
{% else %}
<h1>File <em>(filename unknown)</em></h1>
{% endif %}
</div>
<div class="section">
<h2>General information</h2>
<table>
{% if file_name %}
{% if filename %}
<tr>
<td id="leftcol">File name</td>
<td>{{file_name}}</td>
<td>{{filename}}</td>
</tr>
{% endif %}
<tr>
<td id="leftcol">Persistent identifier</td>
<td><a href="http://hdl.handle.net/{{handle}}">hdl:{{handle}}</a></td>
</tr>
{% if file_size %}
{% if filesize %}
<tr>
<td id="leftcol">File size</td>
<td>{{file_size}}</td>
<td>{{filesize}}</td>
</tr>
{% endif %}
{% if checksum and not checksum_method%}
......@@ -41,6 +85,7 @@
</table>
</div>
<div class="section">
<h2>Data access</h2>
......@@ -48,7 +93,7 @@
<table>
{% if urls_original %}
{% for entry in urls_original %}
<tr>
<tr>
<td id="leftcol">Hosted by {{entry.host}}:</td>
<td><a href="{{entry.url}}">{{entry.url}}</a></td>
</tr>
......@@ -56,7 +101,7 @@
{% endif %}
{% if urls_replicas %}
{% for entry in urls_replicas %}
<tr>
<tr>
<td id="leftcol">Mirrored at {{entry.host}}:</td>
<td><a href="{{entry.url}}">{{entry.url}}</a> (Replica)</td>
</tr>
......@@ -64,17 +109,15 @@
{% endif %}
</table>
{% endif %}
</div>
<div class="section">
<h2>The file is part of the following aggregation(s)</em></h2>
{% if parents_info %}
{% if list_of_aggregation_records %}
<table>
{% for item in parents_info %}
{% for item in list_of_aggregation_records %}
<tr>
<td id="leftcol">{{item.level}}</td>
<td>
......@@ -95,9 +138,9 @@
{% endif %}
</table>
{% else %}{% if parents_list %}
{% else %}{% if list_of_aggregation_handles %}
<table>
{% for handle in parents_list %}
{% for handle in list_of_aggregation_handles %}
<tr><td><a href="http://hdl.handle.net/{{ handle }}/">{{ handle }}</a></td></tr>
{% endfor %}
</table>
......
from django.shortcuts import render
from django.http import HttpResponse
from pages import errorpages, default, cmip6
import pages.cmip6 as cmip6
from pages import errorpages, default
from pages.cmip6 import entrypoint
def prefix_only(request, prefix):
string = errorpages.only_prefix(prefix)
......@@ -15,7 +17,7 @@ def prefix_only_cmip6(request, prefix):
return HttpResponse(string)
def entire_handle_cmip6(request, prefix, suffix):
string = cmip6.get_html_string(request, prefix, suffix)
string = cmip6.entrypoint.get_html_string(request, prefix, suffix)
return HttpResponse(string)
def no_handle(request):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment