unplugged-system/external/rappor/pipeline/ui.sh

323 lines
8.5 KiB
Bash
Executable File

#!/bin/bash
#
# Build the user interface.
#
# Usage:
# ./ui.sh <function name>
set -o nounset
set -o pipefail
set -o errexit
readonly THIS_DIR=$(dirname $0)
readonly RAPPOR_SRC=$(cd $THIS_DIR/.. && pwd)
source $RAPPOR_SRC/pipeline/tools-lib.sh
# Change the default location of this file by setting DEP_DYGRAPHS_JS
readonly DYGRAPHS_JS=${DEP_DYGRAPHS_JS:-$RAPPOR_SRC/third_party/dygraph-combined.js}
_link() {
ln --verbose -s -f "$@"
}
_copy() {
cp --verbose -f "$@"
}
download-dygraphs() {
local out=third_party
wget --directory $out \
http://dygraphs.com/1.1.1/dygraph-combined.js
}
import-table() {
local src=~/git/scratch/ajax/
cp --verbose $src/table-sort.{js,css} $src/url-hash.js ui
pushd ui
# TODO: Could minify it here
cat table-sort.js url-hash.js > table-lib.js
popd
}
# Use symlinks so we can edit and reload during development.
symlink-static() {
local kind=$1
local job_dir=$2
local base=$RAPPOR_SRC/ui
# HTML goes at the top level.
if test "$kind" = dist; then
_link \
$base/overview.html $base/histograms.html $base/metric.html $base/day.html \
$job_dir
elif test "$kind" = assoc; then
_link \
$base/assoc-overview.html $base/assoc-metric.html $base/assoc-pair.html \
$base/assoc-day.html \
$job_dir
else
log "Invalid kind $kind"
exit 1
fi
mkdir --verbose -p $job_dir/static
# Static subdir.
_link \
$base/ui.css $base/ui.js \
$base/table-sort.css $base/table-lib.js \
$DYGRAPHS_JS \
$job_dir/static
}
# Write HTML fragment based on overview.csv.
overview-part-html() {
local job_dir=${1:-_tmp/results-10}
local out=$job_dir/cooked/overview.part.html
# Sort by descending date!
TOOLS-csv-to-html \
--col-format 'metric <a href="metric.html#metric={metric}">{metric}</a>' \
< $job_dir/cooked/overview.csv \
> $out
echo "Wrote $out"
}
metric-part-html() {
local job_dir=${1:-_tmp/results-10}
# Testing it out. This should probably be a different dir.
for entry in $job_dir/cooked/*; do
# Only do it for dirs
if ! test -d $entry; then
continue
fi
# Now it's a metric dir
echo $entry
local metric_name=$(basename $entry)
# Convert status.csv to status.part.html (a fragment)
# NOTE: counts path could be useful. You need the input tree though. Hash
# it? Or point to the git link.
# Link to raw CSV
#--col-format 'date <a href="../../raw/{metric}/{date}/results.csv">{date}</a>' \
# TODO: Link to ui/results_viewer.html#{metric}_{date}
# And that needs some JavaScript to load the correct fragment.
# I guess you could do the same with metric.html. Currently it uses a
# symlink.
# Before job ID:
# --col-format 'date <a href="{date}.html">{date}</a>' \
# --col-format 'status <a href="../../raw/{metric}/{date}/log.txt">{status}</a>' \
local fmt1='date <a href="day.html#jobId={job_id}&metric={metric}&date={date}">{date}</a>'
local fmt2='status <a href="../{job_id}/raw/{metric}/{date}/log.txt">{status}</a>'
TOOLS-csv-to-html \
--def "metric $metric_name" \
--col-format "$fmt1" \
--col-format "$fmt2" \
< $entry/status.csv \
> $entry/status.part.html
done
}
results-html-one() {
local csv_in=$1
echo "$csv_in -> HTML"
# .../raw/Settings.HomePage2/2015-03-01/results.csv ->
# .../cooked/Settings.HomePage2/2015-03-01.part.html
# (This saves some directories)
local html_out=$(echo $csv_in | sed -e 's|/raw/|/cooked/|; s|/results.csv|.part.html|')
TOOLS-csv-to-html < $csv_in > $html_out
}
results-html() {
local job_dir=${1:-_tmp/results-10}
find $job_dir -name results.csv \
| xargs -n 1 --verbose --no-run-if-empty -- $0 results-html-one
}
# Build parts of the HTML
build-html1() {
local job_dir=${1:-_tmp/results-10}
symlink-static dist $job_dir
# writes overview.part.html, which is loaded by overview.html
overview-part-html $job_dir
# Writes status.part.html for each metric
metric-part-html $job_dir
}
#
# Association Analysis
#
readonly ASSOC_TEST_JOB_DIR=~/rappor/chrome-assoc-smoke/smoke5-assoc
# Write HTML fragment based on CSV.
assoc-overview-part-html() {
local job_dir=${1:-$ASSOC_TEST_JOB_DIR}
local html_path=$job_dir/cooked/assoc-overview.part.html
# Sort by descending date!
TOOLS-csv-to-html \
--col-format 'metric <a href="assoc-metric.html#metric={metric}">{metric}</a>' \
< $job_dir/cooked/assoc-overview.csv \
> $html_path
echo "Wrote $html_path"
}
assoc-metric-part-html-one() {
local csv_path=$1
local html_path=$(echo $csv_path | sed 's/.csv$/.part.html/')
local metric_dir=$(dirname $csv_path)
local metric_name=$(basename $metric_dir) # e.g. interstitial.harmful
local fmt='days <a href="assoc-pair.html#metric={metric}&var1={var1}&var2={var2}">{days}</a>'
TOOLS-csv-to-html \
--def "metric $metric_name" \
--col-format "$fmt" \
< $csv_path \
> $html_path
echo "Wrote $html_path"
}
assoc-metric-part-html() {
local job_dir=${1:-$ASSOC_TEST_JOB_DIR}
# Testing it out. This should probably be a different dir.
find $job_dir/cooked -name metric-status.csv \
| xargs -n 1 --verbose --no-run-if-empty -- $0 assoc-metric-part-html-one
}
# TODO:
# - Construct link in JavaScript instead? It has more information. The
# pair-metadata.txt file is a hack.
assoc-pair-part-html-one() {
local csv_path=$1
local html_path=$(echo $csv_path | sed 's/.csv$/.part.html/')
local pair_dir_path=$(dirname $csv_path)
local pair_dir_name=$(basename $pair_dir_path) # e.g. domain_X_flags_IS_REPEAT_VISIT
# This file is generated by metric_status.R for each pair of variables.
local metadata="$pair_dir_path/pair-metadata.txt"
# Read one variable per line.
{ read metric_name; read var1; read var2; } < $metadata
local fmt1='date <a href="assoc-day.html#jobId={job_id}&metric={metric}&var1={var1}&var2={var2}&date={date}">{date}</a>'
local fmt2="status <a href=\"../{job_id}/raw/{metric}/$pair_dir_name/{date}/assoc-log.txt\">{status}</a>"
TOOLS-csv-to-html \
--def "metric $metric_name" \
--def "var1 $var1" \
--def "var2 $var2" \
--col-format "$fmt1" \
--col-format "$fmt2" \
< $csv_path \
> $html_path
}
assoc-pair-part-html() {
local job_dir=${1:-~/rappor/chrome-assoc-smoke/smoke3}
# Testing it out. This should probably be a different dir.
find $job_dir/cooked -name pair-status.csv \
| xargs -n 1 --verbose -- $0 assoc-pair-part-html-one
return
# OLD STUFF
for entry in $job_dir/cooked/*; do
# Only do it for dirs
if ! test -d $entry; then
continue
fi
# Now it's a metric dir
echo $entry
local metric_name=$(basename $entry)
# Convert status.csv to status.part.html (a fragment)
# NOTE: counts path could be useful. You need the input tree though. Hash
# it? Or point to the git link.
# Link to raw CSV
#--col-format 'date <a href="../../raw/{metric}/{date}/results.csv">{date}</a>' \
# TODO: Link to ui/results_viewer.html#{metric}_{date}
# And that needs some JavaScript to load the correct fragment.
# I guess you could do the same with metric.html. Currently it uses a
# symlink.
# Before job ID:
# --col-format 'date <a href="{date}.html">{date}</a>' \
# --col-format 'status <a href="../../raw/{metric}/{date}/log.txt">{status}</a>' \
local fmt1='date <a href="day.html#jobId={job_id}&metric={metric}&date={date}">{date}</a>'
local fmt2='status <a href="../{job_id}/raw/{metric}/{date}/log.txt">{status}</a>'
TOOLS-csv-to-html \
--def "metric $metric_name" \
--col-format "$fmt1" \
--col-format "$fmt2" \
< $entry/status.csv \
> $entry/status.part.html
done
}
assoc-day-part-html-one() {
local csv_in=$1
echo "$csv_in -> HTML"
# .../raw/interstitial.harmful/a_X_b/2015-03-01/assoc-results.csv ->
# .../cooked/interstitial.harmful/a_X_b/2015-03-01.part.html
# (This saves some directories)
local html_out=$(echo $csv_in | sed -e 's|/raw/|/cooked/|; s|/assoc-results.csv|.part.html|')
TOOLS-csv-to-html --as-percent proportion < $csv_in > $html_out
}
assoc-day-part-html() {
local job_dir=${1:-_tmp/results-10}
find $job_dir -name assoc-results.csv \
| xargs -n 1 --verbose --no-run-if-empty -- $0 assoc-day-part-html-one
}
lint-html() {
set -o xtrace
set +o errexit # don't fail fast
tidy -errors -quiet ui/metric.html
tidy -errors -quiet ui/overview.html
tidy -errors -quiet ui/histograms.html
}
# Directory we should serve from
readonly WWW_DIR=_tmp
serve() {
local port=${1:-7999}
cd $WWW_DIR && python -m SimpleHTTPServer $port
}
"$@"