summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Schlaeger <chris@linux.com>2014-08-16 22:31:10 +0200
committerChris Schlaeger <chris@linux.com>2014-08-16 22:31:10 +0200
commit420d3bc52169969196f9c6d9eda58f40b9e47893 (patch)
treef9895c5851eca257eb7211c73df8412843102dad /lib
parente8885b131d8095aa0340a02c644e1f4543dc9630 (diff)
downloadpostrunner-420d3bc52169969196f9c6d9eda58f40b9e47893.zip
Adding HTML index page for activities.
Diffstat (limited to 'lib')
-rw-r--r--lib/postrunner/ActivitiesDB.rb59
-rw-r--r--lib/postrunner/ActivityListView.rb147
-rw-r--r--lib/postrunner/ActivityView.rb73
-rw-r--r--lib/postrunner/FlexiTable.rb9
-rw-r--r--lib/postrunner/ViewWidgets.rb60
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