Select a date to view details of that day's trading (if any).
# This notebook is designed to run in Voila as an app (with the code hidden).
# To launch this notebook in Voila, just select 'View > Open with Voila in New Browser Tab'
# Your browser might ask for permission to open the new tab as a popup.
import pandas as pd
import ipywidgets as widgets
import arrow
import datetime
from pathlib import Path
from IPython.display import display, HTML, Image
from urllib.parse import quote_plus, parse_qs
import json
import os
from collections import Counter
from page_data_master import *
SESSIONS = {
'M': 'Morning',
'N': 'Noon',
'A': 'Afternoon',
'U': 'Unknown'
}
CLOUDSTOR_URL = 'https://cloudstor.aarnet.edu.au/plus/s/i02k4gxeEpMAUkm'
def get_pages(vol_num, page_num):
for key, pages in pages_per_vol.items():
vols = key.split('_')
vols = [int(y) for y in vols]
if len(vols) == 2:
vols = list(range(vols[0], vols[1] + 1))
if vol_num in vols:
for p_key, p_pages in pages.items():
p_range = p_key.split('_')
if p_range[1] == '*':
if page_num >= int(p_range[0]):
return p_pages
else:
if page_num >= int(p_range[0]) and page_num <= int(p_range[1]):
return p_pages
# Get the list of dates
df_dates = pd.read_csv('complete_date_list.csv', parse_dates=['date'])
# Get the list of pages
df_pages = pd.read_csv('complete_page_list.csv', parse_dates=['date'])
# Merge dates and pages on the date field
df = pd.merge(df_dates, df_pages, how='left', on='date').sort_values(by=['date', 'page_num'])
def highlight_missing(row):
'''
Highlight missing pages.
'''
if row['pages expected'] == row['pages found']:
return ['', '']
else:
return ['','background-color: yellow']
def find_pages():
results.clear_output()
images = []
date = arrow.get(date_picker.value)
with results:
display(HTML(f'<h2>{date.format("D MMMM YYYY")}</h2>'))
rows = df.loc[df['date'] == pd.Timestamp(date_picker.value)]
first_page = rows.iloc[0]['page_num']
vol_num = rows.iloc[0]['vol_num']
num_pages = rows.iloc[0]['pages']
if date.weekday() < 6 and pd.notnull(vol_num):
# Get the expected number of pages
expected = get_pages(int(vol_num), int(first_page))
if date.weekday() < 5:
expected_pages = expected['weekday']
elif date.weekday() == 5:
expected_pages = expected['saturday']
expected_num_pages = expected_pages[0]
display(HTML(f'<p><b>Number of pages</b>: {expected_num_pages} expected / {int(num_pages)} found</p>'))
# Display a breakdown of the number of pages per session
expected_sessions = dict(Counter(expected_pages[1]))
actual_sessions = rows['session'].value_counts().to_dict()
sessions = []
for session, number in expected_sessions.items():
try:
sessions.append({'session': SESSIONS[session], 'pages expected': number, 'pages found': actual_sessions[session]})
except KeyError:
sessions.append({'session': SESSIONS[session], 'pages expected': number, 'pages found': 0})
display(pd.DataFrame(sessions).set_index(keys='session').style.apply(highlight_missing, axis=1))
# Show page images
for row in rows.itertuples():
if pd.isnull(row.vol_title):
print(row.reason)
else:
image_url = f'{CLOUDSTOR_URL}/download?path={quote_plus(row.vol_title)}&files=N193-{int(row.vol_num):03}_{int(row.page_num):04}.jpg'
display(HTML(f'<h4>{SESSIONS[row.session]}</h4><p>{row.vol_title}, page {int(row.page_num)} – <a href="{image_url}">Download image</a></p>'))
display(Image(url=image_url))
def start(b):
find_pages()
date_picker = widgets.DatePicker(
description='Pick a Date',
disabled=False,
value=datetime.date(1901, 1, 1)
)
#with results:
# print(os.environ.get('QUERY_STRING', ''))
query_string = os.environ.get('QUERY_STRING', '')
parameters = parse_qs(query_string)
date = parameters.get('date')
find = widgets.Button(
description='Find pages',
disabled=False,
button_style='primary', # 'success', 'info', 'warning', 'danger' or ''
tooltip='Click me',
icon='search'
)
find.on_click(start)
results = widgets.Output()
display(widgets.VBox([widgets.HBox([date_picker, find]), results]))
#display(widgets.HBox([date_picker, find]))
#display(results)
if date:
date_picker.value = arrow.get(date[0]).date()
find_pages()
Created by Tim Sherratt for the GLAM Workbench.