diff options
-rw-r--r-- | lib/postrunner/ActivitiesDB.rb | 59 | ||||
-rw-r--r-- | lib/postrunner/ActivityListView.rb | 147 | ||||
-rw-r--r-- | lib/postrunner/ActivityView.rb | 73 | ||||
-rw-r--r-- | lib/postrunner/FlexiTable.rb | 9 | ||||
-rw-r--r-- | lib/postrunner/ViewWidgets.rb | 60 |
5 files changed, 256 insertions, 92 deletions
diff --git a/lib/postrunner/ActivitiesDB.rb b/lib/postrunner/ActivitiesDB.rb index 759bec6..008fb09 100644 --- a/lib/postrunner/ActivitiesDB.rb +++ b/lib/postrunner/ActivitiesDB.rb @@ -16,19 +16,18 @@ require 'yaml' require 'fit4ruby' require 'postrunner/Activity' require 'postrunner/PersonalRecords' -require 'postrunner/FlexiTable' +require 'postrunner/ActivityListView' module PostRunner class ActivitiesDB - include Fit4Ruby::Converters - - attr_reader :db_dir, :fit_dir + attr_reader :db_dir, :fit_dir, :html_dir, :activities def initialize(db_dir) @db_dir = db_dir @fit_dir = File.join(@db_dir, 'fit') + @html_dir = File.join(@db_dir, 'html') @archive_file = File.join(@db_dir, 'archive.yml') create_directories @@ -184,29 +183,7 @@ module PostRunner end def list - i = 0 - t = FlexiTable.new - t.head - t.row(%w( Ref. Activity Start Distance Duration Pace ), - { :halign => :left }) - t.set_column_attributes([ - { :halign => :right }, - {}, {}, - { :halign => :right }, - { :halign => :right }, - { :halign => :right } - ]) - t.body - @activities.each do |a| - t.row([ - i += 1, - a.name[0..19], - a.timestamp.strftime("%a, %Y %b %d %H:%M"), - "%.2f" % (a.total_distance / 1000), - secsToHMS(a.total_timer_time), - speedToPace(a.avg_speed) ]) - end - puts t.to_s + puts ActivityListView.new(self).to_s end def show_records @@ -223,11 +200,17 @@ module PostRunner end @records.sync + ActivityListView.new(self).update_html_index end def create_directories create_directory(@db_dir, 'data') create_directory(@fit_dir, 'fit') + create_directory(@html_dir, 'html') + + create_symlink('jquery') + create_symlink('flot') + create_symlink('openlayers') end def create_directory(dir, name) @@ -241,6 +224,28 @@ module PostRunner end end + def create_symlink(dir) + # This file should be in lib/postrunner. The 'misc' directory should be + # found in '../../misc'. + misc_dir = File.realpath(File.join(File.dirname(__FILE__), + '..', '..', 'misc')) + unless Dir.exists?(misc_dir) + Log.fatal "Cannot find 'misc' directory under '#{misc_dir}': #{$!}" + end + src_dir = File.join(misc_dir, dir) + unless Dir.exists?(src_dir) + Log.fatal "Cannot find '#{src_dir}': #{$!}" + end + dst_dir = File.join(@html_dir, dir) + unless File.exists?(dst_dir) + begin + FileUtils.ln_s(src_dir, dst_dir) + rescue IOError + Log.fatal "Cannot create symbolic link to '#{dst_dir}': #{$!}" + end + end + end + end end diff --git a/lib/postrunner/ActivityListView.rb b/lib/postrunner/ActivityListView.rb new file mode 100644 index 0000000..40728b1 --- /dev/null +++ b/lib/postrunner/ActivityListView.rb @@ -0,0 +1,147 @@ +#!/usr/bin/env ruby -w +# encoding: UTF-8 +# +# = ActivitListView.rb -- PostRunner - Manage the data from your Garmin sport devices. +# +# Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# + +require 'fit4ruby' + +require 'postrunner/FlexiTable' +require 'postrunner/HTMLBuilder' +require 'postrunner/ViewWidgets' + +module PostRunner + + class ActivityListView + + class ActivityLink + + def initialize(activity) + @activity = activity + end + + def to_html(doc) + doc.a(@activity.name, { :class => 'activity_link', + :href => @activity.fit_file[0..-5] + '.html' }) + end + + def to_s + @activity.name[0..19] + end + + end + + include Fit4Ruby::Converters + include ViewWidgets + + def initialize(db) + @db = db + end + + def update_html_index + doc = HTMLBuilder.new + + doc.html { + head(doc) + body(doc) + } + + write_file(doc) + end + + def to_html(doc) + generate_table.to_html(doc) + end + + def to_s + generate_table.to_s + end + + private + + def head(doc) + doc.head { + doc.meta({ 'http-equiv' => 'Content-Type', + 'content' => 'text/html; charset=utf-8' }) + doc.title("PostRunner Activities") + style(doc) + } + end + + def style(doc) + view_widgets_style(doc) + doc.style(<<EOT +body { + font-family: verdana,arial,sans-serif; + margin: 0px; +} +.main { + text-align: center; +} +.widget_frame { + width: 900px; +} +.activity_link { + padding: 0px 3px 0px 3px; +} +EOT + ) + end + + def body(doc) + doc.body { + titlebar(doc) + doc.div({ :class => 'main' }) { + frame(doc, 'Activities') { + generate_table.to_html(doc) + } + } + footer(doc) + } + end + + def generate_table + i = 0 + t = FlexiTable.new + t.head + t.row(%w( Ref. Activity Start Distance Duration Pace ), + { :halign => :left }) + t.set_column_attributes([ + { :halign => :right }, + {}, {}, + { :halign => :right }, + { :halign => :right }, + { :halign => :right } + ]) + t.body + @db.activities.each do |a| + t.row([ + i += 1, + ActivityLink.new(a), + a.timestamp.strftime("%a, %Y %b %d %H:%M"), + "%.2f" % (a.total_distance / 1000), + secsToHMS(a.total_timer_time), + speedToPace(a.avg_speed) ]) + end + + t + end + + def write_file(doc) + output_file = File.join(@db.html_dir, 'index.html') + begin + File.write(output_file, doc.to_html) + rescue IOError + Log.fatal "Cannot write activity index file '#{output_file}: #{$!}" + end + end + end + +end + diff --git a/lib/postrunner/ActivityView.rb b/lib/postrunner/ActivityView.rb index 3c6312a..6c487c2 100644 --- a/lib/postrunner/ActivityView.rb +++ b/lib/postrunner/ActivityView.rb @@ -29,8 +29,6 @@ module PostRunner @output_dir = activity.html_dir @output_file = nil - ensure_output_dir - @doc = HTMLBuilder.new generate_html(@doc) write_file @@ -38,42 +36,6 @@ module PostRunner private - def ensure_output_dir - unless Dir.exists?(@output_dir) - begin - Dir.mkdir(@output_dir) - rescue SystemCallError - Log.fatal "Cannot create output directory '#{@output_dir}': #{$!}" - end - end - create_symlink('jquery') - create_symlink('flot') - create_symlink('openlayers') - end - - def create_symlink(dir) - # This file should be in lib/postrunner. The 'misc' directory should be - # found in '../../misc'. - misc_dir = File.realpath(File.join(File.dirname(__FILE__), - '..', '..', 'misc')) - unless Dir.exists?(misc_dir) - Log.fatal "Cannot find 'misc' directory under '#{misc_dir}': #{$!}" - end - src_dir = File.join(misc_dir, dir) - unless Dir.exists?(src_dir) - Log.fatal "Cannot find '#{src_dir}': #{$!}" - end - dst_dir = File.join(@output_dir, dir) - unless File.exists?(dst_dir) - begin - FileUtils.ln_s(src_dir, dst_dir) - rescue IOError - Log.fatal "Cannot create symbolic link to '#{dst_dir}': #{$!}" - end - end - end - - def generate_html(doc) @report = ActivityReport.new(@activity) @track_view = TrackView.new(@activity) @@ -94,17 +56,18 @@ module PostRunner 'initial-scale=1.0, maximum-scale=1.0, ' + 'user-scalable=0' }) doc.title("PostRunner Activity: #{@activity.name}") - style(doc) view_widgets_style(doc) @chart_view.head(doc) @track_view.head(doc) + style(doc) } end def style(doc) doc.style(<<EOT -.body { +body { font-family: verdana,arial,sans-serif; + margin: 0px; } .main { width: 1210px; @@ -118,40 +81,24 @@ module PostRunner float: right; width: 600px; } -.flexitable { - width: 100%; - border: 1px solid #CCCCCC; - border-collapse: collapse; - font-size:11pt; -} -.ft_head_row { - background-color: #DEDEDE -} -.ft_even_row { - background-color: #FCFCFC -} -.ft_odd_row { - background-color: #F1F1F1 -} -.ft_cell { - border: 1px solid #CCCCCC; - padding: 1px 3px; -} EOT ) end def body(doc) - doc.body({ 'onload' => 'init()' }) { - doc.div({ 'class' => 'main' }) { - doc.div({ 'class' => 'left_col' }) { + doc.body({ :onload => 'init()' }) { + titlebar(doc) + # The main area with the 2 column layout. + doc.div({ :class => 'main' }) { + doc.div({ :class => 'left_col' }) { @report.to_html(doc) @track_view.div(doc) } - doc.div({ 'class' => 'right_col' }) { + doc.div({ :class => 'right_col' }) { @chart_view.div(doc) } } + footer(doc) } end diff --git a/lib/postrunner/FlexiTable.rb b/lib/postrunner/FlexiTable.rb index bbb9d06..0de737e 100644 --- a/lib/postrunner/FlexiTable.rb +++ b/lib/postrunner/FlexiTable.rb @@ -85,8 +85,13 @@ module PostRunner text_align = get_attribute(:halign) attrs = { :class => 'ft_cell' } attrs[:style] = "text-align: #{text_align.to_s}" if text_align - doc.td(@content.respond_to?('to_html') ? - @content.to_html(doc) : @content.to_s, attrs) + if @content.respond_to?('to_html') + doc.td(attrs) { + @content.to_html(doc) + } + else + doc.td(@content.to_s, attrs) + end end private diff --git a/lib/postrunner/ViewWidgets.rb b/lib/postrunner/ViewWidgets.rb index f9e6848..05e5455 100644 --- a/lib/postrunner/ViewWidgets.rb +++ b/lib/postrunner/ViewWidgets.rb @@ -16,6 +16,19 @@ module PostRunner def view_widgets_style(doc) doc.style(<<EOT +.titlebar { + width: 100%; + height: 50px; + margin: 0px; + background: linear-gradient(#7FA1FF 0, #002EAC 50px); +} +.title { + font-size: 24pt; + font-style: italic; + font-weight: bold; + color: #F8F8F8; + padding: 3px 30px; +} .widget_frame { box-sizing: border-box; width: 600px; @@ -37,6 +50,34 @@ module PostRunner .widget_frame_title { font-size:13pt; padding-bottom: 5px; + text-align: left; +} +.flexitable { + width: 100%; + border: 1px solid #CCCCCC; + border-collapse: collapse; + font-size:11pt; +} +.ft_head_row { + background-color: #DEDEDE +} +.ft_even_row { + background-color: #FCFCFC +} +.ft_odd_row { + background-color: #F1F1F1 +} +.ft_cell { + border: 1px solid #CCCCCC; + padding: 1px 3px; +} +.footer { + clear: both; + width: 100%; + height: 30px; + padding: 15px; + text-align: center; + font-size: 9pt; } EOT ) @@ -53,6 +94,25 @@ EOT } end + def titlebar(doc) + # The top title bar. + doc.div({ :class => 'titlebar' }) { + doc.div('PostRunner', { :class => 'title' }) + } + end + + def footer(doc) + doc.div({ :class => 'footer' }){ + doc.hr + doc.div({ :class => 'copyright' }) { + doc.text("Generated by ") + doc.a('PostRunner', + { :href => 'https://github.com/scrapper/postrunner' }) + doc.text(" #{VERSION} on #{Time.now}") + } + } + end + end end |