xref: /aosp_15_r20/external/rappor/pipeline/ui.sh (revision 2abb31345f6c95944768b5222a9a5ed3fc68cc00)
1*2abb3134SXin Li#!/bin/bash
2*2abb3134SXin Li#
3*2abb3134SXin Li# Build the user interface.
4*2abb3134SXin Li#
5*2abb3134SXin Li# Usage:
6*2abb3134SXin Li#   ./ui.sh <function name>
7*2abb3134SXin Li
8*2abb3134SXin Liset -o nounset
9*2abb3134SXin Liset -o pipefail
10*2abb3134SXin Liset -o errexit
11*2abb3134SXin Li
12*2abb3134SXin Lireadonly THIS_DIR=$(dirname $0)
13*2abb3134SXin Lireadonly RAPPOR_SRC=$(cd $THIS_DIR/.. && pwd)
14*2abb3134SXin Li
15*2abb3134SXin Lisource $RAPPOR_SRC/pipeline/tools-lib.sh
16*2abb3134SXin Li
17*2abb3134SXin Li# Change the default location of this file by setting DEP_DYGRAPHS_JS
18*2abb3134SXin Lireadonly DYGRAPHS_JS=${DEP_DYGRAPHS_JS:-$RAPPOR_SRC/third_party/dygraph-combined.js}
19*2abb3134SXin Li
20*2abb3134SXin Li_link() {
21*2abb3134SXin Li  ln --verbose -s -f "$@"
22*2abb3134SXin Li}
23*2abb3134SXin Li
24*2abb3134SXin Li_copy() {
25*2abb3134SXin Li  cp --verbose -f "$@"
26*2abb3134SXin Li}
27*2abb3134SXin Li
28*2abb3134SXin Lidownload-dygraphs() {
29*2abb3134SXin Li  local out=third_party
30*2abb3134SXin Li  wget --directory $out \
31*2abb3134SXin Li    http://dygraphs.com/1.1.1/dygraph-combined.js
32*2abb3134SXin Li}
33*2abb3134SXin Li
34*2abb3134SXin Liimport-table() {
35*2abb3134SXin Li  local src=~/git/scratch/ajax/
36*2abb3134SXin Li  cp --verbose $src/table-sort.{js,css} $src/url-hash.js ui
37*2abb3134SXin Li  pushd ui
38*2abb3134SXin Li  # TODO: Could minify it here
39*2abb3134SXin Li  cat table-sort.js url-hash.js > table-lib.js
40*2abb3134SXin Li  popd
41*2abb3134SXin Li}
42*2abb3134SXin Li
43*2abb3134SXin Li# Use symlinks so we can edit and reload during development.
44*2abb3134SXin Lisymlink-static() {
45*2abb3134SXin Li  local kind=$1
46*2abb3134SXin Li  local job_dir=$2
47*2abb3134SXin Li
48*2abb3134SXin Li  local base=$RAPPOR_SRC/ui
49*2abb3134SXin Li
50*2abb3134SXin Li  # HTML goes at the top level.
51*2abb3134SXin Li  if test "$kind" = dist; then
52*2abb3134SXin Li    _link \
53*2abb3134SXin Li      $base/overview.html $base/histograms.html $base/metric.html $base/day.html \
54*2abb3134SXin Li      $job_dir
55*2abb3134SXin Li  elif test "$kind" = assoc; then
56*2abb3134SXin Li    _link \
57*2abb3134SXin Li      $base/assoc-overview.html $base/assoc-metric.html $base/assoc-pair.html \
58*2abb3134SXin Li      $base/assoc-day.html \
59*2abb3134SXin Li      $job_dir
60*2abb3134SXin Li  else
61*2abb3134SXin Li    log "Invalid kind $kind"
62*2abb3134SXin Li    exit 1
63*2abb3134SXin Li  fi
64*2abb3134SXin Li
65*2abb3134SXin Li  mkdir --verbose -p $job_dir/static
66*2abb3134SXin Li
67*2abb3134SXin Li  # Static subdir.
68*2abb3134SXin Li  _link \
69*2abb3134SXin Li    $base/ui.css $base/ui.js \
70*2abb3134SXin Li    $base/table-sort.css $base/table-lib.js \
71*2abb3134SXin Li    $DYGRAPHS_JS \
72*2abb3134SXin Li    $job_dir/static
73*2abb3134SXin Li}
74*2abb3134SXin Li
75*2abb3134SXin Li
76*2abb3134SXin Li# Write HTML fragment based on overview.csv.
77*2abb3134SXin Lioverview-part-html() {
78*2abb3134SXin Li  local job_dir=${1:-_tmp/results-10}
79*2abb3134SXin Li  local out=$job_dir/cooked/overview.part.html
80*2abb3134SXin Li  # Sort by descending date!
81*2abb3134SXin Li  TOOLS-csv-to-html \
82*2abb3134SXin Li    --col-format 'metric <a href="metric.html#metric={metric}">{metric}</a>' \
83*2abb3134SXin Li    < $job_dir/cooked/overview.csv \
84*2abb3134SXin Li    > $out
85*2abb3134SXin Li  echo "Wrote $out"
86*2abb3134SXin Li}
87*2abb3134SXin Li
88*2abb3134SXin Limetric-part-html() {
89*2abb3134SXin Li  local job_dir=${1:-_tmp/results-10}
90*2abb3134SXin Li  # Testing it out.  This should probably be a different dir.
91*2abb3134SXin Li
92*2abb3134SXin Li  for entry in $job_dir/cooked/*; do
93*2abb3134SXin Li    # Only do it for dirs
94*2abb3134SXin Li    if ! test -d $entry; then
95*2abb3134SXin Li      continue
96*2abb3134SXin Li    fi
97*2abb3134SXin Li    # Now it's a metric dir
98*2abb3134SXin Li    echo $entry
99*2abb3134SXin Li
100*2abb3134SXin Li    local metric_name=$(basename $entry)
101*2abb3134SXin Li
102*2abb3134SXin Li    # Convert status.csv to status.part.html (a fragment)
103*2abb3134SXin Li
104*2abb3134SXin Li    # NOTE: counts path could be useful.  You need the input tree though.  Hash
105*2abb3134SXin Li    # it?  Or point to the git link.
106*2abb3134SXin Li
107*2abb3134SXin Li    # Link to raw CSV
108*2abb3134SXin Li    #--col-format 'date <a href="../../raw/{metric}/{date}/results.csv">{date}</a>' \
109*2abb3134SXin Li
110*2abb3134SXin Li    # TODO: Link to ui/results_viewer.html#{metric}_{date}
111*2abb3134SXin Li    # And that needs some JavaScript to load the correct fragment.
112*2abb3134SXin Li    # I guess you could do the same with metric.html.  Currently it uses a
113*2abb3134SXin Li    # symlink.
114*2abb3134SXin Li
115*2abb3134SXin Li    # Before job ID:
116*2abb3134SXin Li    # --col-format 'date <a href="{date}.html">{date}</a>' \
117*2abb3134SXin Li    # --col-format 'status <a href="../../raw/{metric}/{date}/log.txt">{status}</a>' \
118*2abb3134SXin Li
119*2abb3134SXin Li    local fmt1='date <a href="day.html#jobId={job_id}&metric={metric}&date={date}">{date}</a>'
120*2abb3134SXin Li    local fmt2='status <a href="../{job_id}/raw/{metric}/{date}/log.txt">{status}</a>'
121*2abb3134SXin Li
122*2abb3134SXin Li    TOOLS-csv-to-html \
123*2abb3134SXin Li      --def "metric $metric_name" \
124*2abb3134SXin Li      --col-format "$fmt1" \
125*2abb3134SXin Li      --col-format "$fmt2" \
126*2abb3134SXin Li      < $entry/status.csv \
127*2abb3134SXin Li      > $entry/status.part.html
128*2abb3134SXin Li  done
129*2abb3134SXin Li}
130*2abb3134SXin Li
131*2abb3134SXin Liresults-html-one() {
132*2abb3134SXin Li  local csv_in=$1
133*2abb3134SXin Li  echo "$csv_in -> HTML"
134*2abb3134SXin Li
135*2abb3134SXin Li  # .../raw/Settings.HomePage2/2015-03-01/results.csv ->
136*2abb3134SXin Li  # .../cooked/Settings.HomePage2/2015-03-01.part.html
137*2abb3134SXin Li  # (This saves some directories)
138*2abb3134SXin Li  local html_out=$(echo $csv_in | sed -e 's|/raw/|/cooked/|; s|/results.csv|.part.html|')
139*2abb3134SXin Li
140*2abb3134SXin Li  TOOLS-csv-to-html < $csv_in > $html_out
141*2abb3134SXin Li}
142*2abb3134SXin Li
143*2abb3134SXin Liresults-html() {
144*2abb3134SXin Li  local job_dir=${1:-_tmp/results-10}
145*2abb3134SXin Li
146*2abb3134SXin Li  find $job_dir -name results.csv \
147*2abb3134SXin Li    | xargs -n 1 --verbose --no-run-if-empty -- $0 results-html-one
148*2abb3134SXin Li}
149*2abb3134SXin Li
150*2abb3134SXin Li# Build parts of the HTML
151*2abb3134SXin Libuild-html1() {
152*2abb3134SXin Li  local job_dir=${1:-_tmp/results-10}
153*2abb3134SXin Li
154*2abb3134SXin Li  symlink-static dist $job_dir
155*2abb3134SXin Li
156*2abb3134SXin Li  # writes overview.part.html, which is loaded by overview.html
157*2abb3134SXin Li  overview-part-html $job_dir
158*2abb3134SXin Li
159*2abb3134SXin Li  # Writes status.part.html for each metric
160*2abb3134SXin Li  metric-part-html $job_dir
161*2abb3134SXin Li}
162*2abb3134SXin Li
163*2abb3134SXin Li#
164*2abb3134SXin Li# Association Analysis
165*2abb3134SXin Li#
166*2abb3134SXin Li
167*2abb3134SXin Lireadonly ASSOC_TEST_JOB_DIR=~/rappor/chrome-assoc-smoke/smoke5-assoc
168*2abb3134SXin Li
169*2abb3134SXin Li# Write HTML fragment based on CSV.
170*2abb3134SXin Liassoc-overview-part-html() {
171*2abb3134SXin Li  local job_dir=${1:-$ASSOC_TEST_JOB_DIR}
172*2abb3134SXin Li  local html_path=$job_dir/cooked/assoc-overview.part.html
173*2abb3134SXin Li
174*2abb3134SXin Li  # Sort by descending date!
175*2abb3134SXin Li
176*2abb3134SXin Li  TOOLS-csv-to-html \
177*2abb3134SXin Li    --col-format 'metric <a href="assoc-metric.html#metric={metric}">{metric}</a>' \
178*2abb3134SXin Li    < $job_dir/cooked/assoc-overview.csv \
179*2abb3134SXin Li    > $html_path
180*2abb3134SXin Li  echo "Wrote $html_path"
181*2abb3134SXin Li}
182*2abb3134SXin Li
183*2abb3134SXin Liassoc-metric-part-html-one() {
184*2abb3134SXin Li  local csv_path=$1
185*2abb3134SXin Li  local html_path=$(echo $csv_path | sed 's/.csv$/.part.html/')
186*2abb3134SXin Li
187*2abb3134SXin Li  local metric_dir=$(dirname $csv_path)
188*2abb3134SXin Li  local metric_name=$(basename $metric_dir)  # e.g. interstitial.harmful
189*2abb3134SXin Li
190*2abb3134SXin Li  local fmt='days <a href="assoc-pair.html#metric={metric}&var1={var1}&var2={var2}">{days}</a>'
191*2abb3134SXin Li
192*2abb3134SXin Li  TOOLS-csv-to-html \
193*2abb3134SXin Li    --def "metric $metric_name" \
194*2abb3134SXin Li    --col-format "$fmt" \
195*2abb3134SXin Li    < $csv_path \
196*2abb3134SXin Li    > $html_path
197*2abb3134SXin Li
198*2abb3134SXin Li  echo "Wrote $html_path"
199*2abb3134SXin Li}
200*2abb3134SXin Li
201*2abb3134SXin Liassoc-metric-part-html() {
202*2abb3134SXin Li  local job_dir=${1:-$ASSOC_TEST_JOB_DIR}
203*2abb3134SXin Li  # Testing it out.  This should probably be a different dir.
204*2abb3134SXin Li
205*2abb3134SXin Li  find $job_dir/cooked -name metric-status.csv \
206*2abb3134SXin Li    | xargs -n 1 --verbose --no-run-if-empty -- $0 assoc-metric-part-html-one
207*2abb3134SXin Li}
208*2abb3134SXin Li
209*2abb3134SXin Li# TODO:
210*2abb3134SXin Li# - Construct link in JavaScript instead?  It has more information.  The
211*2abb3134SXin Li# pair-metadata.txt file is a hack.
212*2abb3134SXin Li
213*2abb3134SXin Liassoc-pair-part-html-one() {
214*2abb3134SXin Li  local csv_path=$1
215*2abb3134SXin Li  local html_path=$(echo $csv_path | sed 's/.csv$/.part.html/')
216*2abb3134SXin Li
217*2abb3134SXin Li  local pair_dir_path=$(dirname $csv_path)
218*2abb3134SXin Li  local pair_dir_name=$(basename $pair_dir_path)  # e.g. domain_X_flags_IS_REPEAT_VISIT
219*2abb3134SXin Li
220*2abb3134SXin Li  # This file is generated by metric_status.R for each pair of variables.
221*2abb3134SXin Li  local metadata="$pair_dir_path/pair-metadata.txt"
222*2abb3134SXin Li  # Read one variable per line.
223*2abb3134SXin Li  { read metric_name; read var1; read var2; } < $metadata
224*2abb3134SXin Li
225*2abb3134SXin Li  local fmt1='date <a href="assoc-day.html#jobId={job_id}&metric={metric}&var1={var1}&var2={var2}&date={date}">{date}</a>'
226*2abb3134SXin Li  local fmt2="status <a href=\"../{job_id}/raw/{metric}/$pair_dir_name/{date}/assoc-log.txt\">{status}</a>"
227*2abb3134SXin Li
228*2abb3134SXin Li  TOOLS-csv-to-html \
229*2abb3134SXin Li    --def "metric $metric_name" \
230*2abb3134SXin Li    --def "var1 $var1" \
231*2abb3134SXin Li    --def "var2 $var2" \
232*2abb3134SXin Li    --col-format "$fmt1" \
233*2abb3134SXin Li    --col-format "$fmt2" \
234*2abb3134SXin Li    < $csv_path \
235*2abb3134SXin Li    > $html_path
236*2abb3134SXin Li}
237*2abb3134SXin Li
238*2abb3134SXin Liassoc-pair-part-html() {
239*2abb3134SXin Li  local job_dir=${1:-~/rappor/chrome-assoc-smoke/smoke3}
240*2abb3134SXin Li  # Testing it out.  This should probably be a different dir.
241*2abb3134SXin Li
242*2abb3134SXin Li  find $job_dir/cooked -name pair-status.csv \
243*2abb3134SXin Li    | xargs -n 1 --verbose -- $0 assoc-pair-part-html-one
244*2abb3134SXin Li
245*2abb3134SXin Li  return
246*2abb3134SXin Li
247*2abb3134SXin Li  # OLD STUFF
248*2abb3134SXin Li  for entry in $job_dir/cooked/*; do
249*2abb3134SXin Li    # Only do it for dirs
250*2abb3134SXin Li    if ! test -d $entry; then
251*2abb3134SXin Li      continue
252*2abb3134SXin Li    fi
253*2abb3134SXin Li    # Now it's a metric dir
254*2abb3134SXin Li    echo $entry
255*2abb3134SXin Li
256*2abb3134SXin Li    local metric_name=$(basename $entry)
257*2abb3134SXin Li
258*2abb3134SXin Li    # Convert status.csv to status.part.html (a fragment)
259*2abb3134SXin Li
260*2abb3134SXin Li    # NOTE: counts path could be useful.  You need the input tree though.  Hash
261*2abb3134SXin Li    # it?  Or point to the git link.
262*2abb3134SXin Li
263*2abb3134SXin Li    # Link to raw CSV
264*2abb3134SXin Li    #--col-format 'date <a href="../../raw/{metric}/{date}/results.csv">{date}</a>' \
265*2abb3134SXin Li
266*2abb3134SXin Li    # TODO: Link to ui/results_viewer.html#{metric}_{date}
267*2abb3134SXin Li    # And that needs some JavaScript to load the correct fragment.
268*2abb3134SXin Li    # I guess you could do the same with metric.html.  Currently it uses a
269*2abb3134SXin Li    # symlink.
270*2abb3134SXin Li
271*2abb3134SXin Li    # Before job ID:
272*2abb3134SXin Li    # --col-format 'date <a href="{date}.html">{date}</a>' \
273*2abb3134SXin Li    # --col-format 'status <a href="../../raw/{metric}/{date}/log.txt">{status}</a>' \
274*2abb3134SXin Li
275*2abb3134SXin Li    local fmt1='date <a href="day.html#jobId={job_id}&metric={metric}&date={date}">{date}</a>'
276*2abb3134SXin Li    local fmt2='status <a href="../{job_id}/raw/{metric}/{date}/log.txt">{status}</a>'
277*2abb3134SXin Li
278*2abb3134SXin Li    TOOLS-csv-to-html \
279*2abb3134SXin Li      --def "metric $metric_name" \
280*2abb3134SXin Li      --col-format "$fmt1" \
281*2abb3134SXin Li      --col-format "$fmt2" \
282*2abb3134SXin Li      < $entry/status.csv \
283*2abb3134SXin Li      > $entry/status.part.html
284*2abb3134SXin Li  done
285*2abb3134SXin Li}
286*2abb3134SXin Li
287*2abb3134SXin Liassoc-day-part-html-one() {
288*2abb3134SXin Li  local csv_in=$1
289*2abb3134SXin Li  echo "$csv_in -> HTML"
290*2abb3134SXin Li
291*2abb3134SXin Li  # .../raw/interstitial.harmful/a_X_b/2015-03-01/assoc-results.csv ->
292*2abb3134SXin Li  # .../cooked/interstitial.harmful/a_X_b/2015-03-01.part.html
293*2abb3134SXin Li  # (This saves some directories)
294*2abb3134SXin Li  local html_out=$(echo $csv_in | sed -e 's|/raw/|/cooked/|; s|/assoc-results.csv|.part.html|')
295*2abb3134SXin Li
296*2abb3134SXin Li  TOOLS-csv-to-html --as-percent proportion < $csv_in > $html_out
297*2abb3134SXin Li}
298*2abb3134SXin Li
299*2abb3134SXin Liassoc-day-part-html() {
300*2abb3134SXin Li  local job_dir=${1:-_tmp/results-10}
301*2abb3134SXin Li
302*2abb3134SXin Li  find $job_dir -name assoc-results.csv \
303*2abb3134SXin Li    | xargs -n 1 --verbose --no-run-if-empty -- $0 assoc-day-part-html-one
304*2abb3134SXin Li}
305*2abb3134SXin Li
306*2abb3134SXin Lilint-html() {
307*2abb3134SXin Li  set -o xtrace
308*2abb3134SXin Li  set +o errexit  # don't fail fast
309*2abb3134SXin Li  tidy -errors -quiet ui/metric.html
310*2abb3134SXin Li  tidy -errors -quiet ui/overview.html
311*2abb3134SXin Li  tidy -errors -quiet ui/histograms.html
312*2abb3134SXin Li}
313*2abb3134SXin Li
314*2abb3134SXin Li# Directory we should serve from
315*2abb3134SXin Lireadonly WWW_DIR=_tmp
316*2abb3134SXin Li
317*2abb3134SXin Liserve() {
318*2abb3134SXin Li  local port=${1:-7999}
319*2abb3134SXin Li  cd $WWW_DIR && python -m SimpleHTTPServer $port
320*2abb3134SXin Li}
321*2abb3134SXin Li
322*2abb3134SXin Li"$@"
323