devlog 0.3.2 → 0.3.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2712d58a9f98c77851b3453e22dd929f4aa7eae6
4
- data.tar.gz: 30bfd02ebd5ad88eeef83084c15850b618bcaf21
2
+ SHA256:
3
+ metadata.gz: 152a77a9bf2759dee53158b75e850e5fa7eac445ffc96c1640f63994afa95657
4
+ data.tar.gz: fa39e2749400e54807d883f106e0a79371633f471d7ad0eb84d54254b4f586d8
5
5
  SHA512:
6
- metadata.gz: d3d76b2d648cdee3327ffcfdbca596a287bc38dc203800c3958f9121946daf7ee8bc39e7abc0a74e56009010ec8e512e08e1249725c6f3b590a4b60e632a6055
7
- data.tar.gz: 47e76d5297ebaeaeed0e130c9cc3b0a9426522d02565d620a248e7a3abbc7821f21a4b0dfcf49c06d6a2c41fe0aeaf68c3bcd18c6723642e63116ef825b3fec5
6
+ metadata.gz: 3240402228afcfe9dc9d8826f96b0a3e3579604e3d3ff139a66c9f8dc65562d03218ee66886c03fc468c1382b81b3d347f30a513c1a0e486f42f8f4d4b7c927f
7
+ data.tar.gz: '080462e56cd322f1af89edf7053ff912b8f9cc0a90dc4c36c2d35839a93abdcf45243b5af2dcb724a6f960e826b53312b362a1703ea6f79cd7f38830da184857'
data/README.md CHANGED
@@ -76,19 +76,33 @@ run in current folder and write out info.markdown, copy devlog to README.markdow
76
76
 
77
77
  `devlog saver`
78
78
 
79
+ write out a weekly timesheet for the current week, using a ERB template producing html + PDF:
80
+
81
+ `devlog w`
82
+
83
+ writing out the week before the current one (and so on):
84
+
85
+ `devlog w 1`
86
+
79
87
  settings
80
88
  ========
81
89
 
82
- currently only `devlog_file` can be configured. it represents the location of the devlog text file.
83
-
84
90
  the settings file is called `.devlog.yml`.
85
91
 
86
92
  it can be placed into a project folder from where one wants to be able to call `devlog`.
87
93
 
94
+ this way you can keep your devlog.markdown anywhere on disk.
95
+
96
+ `devlog_file` represents the location of the devlog text file.
97
+ `weekly_timesheet_template` represents the location of the ERB weekly timesheet template, if you don't provide one, there's a default.
98
+ `convert_to_pdf_command` represents the command used to convert the generated html into a signable PDF.
99
+
100
+ file paths should be relative to `.devlog.yml`.
101
+
88
102
  example settings `.devlog.yml`:
89
103
 
90
104
  ```
91
105
  devlog_file: ../info/devlog.markdown
106
+ weekly_timesheet_template: ../info/weekly_timesheet.erb.html
107
+ convert_to_pdf_command: wkhtmltopdf --dpi 400 --viewport-size 600x800 --orientation Landscape
92
108
  ```
93
-
94
- the file path should be relative to `.devlog.yml`.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.2
1
+ 0.3.3
data/bin/devlog CHANGED
@@ -31,11 +31,15 @@ exporting devlog into a book, which can be read top down, like normal books:
31
31
 
32
32
  #{'devlog'.green} x ~ exports into devlog.txt
33
33
 
34
+ reporting devlog as a timesheet:
35
+
36
+ #{'devlog'.green} w ~ export the current weekly timesheet into a html page and convert that into PDF
34
37
  EOF
35
38
 
36
39
  # arguments
37
40
  $:.unshift File.join(File.dirname(__FILE__))
38
41
  @in_file_or_cmd = ARGV[0]
42
+ @argument = ARGV[1] ? ARGV[1].to_i : 0
39
43
 
40
44
  def print_backtrace(exception)
41
45
  exception.backtrace.join("\n\t").to_s.blue
@@ -51,6 +55,7 @@ def parse_now(devlog_file = 'devlog.markdown', msg = '')
51
55
  puts t.validation_string
52
56
  puts t.to_info_string
53
57
  puts is_session_open(devlog_file) ? "\nSession is open...".yellow : "\nNo open session.".green
58
+ t
54
59
  end
55
60
 
56
61
  def export_now(devlog_file = 'devlog.markdown', msg = '')
@@ -72,6 +77,8 @@ def dodo
72
77
  print_usage
73
78
  elsif @in_file_or_cmd == 'x'
74
79
  export_now(default_devlog_file, "Exporting #{default_devlog_file}...".green)
80
+ elsif @in_file_or_cmd == 'w'
81
+ weekly_pdf(parse_now(default_devlog_file, "Parsing #{default_devlog_file}...".green), @argument)
75
82
  elsif @in_file_or_cmd == 'commit'
76
83
  `git commit -am 'devlog';git push`
77
84
  elsif @in_file_or_cmd == 'b'
data/devlog.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: devlog 0.3.2 ruby lib
5
+ # stub: devlog 0.3.3 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "devlog".freeze
9
- s.version = "0.3.2"
9
+ s.version = "0.3.3"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["mihael".freeze]
14
- s.date = "2018-06-01"
14
+ s.date = "2019-10-19"
15
15
  s.description = "devlog.markdown time&space extractor".freeze
16
16
  s.email = "kitschmaster@gmail.com".freeze
17
17
  s.executables = ["devlog".freeze]
@@ -43,6 +43,8 @@ Gem::Specification.new do |s|
43
43
  "sublime_text/devlog.tmbundle/Snippets/tu.tmSnippet",
44
44
  "sublime_text/devlog.tmbundle/info.plist",
45
45
  "sublime_text/tu.py",
46
+ "templates/background.jpg",
47
+ "templates/weekly_timesheet.erb.html",
46
48
  "test/devlog_file_test.rb",
47
49
  "test/devlog_settings_test.rb",
48
50
  "test/devlog_test.rb",
@@ -56,12 +58,13 @@ Gem::Specification.new do |s|
56
58
  "test/test_devlogs/test_settings.yml",
57
59
  "test/test_devlogs/test_single_devlog.markdown",
58
60
  "test/test_devlogs/test_stats_devlog.markdown",
61
+ "test/test_devlogs/test_weekly_devlog.markdown",
59
62
  "test/test_helper.rb",
60
63
  "tmp/.gitignore"
61
64
  ]
62
65
  s.homepage = "http://github.com/mihael/devlog".freeze
63
66
  s.licenses = ["MIT".freeze]
64
- s.rubygems_version = "2.5.2".freeze
67
+ s.rubygems_version = "3.0.6".freeze
65
68
  s.summary = "takes devlog.markdown and gives info".freeze
66
69
 
67
70
  if s.respond_to? :specification_version then
data/devlog.markdown CHANGED
@@ -1,3 +1,50 @@
1
+ #23.09.2019 23:08:08 CodingSession::END
2
+
3
+ some quick adjustments...
4
+
5
+ wkhtmltopdf does not work very well yet. it produces a huge canvas for some reason, making the actual table look miniature until zoomed in.
6
+ it's not a big issue, ii can open the generated html with safari and make an excellent pdf export.
7
+ but, why does it do it like that...
8
+
9
+ ahm, it seems to produce canvas sized as the current OS resolution, which then on this iMac becomes 5120x2880.
10
+
11
+ solved to a degree with: wkhtmltopdf --dpi 400 --viewport-size 600x800 --orientation Portrait
12
+
13
+ so now there's two more settings, a settings file might look like:
14
+
15
+ devlog_file: info/devlog.markdown
16
+ weekly_timesheet_template: info/weekly_timesheet.erb.html
17
+ convert_to_pdf_command: wkhtmltopdf --dpi 400 --viewport-size 600x800 --orientation Landscape
18
+
19
+ and that's it. will publish this as 0.3.3 if it turns out to work well.
20
+
21
+ #23.09.2019 19:39:39 CodingSession::BEGIN
22
+
23
+ #23.09.2019 01:04:21 CodingSession::END
24
+
25
+ took me some time to decide how to do this.
26
+
27
+ decided to generate a html from the pdf they gave.
28
+
29
+ that was easy, but turned out as rubbish, so ii did it manually.
30
+
31
+ then decided to populate that html with the data.
32
+
33
+ and then decided to use wkhtmltopdf command line utility to convert the html back to pdf.
34
+
35
+ have something, and it's configurable by devlogger. will need some more grind and polish.
36
+
37
+ #22.09.2019 19:05:17 CodingSession::BEGIN
38
+
39
+ #19.09.2019 23:34:08 CodingSession::END
40
+
41
+ adding something ii need for a dayjob. at end of period employer wants a timesheet filled out.
42
+ ii have no intent to do that manually ever again.
43
+
44
+ weekly daily report, ...
45
+
46
+ #19.09.2019 22:00:17 CodingSession::BEGIN
47
+
1
48
  #09.01.2018 23:38:01 CodingSession::END
2
49
 
3
50
  resolving a security issue reported by github. bumping nokogiri.
data/lib/devlog.rb CHANGED
@@ -226,7 +226,7 @@ module Devlog
226
226
  def save_info(devlog_file = 'devlog.markdown', info_file = 'info.markdown')
227
227
  info = parse_devlog_now(devlog_file)
228
228
  if info.has_info?
229
- File.open(File.join(File.dirname(devlog_file), info_file), 'w') {|f| f.write(info.to_info_string(short=true)) }
229
+ File.open(File.join(File.dirname(devlog_file), info_file), 'w') {|f| f.write(info.to_info_string(true)) }
230
230
  else
231
231
  puts "No info present.".red
232
232
  end
@@ -294,6 +294,127 @@ module Devlog
294
294
  devlog_export_file
295
295
  end
296
296
 
297
+ def weekly_pdf(tajm, weeks_from_now = 0, devlog_file = 'devlog.markdown')
298
+ require 'erb'
299
+ devlog_file = settings.devlog_file || devlog_file
300
+ template = settings.has?(:weekly_timesheet_template) ? settings.weekly_timesheet_template : File.join(Devlog.path, 'templates', 'weekly_timesheet.erb.html')
301
+ convert_command = settings.has?(:convert_to_pdf_command) ? settings.convert_to_pdf_command : 'wkhtmltopdf'
302
+ puts "Using weekly template: #{template} #{settings.has?(:weekly_timesheet_template)}".green
303
+
304
+ zezzions = tajm.zezzions_for_week(weeks_from_now, DateTime.current)
305
+
306
+ if zezzions.any?
307
+ file_id = zezzions.last.zzbegin.strftime("%Y-%m-%d")
308
+ pdf = File.join(File.dirname(devlog_file), "sevendays-#{file_id}.pdf")
309
+ html = File.join(File.dirname(devlog_file), "sevendays-#{file_id}.html")
310
+ @sevendays = Sevendays.new(zezzions)
311
+
312
+ renderer = ERB.new(File.read(template))
313
+
314
+ File.open(html,'w') {|f| f.write(renderer.result()) }
315
+
316
+ `#{convert_command} #{html} #{pdf}`
317
+ else
318
+ 'No sessions to render.'.red
319
+ end
320
+ end
321
+
322
+ module SevendaysTotal
323
+ def total_hours
324
+ all.inject(0) { |time, zezzion| time + zezzion.session_time }.round(2)
325
+ end
326
+
327
+ def total_hours_string
328
+ total = total_hours
329
+
330
+ return "" if total <= 0
331
+
332
+ "#{total}h"
333
+ end
334
+ end
335
+
336
+ class Day
337
+ attr_accessor :all
338
+ include SevendaysTotal
339
+
340
+ def initialize(day, zezzions)
341
+ @all = zezzions.sort # sorting by default by zzbegin
342
+ @day = Sevendays::DAYS.include?(day) ? day : Sevendays::RANDOMDAY
343
+ end
344
+
345
+ def name
346
+ @day
347
+ end
348
+
349
+ def any?
350
+ all.any?
351
+ end
352
+
353
+ def begins_at
354
+ return '' unless any?
355
+ all.first.zzbegin.strftime('%H:%M')
356
+ end
357
+
358
+ def ends_at
359
+ return '' unless any?
360
+ all.last.zzend.strftime("%H:%M")
361
+ end
362
+
363
+ def breaks_at
364
+ return '' unless any?
365
+
366
+ size = all.size
367
+
368
+ return "" if size < 2
369
+
370
+ breaks = []
371
+ first = true
372
+ last = nil
373
+
374
+ all.each do |zezzion|
375
+ if first
376
+ last = zezzion
377
+ first = false
378
+ else
379
+ breaks << "#{last.zzend.strftime('%H:%M')} -> #{zezzion.zzbegin.strftime('%H:%M')}"
380
+ last = zezzion
381
+ end
382
+ end
383
+
384
+ breaks.join(', ')
385
+ end
386
+ end
387
+
388
+ class Sevendays
389
+ attr_accessor :all
390
+ include Devlog::SevendaysTotal
391
+
392
+ DAYS = %i(monday tuesday wednesday thursday friday saturday sunday).freeze
393
+ RANDOMDAY = 'Random'.freeze
394
+
395
+ def initialize(zezzions)
396
+ @all = zezzions.sort
397
+ end
398
+
399
+ def begins_at
400
+ all.first.zzbegin.strftime("%Y/%m/%d")
401
+ end
402
+
403
+ def date
404
+ DateTime.current.strftime("%Y/%m/%d")
405
+ end
406
+
407
+ DAYS.each do |day|
408
+ attr_accessor day
409
+
410
+ define_method(day) do
411
+ value = Day.new(day, all.select { |zezzion| zezzion.zzbegin.send("#{day.to_s}?") } )
412
+ instance_variable_set("@__#{day.to_s}", value) unless instance_variable_get("@__#{day.to_s}")&.any?
413
+ instance_variable_get("@__#{day.to_s}")
414
+ end
415
+ end
416
+ end
417
+
297
418
  # The parsing object
298
419
  class Parsing
299
420
  # this is the total time, but each session has these same params
@@ -379,14 +500,37 @@ module Devlog
379
500
  (coding_session_time + com_session_time + payed_time).round(2)
380
501
  end
381
502
 
382
- # return hours worked for the last X days, from beginTime
383
- def hours_for_last(days, beginTime = DateTime.now)
384
- endTime = beginTime.to_time - days.days
385
- selected_zezzions = @zezzions.select { |z| z.zzbegin.to_time < beginTime && z.zzend >= endTime }
386
- # puts("Selected sessons from #{beginTime} to #{endTime}: #{selected_zezzions.size}")
503
+ # return hours worked for the last X days, from current_time
504
+ def hours_for_last(days, current_time = DateTime.now)
505
+ endTime = current_time.to_time - days.days
506
+ selected_zezzions = @zezzions.select { |z| z.zzbegin.to_time < current_time && z.zzend >= endTime }
507
+ #puts("Selected sessons from #{current_time} to #{endTime}: #{selected_zezzions.size}")
387
508
  selected_zezzions.inject(0) { |time, z| time + z.session_time }.round(2)
388
509
  end
389
510
 
511
+ # from time to time select some zezzions
512
+ def select_zezzions(from_time, to_time)
513
+ @zezzions.select { |z| z.zzbegin.to_time > from_time && z.zzend.to_time <= to_time }
514
+ end
515
+
516
+ # returns zezzions recorded during beginning of week and end of week
517
+ # fromnow - how many weeks into the past
518
+ def zezzions_for_week(fromnow = 0, current_time = DateTime.current)
519
+ moment = current_time - (7 * fromnow).days
520
+ begin_time = moment.beginning_of_week
521
+ end_time = moment.end_of_week
522
+
523
+ select_zezzions(begin_time, end_time)
524
+ end
525
+
526
+ def zezzions_for_month(fromnow = 0, current_time = DateTime.current_time)
527
+ moment = current_time - (fromnow).months
528
+ begin_time = moment.beginning_of_month
529
+ end_time = moment.end_of_month
530
+
531
+ select_zezzions(begin_time, end_time)
532
+ end
533
+
390
534
  def longest_session
391
535
  @zezzions.max_by(&:session_time)
392
536
  end
@@ -463,6 +607,26 @@ module Devlog
463
607
  s << ("Longest Session = #{self.longest_session.to_s}\n")
464
608
  s << ("Shortest Session = #{self.shortest_session.to_s}\n")
465
609
  s << ("Last Session = #{self.devlog_end.ago_in_words}, duration: #{self.last_session.session_time.round(3)} [h]")
610
+ s << ("\n")
611
+ s << ("Weekly Sessions\n")
612
+ s << ("\n")
613
+ sevendays = Sevendays.new(zezzions_for_week)
614
+ sevendays_total = 0
615
+ Sevendays::DAYS.each do |day|
616
+ current_day = sevendays.send(day.to_sym)
617
+ dayname = day.upcase
618
+ if current_day.any?
619
+ current_day_total_hours = current_day.total_hours
620
+ sevendays_total += current_day_total_hours
621
+ s << ("#{dayname.upcase}\n")
622
+ s << ("begins at: #{current_day.begins_at}\n")
623
+ s << ("breaks: #{current_day.breaks_at}\n")
624
+ s << ("end_at: #{current_day.ends_at}\n")
625
+ s << ("sum: #{current_day_total_hours}\n")
626
+ s << ("\n")
627
+ end
628
+ end
629
+ s << ("Weekly sessions total: #{sevendays_total}\n")
466
630
  end
467
631
  s
468
632
  end
@@ -486,6 +650,8 @@ module Devlog
486
650
  end
487
651
 
488
652
  class Zezzion
653
+ include Comparable
654
+
489
655
  COM = 1 # communication session
490
656
  COD = 0 # coding session
491
657
  attr_accessor :zzbegin, :zzend, :zzbegin_title, :zzend_title, :zztype
@@ -506,6 +672,10 @@ module Devlog
506
672
  @zzend_line_number = 0
507
673
  end
508
674
 
675
+ def <=>(other)
676
+ zzbegin <=> other.zzbegin
677
+ end
678
+
509
679
  # in seconds
510
680
  def time
511
681
  @zzend.to_time - @zzbegin.to_time
@@ -516,6 +686,7 @@ module Devlog
516
686
  min = self.time / 60
517
687
  hours = min / 60
518
688
  days = hours / 24
689
+ days
519
690
  end
520
691
 
521
692
  # the whole coding session time
@@ -8,6 +8,10 @@ module Devlog
8
8
  # Allow settings.key besides settings[:key]
9
9
  # If the method name exists as a key within this Hash, fetch it.
10
10
  class Settings < Hash
11
+ def has?(m)
12
+ return key?(m) || key?(m.to_s)
13
+ end
14
+
11
15
  def method_missing(m, *args, &block)
12
16
  if key?(m)
13
17
  fetch m
@@ -29,7 +33,7 @@ module Devlog
29
33
  end
30
34
 
31
35
  def settings
32
- @settings
36
+ @settings ||= Settings.new
33
37
  end
34
38
 
35
39
  # The default is the current folder with devlog.markdown in it.
@@ -37,9 +41,9 @@ module Devlog
37
41
 
38
42
  # Calculate a devlog_file path.
39
43
  def devlog_file_setting
40
- return DEVLOG_FILE unless @settings
41
- devlog_file_setting = @settings['devlog_file']
42
- if devlog_file_setting && File.exists?(File.join(Dir.pwd, devlog_file_setting))
44
+ return DEVLOG_FILE unless settings
45
+ devlog_file_setting = settings['devlog_file']
46
+ if devlog_file_setting && File.exist?(File.join(Dir.pwd, devlog_file_setting))
43
47
  devlog_file_setting
44
48
  else
45
49
  DEVLOG_FILE
Binary file
@@ -0,0 +1,71 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head><meta http-equiv=Content-Type content="text/html; charset=UTF-8">
4
+ <style type="text/css">
5
+ <!--
6
+ span.cls_005{font-family:Arial,serif;font-size:10.1px;color:rgb(118,112,113);font-weight:normal;font-style:normal;text-decoration: none}
7
+ div.cls_005{font-family:Arial,serif;font-size:10.1px;color:rgb(118,112,113);font-weight:normal;font-style:normal;text-decoration: none}
8
+ span.cls_003{font-family:Arial,serif;font-size:11.1px;color:rgb(118,112,113);font-weight:bold;font-style:normal;text-decoration: none}
9
+ div.cls_003{font-family:Arial,serif;font-size:11.1px;color:rgb(118,112,113);font-weight:bold;font-style:normal;text-decoration: none}
10
+ span.cls_006{font-family:Arial,serif;font-size:11.1px;color:rgb(118,112,113);font-weight:normal;font-style:normal;text-decoration: none}
11
+ div.cls_006{font-family:Arial,serif;font-size:11.1px;color:rgb(118,112,113);font-weight:normal;font-style:normal;text-decoration: none}
12
+ -->
13
+
14
+ .time {
15
+ font-family:Arial,serif;font-size:8px;color:rgb(118,112,113);font-weight:bold;font-style:normal;text-decoration: none
16
+ }
17
+ </style>
18
+ </head>
19
+ <body style="width:900px;">
20
+ <div style="position:absolute;left:50%;margin-left:-420px;top:0px;width:841px;height:595px;overflow:hidden">
21
+ <div style="position:absolute;left:0px;top:0px">
22
+ <img src="background.jpg" width=841 height=589></div>
23
+ <div style="position:absolute;left:441.59px;top:158.60px" class="cls_005"><span class="cls_005">Clients Name</span></div>
24
+ <div style="position:absolute;left:441.59px;top:173.71px" class="cls_005"><span class="cls_005">Contract Number</span></div>
25
+ <div style="position:absolute;left:441.59px;top:189.07px" class="cls_005"><span class="cls_005">Consultancy Company Name</span></div>
26
+ <div style="position:absolute;left:53.51px;top:191.72px" class="cls_003"><span class="cls_003">WEEK COMMENCING</span></div>
27
+ <div style="position:absolute;left:225px;top:193.72px" class="cls_006"><span class="time week-comencing"><%= @sevendays.begins_at %></span></div>
28
+
29
+
30
+ <div style="position:absolute;left:441.59px;top:204.19px" class="cls_005"><span class="cls_005">Consultants Name</span></div>
31
+
32
+
33
+ <!-- The weekly timesheet table -->
34
+ <div style="position:absolute;left:54.71px;top:234.44px" class="cls_003"><span class="cls_003">DAY</span></div>
35
+ <div style="position:absolute;left:146.39px;top:234.44px" class="cls_003"><span class="cls_003">START TIME</span></div>
36
+ <div style="position:absolute;left:252.71px;top:234.44px" class="cls_003"><span class="cls_003">BREAK/S START & FINISH</span></div>
37
+ <div style="position:absolute;left:578.87px;top:234.44px" class="cls_003"><span class="cls_003">END TIME</span></div>
38
+ <div style="position:absolute;left:685.19px;top:234.44px" class="cls_003"><span class="cls_003">TOTAL HOURS</span></div>
39
+
40
+ <% top = 251 %>
41
+ <% %w[monday tuesday wednesday thursday friday saturday sunday].each do |day| %>
42
+ <% current_day = @sevendays.send(day.to_sym) %>
43
+ <% dayname = day.upcase %>
44
+ <div style="position:absolute;left:54.71px;top:<%= top.to_s %>px" class="cls_006"><span class="cls_006"><%= dayname %></span></div>
45
+ <div style="position:absolute;left:146.39px;top:<%= top.to_s %>px" class="cls_006"><span class="time <%= day %> start-time"><%= current_day.begins_at %></span></div>
46
+ <div style="position:absolute;left:252.7px;top:<%= top.to_s %>px" class="cls_006"><span class="time <%= day %> breaks"><%= current_day.breaks_at %></span></div>
47
+ <div style="position:absolute;left:578.8px;top:<%= top.to_s %>px" class="cls_006"><span class="time <%= day %> end-time"><%= current_day.ends_at %></span></div>
48
+ <div style="position:absolute;left:685.19px;top:<%= top.to_s %>px" class="cls_006"><span class="time <%= day %> total-hours"><%= current_day.total_hours %></span></div>
49
+ <% top += 16 %>
50
+ <%end%>
51
+
52
+ <div style="position:absolute;left:55.43px;top:380.83px" class="cls_006"><span class="cls_006">Notes Regarding Overtime or Expenses:</span></div>
53
+ <div style="position:absolute;left:60.43px;top:410.83px" class="cls_006"><span class="cls_006"><%= @sevendays.total_hours_string %></span></div>
54
+
55
+ <div style="position:absolute;left:54.71px;top:450.43px" class="cls_006"><span class="cls_006">Signed by Consultant</span></div>
56
+ <div style="position:absolute;left:200.71px;top:450.43px" class="cls_006"><span class="cls_006"></span></div>
57
+
58
+ <div style="position:absolute;left:467.03px;top:451.88px" class="cls_006"><span class="cls_006">Signed by Client</span></div>
59
+ <div style="position:absolute;left:54.71px;top:468.67px" class="cls_006"><span class="cls_006">Print Name</span></div>
60
+ <div style="position:absolute;left:200.71px;top:468.67px" class="cls_006"><span class="cls_006"></span></div>
61
+
62
+ <div style="position:absolute;left:467.03px;top:471.32px" class="cls_006"><span class="cls_006">Job Title</span></div>
63
+ <div style="position:absolute;left:54.71px;top:488.83px" class="cls_006"><span class="cls_006">Date</span></div>
64
+ <div style="position:absolute;left:200px;top:488.83px" class="cls_006"><span class="date"><%= @sevendays.date %></span></div>
65
+ <div style="position:absolute;left:467.03px;top:491.71px" class="cls_006"><span class="cls_006">Print Name</span></div>
66
+ <div style="position:absolute;left:467.03px;top:511.16px" class="cls_006"><span class="cls_006">Date</span></div>
67
+ </div>
68
+ </body>
69
+ </html>
70
+
71
+
data/test/devlog_test.rb CHANGED
@@ -189,7 +189,7 @@ class DevlogTest < Test::Unit::TestCase
189
189
 
190
190
  def test_devlog_export
191
191
  @exported_devlog = export_devlog_now(File.join(File.dirname(__FILE__), TEST_FILES_PATH, 'test_devlog_export.markdown'))
192
- assert(File.exists?(@exported_devlog))
192
+ assert(File.exist?(@exported_devlog))
193
193
  assert(File.size(@exported_devlog)>0, "file should not be empty")
194
194
  File.open(@exported_devlog, "r") do |f|
195
195
  first = f.readline
@@ -207,4 +207,48 @@ class DevlogTest < Test::Unit::TestCase
207
207
  def test_default_devlog_file_setting
208
208
  assert(devlog_file_setting == 'devlog.markdown', 'should return default')
209
209
  end
210
+
211
+ def test_zezzions_for_week
212
+ load_devlog_weekly
213
+ assert(@tajm_weekly.devlog_sessions.size==15, "should be 15, but is #{@tajm_weekly.devlog_sessions.size}")
214
+
215
+ zezzions = @tajm_weekly.zezzions_for_week(0, DateTime.new(2019, 9, 11, 18, 0, 0))
216
+
217
+ assert(zezzions.size == 4, 'should be 4 but is not')
218
+
219
+ zezzions = @tajm_weekly.zezzions_for_week(1, DateTime.new(2019, 9, 11, 18, 0, 0))
220
+
221
+ assert(zezzions.size == 10, "should be 10 but is #{zezzions.size}")
222
+
223
+ zezzions = @tajm_weekly.zezzions_for_week(2, DateTime.new(2019, 9, 11, 18, 0, 0))
224
+
225
+ assert(zezzions.size == 1, "should be 1 but is #{zezzions.size}")
226
+
227
+ zezzions = @tajm_weekly.zezzions_for_week(0, DateTime.new(2019, 9, 6, 23, 0, 0))
228
+
229
+ assert(zezzions.size == 10, "should be 10 but is #{zezzions.size}")
230
+ end
231
+
232
+ def test_weekly_timesheet_html_generation
233
+ load_devlog_weekly
234
+
235
+ @sevendays = Sevendays.new(@tajm_weekly.zezzions_for_week(0, DateTime.new(2019, 9, 6, 23, 0, 0)))
236
+
237
+ assert(@sevendays.monday.begins_at == "08:00", "monday should begin at 08:00 but begins at #{@sevendays.monday.begins_at}")
238
+ assert(@sevendays.monday.ends_at == "16:00", "monday should end at 16:00 but ends at #{@sevendays.monday.ends_at}")
239
+
240
+ assert(@sevendays.tuesday.begins_at == "08:00", "tuesday should begin at 08:00 but begins at #{@sevendays.tuesday.begins_at}")
241
+ assert(@sevendays.tuesday.ends_at == "22:00", "tuesday should end at 22:00 but ends at #{@sevendays.tuesday.ends_at}")
242
+
243
+ assert(@sevendays.friday.begins_at == "08:00", "friday should begin at 08:00 but begins at #{@sevendays.friday.begins_at}")
244
+ assert(@sevendays.friday.ends_at == "18:00", "friday should end at 18:00 but ends at #{@sevendays.friday.ends_at}")
245
+
246
+ assert(@sevendays.begins_at == "2019/09/02", "seven days should begin on 2019/09/02 but beings on #{@sevendays.begins_at}")
247
+
248
+ assert(@sevendays.sunday.breaks_at == "", "no breaks on sunday but is: #{@sevendays.sunday.breaks_at}")
249
+
250
+ assert(@sevendays.friday.breaks_at == "12:00 -> 14:00", "one break on friday but is: #{@sevendays.friday.breaks_at}")
251
+
252
+ assert(@sevendays.tuesday.breaks_at == "12:00 -> 13:00, 15:00 -> 20:00", "two breaks on tuesday but is: #{@sevendays.tuesday.breaks_at}")
253
+ end
210
254
  end
@@ -0,0 +1,89 @@
1
+ #11.09.2019 17:00:00 CodingSession::END
2
+
3
+ Wednesday
4
+
5
+ #11.09.2019 13:00:00 CodingSession::BEGIN
6
+
7
+ #11.09.2019 12:00:00 CodingSession::END
8
+
9
+ Wednesday
10
+
11
+ #11.09.2019 08:00:00 CodingSession::BEGIN
12
+
13
+ #10.09.2019 16:00:00 CodingSession::END
14
+
15
+ Tuesday
16
+
17
+ #10.09.2019 08:00:00 CodingSession::BEGIN
18
+
19
+ #09.09.2019 16:00:00 CodingSession::END
20
+
21
+ Monday
22
+
23
+ #09.09.2019 08:00:00 CodingSession::BEGIN
24
+
25
+ #08.09.2019 16:00:00 CodingSession::END
26
+
27
+ Sunday
28
+
29
+ #08.09.2019 08:00:00 CodingSession::BEGIN
30
+
31
+ #07.09.2019 16:00:00 CodingSession::END
32
+
33
+ Saturday
34
+
35
+ #07.09.2019 08:00:00 CodingSession::BEGIN
36
+
37
+ #06.09.2019 18:00:00 CodingSession::END
38
+
39
+ Friday
40
+
41
+ #06.09.2019 14:00:00 CodingSession::BEGIN
42
+
43
+ #06.09.2019 12:00:00 CodingSession::END
44
+
45
+ Friday
46
+
47
+ #06.09.2019 08:00:00 CodingSession::BEGIN
48
+
49
+ #05.09.2019 16:00:00 CodingSession::END
50
+
51
+ Thursday
52
+
53
+ #05.09.2019 08:00:00 CodingSession::BEGIN
54
+
55
+ #04.09.2019 16:00:00 CodingSession::END
56
+
57
+ Wednesday
58
+
59
+ #04.09.2019 08:00:00 CodingSession::BEGIN
60
+
61
+ #03.09.2019 22:00:00 CodingSession::END
62
+
63
+ Tuesday 3
64
+
65
+ #03.09.2019 20:00:00 CodingSession::BEGIN
66
+
67
+ #03.09.2019 15:00:00 CodingSession::END
68
+
69
+ Tuesday 2
70
+
71
+ #03.09.2019 13:00:00 CodingSession::BEGIN
72
+
73
+ #03.09.2019 12:00:00 CodingSession::END
74
+
75
+ Tuesday 1
76
+
77
+ #03.09.2019 08:00:00 CodingSession::BEGIN
78
+
79
+ #02.09.2019 16:00:00 CodingSession::END
80
+
81
+ Monday
82
+
83
+ #02.09.2019 08:00:00 CodingSession::BEGIN
84
+
85
+ #01.09.2019 16:00:00 CodingSession::END
86
+
87
+ Sunday
88
+
89
+ #01.09.2019 08:00:00 CodingSession::BEGIN
data/test/test_helper.rb CHANGED
@@ -12,6 +12,10 @@ end
12
12
  TEST_FILES_PATH = 'test_devlogs'.freeze
13
13
  TEMP_PATH = '../tmp'.freeze
14
14
 
15
+ def parse_test_devlog(filename)
16
+ parse_devlog_now(File.join(File.dirname(__FILE__), TEST_FILES_PATH, filename))
17
+ end
18
+
15
19
  def load_devlog
16
20
  @tajm = parse_devlog_now(File.join(File.dirname(__FILE__), '..', 'devlog.markdown'))
17
21
  puts "#{@tajm.coding_session_time} #{@tajm.com_session_time} #{@tajm.payed_time}"
@@ -29,7 +33,7 @@ def load_devlog_now
29
33
  end
30
34
 
31
35
  def load_devlog_test
32
- @tajm_test = parse_devlog_now(File.join(File.dirname(__FILE__), TEST_FILES_PATH, 'test_devlog.markdown'))
36
+ @tajm_test = parse_test_devlog('test_devlog.markdown')
33
37
  puts "#{@tajm_test.coding_session_time} #{@tajm_test.com_session_time} #{@tajm_test.payed_time}"
34
38
  assert(@tajm_test.coding_session_time>0, "truth")
35
39
  assert(@tajm_test.com_session_time>0, "love")
@@ -37,13 +41,17 @@ def load_devlog_test
37
41
  end
38
42
 
39
43
  def load_devlog_stat
40
- @tajm_stat = parse_devlog_now(File.join(File.dirname(__FILE__), TEST_FILES_PATH, 'test_stats_devlog.markdown'))
44
+ @tajm_stat = parse_test_devlog('test_stats_devlog.markdown')
41
45
  end
42
46
 
43
47
  def load_devlog_single
44
- @tajm_single = parse_devlog_now(File.join(File.dirname(__FILE__), TEST_FILES_PATH, 'test_single_devlog.markdown'))
48
+ @tajm_single = parse_test_devlog('test_single_devlog.markdown')
45
49
  end
46
50
 
47
51
  def load_devlog_negative
48
- @tajm_negative = parse_devlog_now(File.join(File.dirname(__FILE__), TEST_FILES_PATH, 'test_negative_devlog.markdown'))
52
+ @tajm_negative = parse_test_devlog('test_negative_devlog.markdown')
53
+ end
54
+
55
+ def load_devlog_weekly
56
+ @tajm_weekly = parse_test_devlog('test_weekly_devlog.markdown')
49
57
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devlog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - mihael
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-01 00:00:00.000000000 Z
11
+ date: 2019-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -98,6 +98,8 @@ files:
98
98
  - sublime_text/devlog.tmbundle/Snippets/tu.tmSnippet
99
99
  - sublime_text/devlog.tmbundle/info.plist
100
100
  - sublime_text/tu.py
101
+ - templates/background.jpg
102
+ - templates/weekly_timesheet.erb.html
101
103
  - test/devlog_file_test.rb
102
104
  - test/devlog_settings_test.rb
103
105
  - test/devlog_test.rb
@@ -111,6 +113,7 @@ files:
111
113
  - test/test_devlogs/test_settings.yml
112
114
  - test/test_devlogs/test_single_devlog.markdown
113
115
  - test/test_devlogs/test_stats_devlog.markdown
116
+ - test/test_devlogs/test_weekly_devlog.markdown
114
117
  - test/test_helper.rb
115
118
  - tmp/.gitignore
116
119
  homepage: http://github.com/mihael/devlog
@@ -132,8 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
135
  - !ruby/object:Gem::Version
133
136
  version: '0'
134
137
  requirements: []
135
- rubyforge_project:
136
- rubygems_version: 2.5.2
138
+ rubygems_version: 3.0.6
137
139
  signing_key:
138
140
  specification_version: 4
139
141
  summary: takes devlog.markdown and gives info