evertils 0.3.14.1 → 0.3.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/evertils/base.rb +7 -0
- data/lib/evertils/controllers/generate.rb +2 -0
- data/lib/evertils/helpers/api-enml-handler.rb +45 -1
- data/lib/evertils/helpers/xml.rb +68 -0
- data/lib/evertils/type.rb +48 -4
- data/lib/evertils/types/daily.rb +10 -33
- data/lib/evertils/types/monthly.rb +37 -3
- data/lib/evertils/types/priority-queue.rb +15 -67
- data/lib/evertils/types/weekly.rb +34 -0
- data/lib/evertils/version.rb +1 -1
- data/lib/evertils.rb +1 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 390570a1abaf99659566485a2a510eb04420bd9f
|
4
|
+
data.tar.gz: ab267ee4d649934d9c14f65190fb7141dceb5efc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 465c395234e693c2d2629a2fec71a2aed62ef54c4b30894dc921840604e057a470fb5c323f2b2421703b5a811f70c108e17e4bae25bd7409f28c39db1ab06af2
|
7
|
+
data.tar.gz: 58eaa1cebdf34080a4297eeab8d910919080e1340bffef65db988c33f80f59d05dc0bbc9887ee618c1cce4918b7346ac26f3101f44926e14f3b108e1688d4db1
|
@@ -17,12 +17,14 @@ module Evertils
|
|
17
17
|
def weekly
|
18
18
|
note = Type::Weekly.new(@config)
|
19
19
|
note.create if note.should_create?
|
20
|
+
note.add_daily_note_link
|
20
21
|
end
|
21
22
|
|
22
23
|
# generate monthly notes
|
23
24
|
def monthly
|
24
25
|
note = Type::Monthly.new(@config)
|
25
26
|
note.create if note.should_create?
|
27
|
+
note.add_weekly_note_link
|
26
28
|
end
|
27
29
|
|
28
30
|
# generate monthly task summary templates
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Evertils
|
2
2
|
module Helper
|
3
3
|
class ApiEnmlHandler
|
4
|
+
include Nokogiri::XML
|
5
|
+
|
4
6
|
#
|
5
7
|
# @since 0.3.7
|
6
8
|
def initialize(config = nil)
|
@@ -11,7 +13,13 @@ module Evertils
|
|
11
13
|
#
|
12
14
|
# @since 0.3.13
|
13
15
|
def from_str(str)
|
14
|
-
|
16
|
+
str.sub!("\n", '')
|
17
|
+
@xml = DocumentFragment.parse(str) do |conf|
|
18
|
+
conf.noblanks
|
19
|
+
end
|
20
|
+
|
21
|
+
fix_dtd
|
22
|
+
clear_empty
|
15
23
|
end
|
16
24
|
|
17
25
|
#
|
@@ -36,11 +44,47 @@ module Evertils
|
|
36
44
|
note_xml.inner_html.to_s
|
37
45
|
end
|
38
46
|
|
47
|
+
#
|
48
|
+
# @since 0.3.15
|
49
|
+
def clear_empty
|
50
|
+
@xml.css('div').each do |node|
|
51
|
+
children = node.children
|
52
|
+
|
53
|
+
if children.size == 1 && children.first.is_a?(Nokogiri::XML::Text)
|
54
|
+
node.remove if node.text.strip == ''
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
@xml
|
59
|
+
end
|
60
|
+
|
61
|
+
# Sometimes, the Doctype declaration gets borked by the XML parser
|
62
|
+
# lets replace it with a new DTD if that is the case
|
63
|
+
# @since 0.3.15
|
64
|
+
def fix_dtd
|
65
|
+
if @xml.children[1].is_a?(Text)
|
66
|
+
# remove the existing broken DTD
|
67
|
+
@xml.children[1].remove
|
68
|
+
# create a new one (note: output is overridden in DTD class defined
|
69
|
+
# below ApiEnmlHandler)
|
70
|
+
dtd = DTD.new('DOCTYPE', @xml)
|
71
|
+
|
72
|
+
@xml.children.first.after(dtd)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
39
76
|
#
|
40
77
|
# @since 0.3.1
|
41
78
|
def to_enml(hash)
|
42
79
|
Evertils::Helper::EvernoteENML.with_list(hash)
|
43
80
|
end
|
44
81
|
end
|
82
|
+
|
83
|
+
# gross hack to get around nokogiri failing to parse the DTD
|
84
|
+
class DTD < Nokogiri::XML::DTD
|
85
|
+
def to_s
|
86
|
+
return "\n<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n"
|
87
|
+
end
|
88
|
+
end
|
45
89
|
end
|
46
90
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Evertils
|
2
|
+
module Helper
|
3
|
+
class Xml < Base
|
4
|
+
attr_accessor :doc
|
5
|
+
|
6
|
+
#
|
7
|
+
# @since 0.3.15
|
8
|
+
def initialize(doc)
|
9
|
+
raise ArgumentError, "doc param required" unless doc
|
10
|
+
|
11
|
+
@doc = doc.first
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# @since 0.3.15
|
16
|
+
def a(link, content)
|
17
|
+
conf = {
|
18
|
+
href: link,
|
19
|
+
content: content
|
20
|
+
}
|
21
|
+
|
22
|
+
create(:a, conf)
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# @since 0.3.15
|
27
|
+
def br
|
28
|
+
create(:br)
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# @since 0.3.15
|
33
|
+
def li(*children)
|
34
|
+
el = create(:li)
|
35
|
+
children.each { |child| el.add_child(child) }
|
36
|
+
el
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# @since 0.3.15
|
41
|
+
def div(*children)
|
42
|
+
el = create(:div)
|
43
|
+
children.each { |child| el.add_child(child) }
|
44
|
+
el
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# @since 0.3.15
|
49
|
+
def create(element, conf = {})
|
50
|
+
el = Nokogiri::XML::Node.new(element.to_s, @doc)
|
51
|
+
|
52
|
+
return el if conf.empty?
|
53
|
+
|
54
|
+
conf.each_pair do |k, v|
|
55
|
+
if el.respond_to? "#{k}="
|
56
|
+
el.send("#{k}=", v)
|
57
|
+
elsif el.respond_to? k
|
58
|
+
el.send(k, v)
|
59
|
+
else
|
60
|
+
el[k] = v
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
el
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/evertils/type.rb
CHANGED
@@ -4,13 +4,17 @@ module Evertils
|
|
4
4
|
attr_reader :title, :content, :notebook
|
5
5
|
|
6
6
|
COLOUR = 0xffffff
|
7
|
+
MAX_SEARCH_SIZE = 21
|
7
8
|
|
8
9
|
#
|
9
10
|
# @since 0.3.7
|
10
11
|
def initialize(config, *args)
|
11
12
|
@model = Evertils::Common::Query::Simple.new
|
13
|
+
@user = @model.user_info[:user]
|
14
|
+
@shard = @model.user_info[:shard]
|
12
15
|
@format = Evertils::Helper.load('Formatting')
|
13
16
|
@config = config if config
|
17
|
+
@api = Evertils::Helper.load('ApiEnmlHandler', @config)
|
14
18
|
@args = args unless args.size.zero?
|
15
19
|
end
|
16
20
|
|
@@ -19,7 +23,7 @@ module Evertils
|
|
19
23
|
def create
|
20
24
|
data = {
|
21
25
|
title: @title,
|
22
|
-
body: @content,
|
26
|
+
body: @content.delete!("\n"),
|
23
27
|
parent_notebook: self.class::NOTEBOOK,
|
24
28
|
tags: tags || [],
|
25
29
|
colour: self.class::COLOUR
|
@@ -35,14 +39,54 @@ module Evertils
|
|
35
39
|
#
|
36
40
|
# @since 0.3.7
|
37
41
|
def should_create?
|
38
|
-
|
39
|
-
|
40
|
-
result =
|
42
|
+
@note = find_note(self.class::NOTEBOOK)
|
43
|
+
@entity = @note.entity
|
44
|
+
result = @note.nil?
|
41
45
|
|
42
46
|
Notify.warning "#{self.class.name} skipped, note already exists" unless result
|
43
47
|
|
44
48
|
result
|
45
49
|
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# @since 0.3.15
|
53
|
+
def morning_note?
|
54
|
+
!caller.grep(/morning/).nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# @since 0.3.15
|
59
|
+
def wait_for(notebook)
|
60
|
+
Notify.info('Waiting for...')
|
61
|
+
note = find_note(notebook)
|
62
|
+
|
63
|
+
# didn't find it the first time? wait and try again
|
64
|
+
if note.entity.nil?
|
65
|
+
(1..MAX_SEARCH_SIZE).each do |iter|
|
66
|
+
Notify.info(" (#{iter}) #{note_title}")
|
67
|
+
note = find_note(notebook, true)
|
68
|
+
break unless note.entity.nil?
|
69
|
+
end
|
70
|
+
|
71
|
+
Notify.info("#{iter} attempts to find #{notebook} note") unless iter.zero?
|
72
|
+
end
|
73
|
+
|
74
|
+
note
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# @since 0.3.15
|
79
|
+
def find_note(notebook, sleep = false)
|
80
|
+
sleep(5) if sleep
|
81
|
+
title = @format.date_templates[notebook]
|
82
|
+
@model.find_note_contents(title)
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# @since 0.3.15
|
87
|
+
def internal_url_for(note)
|
88
|
+
"evernote:///view/#{@user[:id]}/#{@shard}/#{note.guid}/#{note.guid}/"
|
89
|
+
end
|
46
90
|
end
|
47
91
|
end
|
48
92
|
end
|
data/lib/evertils/types/daily.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
require 'evertils/helpers/xml'
|
2
|
+
|
1
3
|
module Evertils
|
2
4
|
module Type
|
3
5
|
class Daily < Type::Base
|
4
6
|
NOTEBOOK = :Daily
|
5
7
|
COLOUR = 0xffe8b7
|
6
|
-
MAX_SEARCH_SIZE = 21
|
7
8
|
|
8
9
|
#
|
9
10
|
# @since 0.3.7
|
@@ -24,12 +25,6 @@ module Evertils
|
|
24
25
|
|
25
26
|
private
|
26
27
|
|
27
|
-
#
|
28
|
-
# @since 0.3.13
|
29
|
-
def morning_note?
|
30
|
-
!caller.grep(/morning/).nil?
|
31
|
-
end
|
32
|
-
|
33
28
|
#
|
34
29
|
# TODO: refactor
|
35
30
|
# @since 0.3.13
|
@@ -37,39 +32,21 @@ module Evertils
|
|
37
32
|
@api = Evertils::Helper.load('ApiEnmlHandler', @config)
|
38
33
|
enml = @api.from_str(@format.template_contents(NOTEBOOK))
|
39
34
|
|
40
|
-
|
41
|
-
pq = find_priority_queue
|
42
|
-
|
43
|
-
# didn't find the note the first time? wait and try again
|
44
|
-
if pq.entity.nil?
|
45
|
-
iter = 1
|
46
|
-
loop do
|
47
|
-
iter += 1
|
48
|
-
pq = find_priority_queue(true)
|
49
|
-
break unless pq.entity.nil? || iter == MAX_SEARCH_SIZE
|
50
|
-
end
|
51
|
-
|
52
|
-
Notify.info("#{iter} attempts to find the pq note") unless iter.zero?
|
53
|
-
end
|
35
|
+
pq = wait_for(:'Priority Queue')
|
54
36
|
|
55
37
|
guid = pq.entity.guid
|
56
|
-
user = @model.user_info[:user]
|
57
|
-
shard = @model.user_info[:shard]
|
58
38
|
|
59
|
-
|
60
|
-
|
61
|
-
|
39
|
+
xml_conf = {
|
40
|
+
href: "evernote:///view/#{@user[:id]}/#{@shard}/#{guid}/#{guid}/",
|
41
|
+
content: @format.date_templates[:'Priority Queue']
|
42
|
+
}
|
43
|
+
|
44
|
+
xml = Evertils::Helper.load('Xml', enml)
|
45
|
+
a = xml.create(:a, xml_conf)
|
62
46
|
|
63
47
|
enml.at('li:contains("Queue") ul li').children.first.replace(a)
|
64
48
|
@content = enml
|
65
49
|
end
|
66
|
-
|
67
|
-
def find_priority_queue(sleep = false)
|
68
|
-
sleep(5) if sleep
|
69
|
-
title = @format.date_templates[:'Priority Queue']
|
70
|
-
Notify.info(title)
|
71
|
-
@model.find_note_contents(title)
|
72
|
-
end
|
73
50
|
end
|
74
51
|
end
|
75
52
|
end
|
@@ -24,14 +24,48 @@ module Evertils
|
|
24
24
|
def should_create?
|
25
25
|
today_is_first_of_month = Date.today.day == 1
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
result =
|
27
|
+
@note = find_note(NOTEBOOK)
|
28
|
+
@entity = @note.entity
|
29
|
+
result = @note.nil? && today_is_first_of_month
|
30
30
|
|
31
31
|
Notify.warning "#{self.class.name} skipped, note already exists" unless result
|
32
32
|
|
33
33
|
result
|
34
34
|
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# @since 0.3.15
|
38
|
+
def add_weekly_note_link
|
39
|
+
# parse the ENML note data into something we can work with
|
40
|
+
xml = @api.from_str(@entity.content)
|
41
|
+
# include the XML element builder
|
42
|
+
xml_helper = Evertils::Helper.load('Xml', xml)
|
43
|
+
# find the note entity we want to link
|
44
|
+
linked_note = find_note(:Weekly).entity
|
45
|
+
|
46
|
+
# don't add the note link if it is already there
|
47
|
+
unless xml.search("a[href='#{internal_url_for(linked_note)}']").size.zero?
|
48
|
+
return Notify.warning('Weekly note link already exists here, exiting to avoid duplicate content')
|
49
|
+
end
|
50
|
+
|
51
|
+
a = xml_helper.a(
|
52
|
+
internal_url_for(linked_note),
|
53
|
+
@format.date_templates[:Weekly]
|
54
|
+
)
|
55
|
+
li = xml_helper.li(a)
|
56
|
+
br = xml_helper.br
|
57
|
+
|
58
|
+
xml.search('ul:first-child li').after(li)
|
59
|
+
|
60
|
+
# add a line break after the UL if one is not there yet
|
61
|
+
if xml.search('ul:first-child').first.next_element.name != 'br'
|
62
|
+
xml.search('ul:first-child').after(br)
|
63
|
+
end
|
64
|
+
|
65
|
+
@entity.content = xml.to_s
|
66
|
+
|
67
|
+
Notify.success("#{self.class.name} updated, added weekly note link") if @note.update
|
68
|
+
end
|
35
69
|
end
|
36
70
|
end
|
37
71
|
end
|
@@ -3,7 +3,6 @@ module Evertils
|
|
3
3
|
class PriorityQueue < Type::Base
|
4
4
|
NOTEBOOK = :'Priority Queue'
|
5
5
|
COLOUR = 0xffe8b7
|
6
|
-
MAX_SEARCH_SIZE = 21
|
7
6
|
|
8
7
|
#
|
9
8
|
# @since 0.3.7
|
@@ -12,14 +11,7 @@ module Evertils
|
|
12
11
|
|
13
12
|
@handler = Evertils::Helper.load('ApiEnmlHandler', @config)
|
14
13
|
@title = @format.date_templates[NOTEBOOK]
|
15
|
-
|
16
|
-
if Date.today.monday?
|
17
|
-
@content = condition_monday
|
18
|
-
elsif Date.today.tuesday?
|
19
|
-
@content = condition_tuesday
|
20
|
-
else
|
21
|
-
@content = condition_default
|
22
|
-
end
|
14
|
+
@content = find_previous
|
23
15
|
end
|
24
16
|
|
25
17
|
#
|
@@ -30,77 +22,33 @@ module Evertils
|
|
30
22
|
|
31
23
|
private
|
32
24
|
|
33
|
-
#
|
34
|
-
# @since 0.3.7
|
35
|
-
def condition_monday
|
36
|
-
friday = (Date.today - 3)
|
37
|
-
dow = @format.day_of_week(friday.strftime('%a'))
|
38
|
-
note_title = "Queue For [#{friday.strftime('%B %-d')} - #{dow}]"
|
39
|
-
found = @model.find_note_contents(note_title)
|
40
|
-
|
41
|
-
raise "Queue was not found - #{friday.strftime('%B %-d')}" unless found
|
42
|
-
|
43
|
-
@handler.convert_to_xml(found.entity.content).prepare
|
44
|
-
end
|
45
|
-
|
46
|
-
# Find monday's note
|
47
|
-
# TODO: refactor
|
25
|
+
# Find a previous note
|
48
26
|
# @since 0.3.7
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
dow = @format.day_of_week(monday.strftime('%a'))
|
53
|
-
monday_note_title = "Queue For [#{monday.strftime('%B %-d')} - #{dow}]"
|
54
|
-
monday_note = @model.find_note_contents(monday_note_title)
|
27
|
+
def find_previous
|
28
|
+
day = Date.today
|
29
|
+
note = nil
|
55
30
|
|
56
|
-
|
57
|
-
note = monday_note.entity
|
58
|
-
else
|
59
|
-
# if it does not exist, get friday's note
|
60
|
-
friday = (Date.today - 4)
|
61
|
-
dow = @format.day_of_week(friday.strftime('%a'))
|
62
|
-
fri_note_title = "Queue For [#{friday.strftime('%B %-d')} - #{dow}]"
|
63
|
-
fri_note = @model.find_note_contents(fri_note_title)
|
31
|
+
Notify.info('Searching for...')
|
64
32
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
iter = 0
|
33
|
+
(1..MAX_SEARCH_SIZE).each do |iter|
|
34
|
+
day -= 1
|
35
|
+
dow = @format.day_of_week(day.strftime('%a'))
|
69
36
|
|
70
|
-
|
37
|
+
# always skip weekends, even if there is a note for those days
|
38
|
+
next if %i[Sa Su].include?(dow)
|
71
39
|
|
72
|
-
|
73
|
-
|
74
|
-
day -= 1
|
75
|
-
dow = @format.day_of_week(day.strftime('%a'))
|
76
|
-
note_title = "Queue For [#{day.strftime('%B %-d')} - #{dow}]"
|
77
|
-
query = @model.find_note_contents(note_title)
|
78
|
-
note = query.entity
|
40
|
+
note_title = "Queue For [#{day.strftime('%B %-d')} - #{dow}]"
|
41
|
+
note = @model.find_note_contents(note_title).entity
|
79
42
|
|
80
|
-
|
43
|
+
Notify.info(" (#{iter}) #{note_title}")
|
81
44
|
|
82
|
-
|
83
|
-
end
|
84
|
-
end
|
45
|
+
break unless note.nil?
|
85
46
|
end
|
86
47
|
|
87
48
|
raise 'Queue was not found' unless note
|
88
49
|
|
89
50
|
@handler.convert_to_xml(note.content).prepare
|
90
51
|
end
|
91
|
-
|
92
|
-
# Default action for not-Monday/Tuesday
|
93
|
-
# @since 0.3.7
|
94
|
-
def condition_default
|
95
|
-
yest = (Date.today - 1)
|
96
|
-
dow = @format.day_of_week(yest.strftime('%a'))
|
97
|
-
yest_note_title = "Queue For [#{yest.strftime('%B %-d')} - #{dow}]"
|
98
|
-
found = @model.find_note_contents(yest_note_title).entity
|
99
|
-
|
100
|
-
raise "Queue was not found - #{yest.strftime('%B %-d')}" unless found
|
101
|
-
|
102
|
-
@handler.convert_to_xml(found.content).prepare
|
103
|
-
end
|
104
52
|
end
|
105
53
|
end
|
106
54
|
end
|
@@ -18,6 +18,40 @@ module Evertils
|
|
18
18
|
def tags
|
19
19
|
["week-#{Date.today.cweek}"]
|
20
20
|
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# @since 0.3.15
|
24
|
+
def add_daily_note_link
|
25
|
+
# parse the ENML note data into something we can work with
|
26
|
+
xml = @api.from_str(@entity.content)
|
27
|
+
# include the XML element builder
|
28
|
+
xml_helper = Evertils::Helper.load('Xml', xml)
|
29
|
+
# find the note entity we want to link
|
30
|
+
linked_note = find_note(:Daily).entity
|
31
|
+
|
32
|
+
# don't add the note link if it is already there
|
33
|
+
unless xml.search("a[href='#{internal_url_for(linked_note)}']").size.zero?
|
34
|
+
return Notify.warning('Daily note link already exists here, exiting to avoid duplicate content')
|
35
|
+
end
|
36
|
+
|
37
|
+
a = xml_helper.a(
|
38
|
+
internal_url_for(linked_note),
|
39
|
+
@format.date_templates[:Daily]
|
40
|
+
)
|
41
|
+
li = xml_helper.li(a)
|
42
|
+
br = xml_helper.br
|
43
|
+
|
44
|
+
xml.search('en-note>div:first-child>ul li:last-child').after(li)
|
45
|
+
|
46
|
+
# add a line break after the UL if one is not there yet
|
47
|
+
if xml.search('en-note>div:first-child').first.next_element.name != 'br'
|
48
|
+
xml.search('en-note>div:first-child').after(br)
|
49
|
+
end
|
50
|
+
|
51
|
+
@entity.content = xml.to_s
|
52
|
+
|
53
|
+
Notify.success("#{self.class.name} updated, added daily note link") if @note.update
|
54
|
+
end
|
21
55
|
end
|
22
56
|
end
|
23
57
|
end
|
data/lib/evertils/version.rb
CHANGED
data/lib/evertils.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: evertils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Priebe
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- com.evertils.plist.dist
|
111
111
|
- evertils.gemspec
|
112
112
|
- lib/evertils.rb
|
113
|
+
- lib/evertils/base.rb
|
113
114
|
- lib/evertils/config.rb
|
114
115
|
- lib/evertils/configs/templates/daily.enml
|
115
116
|
- lib/evertils/configs/templates/monthly-task-summaries.enml
|
@@ -130,6 +131,7 @@ files:
|
|
130
131
|
- lib/evertils/helpers/formatting.rb
|
131
132
|
- lib/evertils/helpers/results.rb
|
132
133
|
- lib/evertils/helpers/time.rb
|
134
|
+
- lib/evertils/helpers/xml.rb
|
133
135
|
- lib/evertils/kernel.rb
|
134
136
|
- lib/evertils/request.rb
|
135
137
|
- lib/evertils/router.rb
|