postrunner 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = RecordListPageView.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'fit4ruby'
14
+
15
+ require 'postrunner/FlexiTable'
16
+ require 'postrunner/View'
17
+ require 'postrunner/ViewFrame'
18
+ require 'postrunner/ViewButtons'
19
+ require 'postrunner/PagingButtons'
20
+
21
+ module PostRunner
22
+
23
+ # Generates an HTML page with all personal records for a particular sport
24
+ # type.
25
+ class RecordListPageView < View
26
+
27
+ include Fit4Ruby::Converters
28
+
29
+ # Create a RecordListPageView object.
30
+ # @param db [ActivityDB] Activity database
31
+ # @param records [PersonalRecords] Database with personal records
32
+ # @param page_count [Fixnum] Number of total pages
33
+ # @param page_index [Fixnum] Index of the page
34
+ def initialize(db, records, page_count, page_index)
35
+ @db = db
36
+ @unit_system = @db.cfg[:unit_system]
37
+ @records = records
38
+
39
+ views = @db.views
40
+ views.current_page = "records-0.html"
41
+
42
+ pages = PagingButtons.new((0..(page_count - 1)).map do |i|
43
+ "records-#{i}.html"
44
+ end)
45
+ pages.current_page =
46
+ "records-#{page_index}.html"
47
+
48
+ @sport_name = Activity::ActivityTypes[@records.sport]
49
+ super("#{@sport_name} Records", views, pages)
50
+
51
+ body {
52
+ frame_width = 800
53
+
54
+ @doc.div({ :class => 'main' }) {
55
+ ViewFrame.new("All-time #{@sport_name} Records",
56
+ frame_width, @records.all_time).to_html(@doc)
57
+
58
+ @records.yearly.each do |year, record|
59
+ next if record.empty?
60
+ ViewFrame.new("#{year} #{@sport_name} Records",
61
+ frame_width, record).to_html(@doc)
62
+ end
63
+ }
64
+ }
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = ActivitiesDB.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
5
  #
6
- # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
6
+ # Copyright (c) 2014, 2015 by Chris Schlaeger <cs@taskjuggler.org>
7
7
  #
8
8
  # This program is free software; you can redistribute it and/or modify
9
9
  # it under the terms of version 2 of the GNU General Public License as
@@ -12,6 +12,7 @@
12
12
 
13
13
  require 'yaml'
14
14
  require 'fit4ruby'
15
+ require 'postrunner/BackedUpFile'
15
16
 
16
17
  module PostRunner
17
18
 
@@ -25,7 +26,8 @@ module PostRunner
25
26
  @options = {
26
27
  :version => '0.0.0',
27
28
  :unit_system => :metric,
28
- :import_dir => nil
29
+ :import_dir => nil,
30
+ :html_dir => File.join(dir, 'html')
29
31
  }
30
32
  @config_file = File.join(dir, 'config.yml')
31
33
 
@@ -68,7 +70,7 @@ module PostRunner
68
70
 
69
71
  def save_options
70
72
  begin
71
- File.write(@config_file, @options.to_yaml)
73
+ BackedUpFile.write(@config_file, @options.to_yaml)
72
74
  Log.info "Runtime config file '#{@config_file}' written"
73
75
  rescue
74
76
  Log.error "Cannot write config file '#{@config_file}': #{$!}"
@@ -12,37 +12,35 @@
12
12
 
13
13
  require 'fit4ruby'
14
14
 
15
- require 'postrunner/ViewWidgets'
15
+ require 'postrunner/ViewFrame'
16
16
 
17
17
  module PostRunner
18
18
 
19
19
  class TrackView
20
20
 
21
- include ViewWidgets
22
-
23
21
  def initialize(activity)
24
22
  @activity = activity
25
23
  @session = @activity.fit_activity.sessions[0]
26
24
  @has_geo_data = @session.has_geo_data?
27
25
  end
28
26
 
29
- def head(doc)
27
+ def to_html(doc)
30
28
  return unless @has_geo_data
31
29
 
32
- doc.link({ 'rel' => 'stylesheet',
33
- 'href' => 'openlayers/theme/default/style.css',
34
- 'type' => 'text/css' })
35
- doc.style(style)
36
- doc.script({ 'src' => 'openlayers/OpenLayers.js' })
37
- doc.script(java_script)
38
- end
39
-
40
- def div(doc)
41
- return unless @has_geo_data
30
+ doc.head {
31
+ doc.unique(:trackview_style) {
32
+ doc.style(style)
33
+ doc.link({ 'rel' => 'stylesheet',
34
+ 'href' => 'openlayers/theme/default/style.css',
35
+ 'type' => 'text/css' })
36
+ doc.script({ 'src' => 'openlayers/OpenLayers.js' })
37
+ }
38
+ doc.script(java_script)
39
+ }
42
40
 
43
- frame(doc, 'Map') {
41
+ ViewFrame.new('Map', 600) {
44
42
  doc.div({ 'id' => 'map', 'class' => 'trackmap' })
45
- }
43
+ }.to_html(doc)
46
44
  end
47
45
 
48
46
  private
@@ -12,14 +12,12 @@
12
12
 
13
13
  require 'fit4ruby'
14
14
 
15
- require 'postrunner/ViewWidgets'
15
+ require 'postrunner/ViewFrame'
16
16
 
17
17
  module PostRunner
18
18
 
19
19
  class UserProfileView
20
20
 
21
- include ViewWidgets
22
-
23
21
  def initialize(fit_activity, unit_system)
24
22
  @fit_activity = fit_activity
25
23
  @unit_system = unit_system
@@ -28,9 +26,7 @@ module PostRunner
28
26
  def to_html(doc)
29
27
  return nil if @fit_activity.user_profiles.empty?
30
28
 
31
- frame(doc, 'User Profile') {
32
- profile.to_html(doc)
33
- }
29
+ ViewFrame.new('User Profile', 600, profile).to_html(doc)
34
30
  end
35
31
 
36
32
  def to_s
@@ -47,7 +43,7 @@ module PostRunner
47
43
  unit = { :metric => 'm', :statute => 'ft' }[@unit_system]
48
44
  height = profile.get_as('height', unit)
49
45
  t.cell('Height:', { :width => '40%' })
50
- t.cell("#{'%.1f' % height} #{unit}", { :width => '60%' })
46
+ t.cell("#{'%.2f' % height} #{unit}", { :width => '60%' })
51
47
  t.new_row
52
48
  end
53
49
  if profile.weight
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = View.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'postrunner/HTMLBuilder'
14
+ require 'postrunner/ViewTop'
15
+ require 'postrunner/ViewBottom'
16
+
17
+ module PostRunner
18
+
19
+ # Base class for all generated HTML pages.
20
+ class View
21
+
22
+ attr_reader :doc
23
+
24
+ # Create a new View object.
25
+ # @param title [String] The title of the HTML page
26
+ # @param views [ViewButtons] List of all cross referenced View objects
27
+ # @param pages [PagingButtons] List of all pages of this View
28
+ def initialize(title, views, pages)
29
+ @doc = HTMLBuilder.new(title)
30
+ @views = views
31
+ @pages = pages
32
+
33
+ @doc.unique(:view_style) {
34
+ style
35
+ }
36
+ end
37
+
38
+ # Create the body section of the HTML document.
39
+ def body
40
+ ViewTop.new(@views, @pages).to_html(@doc)
41
+ yield if block_given?
42
+ ViewBottom.new.to_html(@doc)
43
+
44
+ self
45
+ end
46
+
47
+ # Convert the View into an HTML document.
48
+ def to_html
49
+ @doc.to_html
50
+ end
51
+
52
+ # Write the HTML document to a file
53
+ # @param file_name [String] Name of the file to write
54
+ def write(file_name)
55
+ begin
56
+ File.write(file_name, to_html)
57
+ rescue IOError
58
+ Log.fatal "Cannot write file '#{file_name}: #{$!}"
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def style
65
+ @doc.head {
66
+ @doc.style(<<"EOT"
67
+ body {
68
+ font-family: verdana,arial,sans-serif;
69
+ margin: 0px;
70
+ }
71
+ .flexitable {
72
+ width: 100%;
73
+ border: 2px solid #545454;
74
+ border-collapse: collapse;
75
+ font-size:11pt;
76
+ }
77
+ .ft_head_row {
78
+ background-color: #DEDEDE
79
+ }
80
+ .ft_even_row {
81
+ background-color: #FCFCFC
82
+ }
83
+ .ft_odd_row {
84
+ background-color: #F1F1F1
85
+ }
86
+ .ft_cell {
87
+ border: 1px solid #CCCCCC;
88
+ padding: 1px 3px;
89
+ }
90
+ EOT
91
+ )
92
+ }
93
+ end
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = ViewBottom.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'postrunner/HTMLBuilder'
14
+ require 'postrunner/version'
15
+
16
+ module PostRunner
17
+
18
+ # This class generates the footer of a HTML page.
19
+ class ViewBottom
20
+
21
+ # Generate the HTML code to that describes the foot section.
22
+ # @param doc [HTMLBuilder] Reference to the HTML document to add to.
23
+ def to_html(doc)
24
+ doc.unique(:viewbottom_style) {
25
+ doc.head { doc.style(style) }
26
+ }
27
+ doc.div({ :class => 'footer' }){
28
+ doc.hr
29
+ doc.div({ :class => 'copyright' }) {
30
+ doc.text("Generated by ")
31
+ doc.a('PostRunner',
32
+ { :href => 'https://github.com/scrapper/postrunner' })
33
+ doc.text(" #{VERSION} on #{Time.now}")
34
+ }
35
+ }
36
+ end
37
+
38
+ private
39
+
40
+ def style
41
+ <<EOT
42
+ .footer {
43
+ clear: both;
44
+ width: 100%;
45
+ height: 30px;
46
+ padding: 15px 0px;
47
+ text-align: center;
48
+ font-size: 9pt;
49
+ }
50
+ EOT
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = ViewButtons.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ module PostRunner
14
+
15
+ # This class generates a simple icon menue to select from a set of HTML
16
+ # pages (called views). The current page is represented as an inactive icon.
17
+ # All other icons are buttons that contain links to other pages.
18
+ class ViewButtons
19
+
20
+ # Create a ViewButtons object.
21
+ # @params views [Array of NavButtonDef] icons and URLs for all pages.
22
+ def initialize(views)
23
+ if views.empty?
24
+ raise ArgumentError.new("'views' must not be empty")
25
+ end
26
+ @views = views
27
+ self.current_page = views[0].url
28
+ end
29
+
30
+ # Get the URL of the current page
31
+ # @return [String]
32
+ def current_page
33
+ @current_view_url
34
+ end
35
+
36
+ # Set the the current page.
37
+ # @param page_url [String] URL of the current page. This must either be
38
+ # nil or a URL in the predefined set.
39
+ def current_page=(page_url)
40
+ unless page_url
41
+ @current_view_url = nil
42
+ return
43
+ end
44
+
45
+ if (current = @views.find { |v| v.url == page_url })
46
+ @current_view_url = current.url
47
+ else
48
+ raise ArgumentError.new("#{page_url} is not a URL of a known view")
49
+ end
50
+ end
51
+
52
+ # Iterate over all buttons. A NavButtonDef object is passed to the block
53
+ # that contains the icon and URL for the button. If no URL is set, the
54
+ # button is inactive.
55
+ def each
56
+ @views.each do |view|
57
+ view = view.clone
58
+ if @current_view_url == view.url
59
+ view.url = nil
60
+ end
61
+ yield(view)
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = ViewFrame.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ module PostRunner
14
+
15
+ # Creates an HTML frame around the passed object or HTML block.
16
+ class ViewFrame
17
+
18
+ # Create a ViewFrame object.
19
+ # @param title [String] Title/heading of the framed box
20
+ # @param width [Fixnum or nil] Width of the frame. Use nil to set no
21
+ # width.
22
+ # @param content [Any object that respons to to_html] Object to frame
23
+ # @param &block [HTMLBuilder actions]
24
+ def initialize(title, width = 600, content = nil, &block)
25
+ @title = title
26
+ @content = content
27
+ @block = block
28
+ @width = width
29
+ end
30
+
31
+ # Generate the HTML code for the frame and the enclosing content.
32
+ # @param doc [HTMLBuilder] HTML document
33
+ def to_html(doc)
34
+ doc.unique(:viewframe_style) {
35
+ # Add the necessary style sheet snippets to the document head.
36
+ doc.head { doc.style(style) }
37
+ }
38
+
39
+ attr = { 'class' => 'widget_frame' }
40
+ attr['style'] = "width: #{@width}px" if @width
41
+ doc.div(attr) {
42
+ doc.div({ 'class' => 'widget_frame_title' }) {
43
+ doc.b(@title)
44
+ }
45
+ doc.div {
46
+ # The @content holds an object that must respond to to_html to
47
+ # generate the HTML code.
48
+ if @content
49
+ if @content.is_a?(Array)
50
+ @content.each { |c| c.to_html(doc) }
51
+ else
52
+ @content.to_html(doc)
53
+ end
54
+ end
55
+ # The block generates HTML code directly
56
+ @block.yield if @block
57
+ }
58
+ }
59
+ end
60
+
61
+ private
62
+
63
+ def style
64
+ <<EOT
65
+ .widget_frame {
66
+ box-sizing: border-box;
67
+ padding: 10px 15px 15px 15px;
68
+ margin: 15px auto 15px auto;
69
+ border: 1px solid #ddd;
70
+ background: #fff;
71
+ background: linear-gradient(#f6f6f6 0, #fff 50px);
72
+ background: -o-linear-gradient(#f6f6f6 0, #fff 50px);
73
+ background: -ms-linear-gradient(#f6f6f6 0, #fff 50px);
74
+ background: -moz-linear-gradient(#f6f6f6 0, #fff 50px);
75
+ background: -webkit-linear-gradient(#f6f6f6 0, #fff 50px);
76
+ box-shadow: 0 3px 10px rgba(0,0,0,0.15);
77
+ -o-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
78
+ -ms-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
79
+ -moz-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
80
+ -webkit-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
81
+ }
82
+ .widget_frame_title {
83
+ font-size:13pt;
84
+ padding-bottom: 5px;
85
+ text-align: left;
86
+ }
87
+ EOT
88
+ end
89
+
90
+ end
91
+
92
+ end
93
+