evertils 0.3.14.1 → 0.3.15

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
2
  SHA1:
3
- metadata.gz: 718d7296f7fb64fe1e53c51150e94d5dbfca5771
4
- data.tar.gz: 1f4a1ff05f39f7e2dfd49a7d525cce45157b5075
3
+ metadata.gz: 390570a1abaf99659566485a2a510eb04420bd9f
4
+ data.tar.gz: ab267ee4d649934d9c14f65190fb7141dceb5efc
5
5
  SHA512:
6
- metadata.gz: d7ac052ae463845c104993eb40e4735629c5094cc438bc9ae4c6c50f1ddc11f36a1909e48601b7003ef33848bf853be929ab4f6f4ff762d75ca56cfd1500153a
7
- data.tar.gz: 7e54c227677a05a14621fcc4b20314e2a06c3ac60ed2f57c55b0ffaa7090b5f51cb83ed255a0d299f9e3b1ae86cb4af18e34afb3d80fbdbdb424a1d0cc3d69f3
6
+ metadata.gz: 465c395234e693c2d2629a2fec71a2aed62ef54c4b30894dc921840604e057a470fb5c323f2b2421703b5a811f70c108e17e4bae25bd7409f28c39db1ab06af2
7
+ data.tar.gz: 58eaa1cebdf34080a4297eeab8d910919080e1340bffef65db988c33f80f59d05dc0bbc9887ee618c1cce4918b7346ac26f3101f44926e14f3b108e1688d4db1
@@ -0,0 +1,7 @@
1
+ module Evertils
2
+ class Base
3
+ def initialize
4
+ @format = Evertils::Helper.load('Formatting')
5
+ end
6
+ end
7
+ end
@@ -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
- @xml = Nokogiri::XML::DocumentFragment.parse(str)
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
- note_title = @format.date_templates[self.class::NOTEBOOK]
39
- found = @model.find_note_contents(note_title)
40
- result = found.entity.nil?
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
@@ -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
- Notify.info('Waiting for...')
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
- a = Nokogiri::XML::Node.new('a', enml)
60
- a['href'] = "evernote:///view/#{user[:id]}/#{shard}/#{guid}/#{guid}/"
61
- a.content = @format.date_templates[:'Priority Queue']
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
- monthly_note_title = @format.date_templates[NOTEBOOK]
28
- found = @model.find_note_contents(monthly_note_title)
29
- result = found.entity.nil? && today_is_first_of_month
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
- # Get friday's note
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 condition_tuesday
50
- # get monday note
51
- monday = (Date.today - 1)
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
- if !monday_note.entity.nil?
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
- if fri_note.entity.nil?
66
- # if it does not exist, get $day - 1 note until we find one
67
- day = friday
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
- Notify.info('Searching for...')
37
+ # always skip weekends, even if there is a note for those days
38
+ next if %i[Sa Su].include?(dow)
71
39
 
72
- loop do
73
- iter += 1
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
- Notify.info(" (#{iter}) #{note_title}")
43
+ Notify.info(" (#{iter}) #{note_title}")
81
44
 
82
- break unless note.nil? || iter == MAX_SEARCH_SIZE
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
@@ -1,3 +1,3 @@
1
1
  module Evertils
2
- VERSION = '0.3.14.1'.freeze
2
+ VERSION = '0.3.15'.freeze
3
3
  end
data/lib/evertils.rb CHANGED
@@ -18,6 +18,7 @@ require 'nokogiri'
18
18
  # include required files
19
19
  require 'evertils/kernel'
20
20
  require 'evertils/version'
21
+ require 'evertils/base'
21
22
  require 'evertils/type'
22
23
  require 'evertils/helpers/time'
23
24
  require 'evertils/helpers/results'
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.14.1
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