postrunner 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+