enumark 0.1.3 → 0.1.4

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
  SHA256:
3
- metadata.gz: 24753e0838c8e355e1ddeec38ab241488f2cf71197dd4fe136dccb62a377b9dc
4
- data.tar.gz: 5f5659f7fd18b5d21ac5f63a367cb778537d296f21ff4bcd90beda20667a4be2
3
+ metadata.gz: b85bfbf07990e9f2a38461056ade65766019e3b322c7f4f64778d8627a1c6561
4
+ data.tar.gz: 5c42a625adbfd33c04d8d5cec939fb7fc91355e127dfe6181328433a7c7f7dc6
5
5
  SHA512:
6
- metadata.gz: 9e72d815fde4bd327f34018d65dfd1407bca74b05cd119daf451e1a407644ee53a0e6c4ec205d50e923b6a43badc7d1a0c17d229669edae2d32f1292b81451e8
7
- data.tar.gz: c2b795969b331004b1332100ba0827fcf0b41a511c7f358c345b4453db53db008a5fa607f73568d32dc82e374188c69f236f50e6a4f1eb90ad272eda0420f17b
6
+ metadata.gz: ed84f93d9a0b17acce86b08cc50e64517c023c46e85e29661471088afafb54c749bd3e20da4d42aecd6f91ecb1cbe201ce8d2e95ee50aafdfd729a440f33ed34
7
+ data.tar.gz: 9b679c8511689282e29c8c9b602d33510088d7ef00d1cba6bf88e60871d49c1ac02995de895dccff4a3385a5ae45729ecd2d85a353838c74ea1e096d7c922e62
data/README.md CHANGED
@@ -53,6 +53,17 @@ enum.each_category do |cate|
53
53
  end
54
54
  ```
55
55
 
56
+ Explore trends of your dump files:
57
+
58
+ ```ruby
59
+ dir = Enumark::Dir.new('/path/to/directory_with_bookmark_dump_files_more_than_one')
60
+
61
+ dir.added # select items in last file but not in second to last
62
+ dir.deleted # reject items in last file
63
+ dir.uniq # union all items
64
+ dir.static # select items appear in all files
65
+ ```
66
+
56
67
  ## Development
57
68
 
58
69
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/lib/enumark.rb CHANGED
@@ -1,111 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "enumark/version"
4
+ require 'enumark/item'
5
+ require 'enumark/category'
6
+ require 'enumark/grouping'
7
+ require 'enumark/dir'
4
8
 
5
9
  class Enumark
6
10
  include Enumerable
7
11
 
8
- CATEGORY_START = /^\s.*<DT><H3/
9
- CATEGORY_END = /^\s.*<\/DL><p>/
10
- CATEGORY_NAME = /ADD_DATE="(.*?)".*LAST_MODIFIED="(.*?)".*>(.*)<\/H3/
11
-
12
- ITEM_PREFIX = /^\s.*<DT><A/
13
- ITEM_NAME = /HREF="(.*?)".*ADD_DATE="(.*?)".*>(.*)<\/A>/
14
-
15
- class Category
16
- attr_reader :name
17
- alias_method :inspect, :name
18
- alias_method :to_s, :name
19
-
20
- def initialize(line)
21
- m = line.match(CATEGORY_NAME)
22
- @add_date = m[1]
23
- @last_mod = m[2]
24
- @name = m[3]
25
- end
26
- end
27
-
28
- class Item
29
- attr_reader :name, :href, :categories
30
-
31
- USELESS_SHARP = /\#.*$/
32
-
33
- def initialize(line, categories)
34
- m = line.match(ITEM_NAME)
35
- @href = m[1].gsub(USELESS_SHARP, '')
36
- @add_date = m[2]
37
- @name = m[3]
38
- @categories = categories
39
- end
40
-
41
- def inspect
42
- @inspect ||= "#{categories_str}> #{name}"
43
- end
44
-
45
- def categories_str
46
- @categories_str ||= "/#{categories.join('/')}"
47
- end
48
-
49
- def to_s
50
- inspect
51
- end
52
-
53
- def host
54
- @host ||= (URI.parse(href).host rescue 'unknown')
55
- end
56
- end
57
-
58
- class Hostname
59
- attr_reader :name, :items
60
-
61
- def initialize(name)
62
- @name = name
63
- @items = []
64
- end
65
-
66
- def add(item)
67
- @items << item
68
- end
69
-
70
- def inspect
71
- @name
72
- end
73
-
74
- def to
75
- inspect
76
- end
77
- end
78
-
79
- class Grouping
80
- Group = Struct.new(:name, :items)
81
-
82
- def initialize(enumark, key, &post)
83
- @lock = Mutex.new
84
- @collection = nil
85
-
86
- @enumark = enumark
87
- @key = key
88
- @post = post
89
- end
90
-
91
- def each(&block)
92
- unless @collection
93
- @lock.synchronize do
94
- @collection = @enumark.group_by(&@key)
95
- @collection = @post.call(@collection) if @post
96
- @collection = @collection.map{ |k, items| Group.new(k, items) }
97
- end
98
- end
99
-
100
- @collection.each(&block)
101
- end
102
- end
103
-
104
- def initialize(file)
12
+ def initialize(file, items: nil)
105
13
  @file = file
106
14
  @lock = Mutex.new
107
- @read = false
108
- @items = []
15
+ @items = items
109
16
 
110
17
  @hosts = Grouping.new(self, :host)
111
18
  @dup_titles = Grouping.new(self, :name){ |groups| groups.select{ |_, items| items.count > 1 } }
@@ -115,6 +22,7 @@ class Enumark
115
22
 
116
23
  def each(&block)
117
24
  read_all_lines
25
+ sort_by_add_date!
118
26
  @items.each(&block)
119
27
  end
120
28
 
@@ -134,32 +42,50 @@ class Enumark
134
42
  @cates.each(&block)
135
43
  end
136
44
 
45
+ [:+ ,:-, :&, :|].each do |op|
46
+ class_eval <<-EOM
47
+ def #{op}(another)
48
+ new_items = self.to_a #{op} another.to_a
49
+ Enumark.new(nil, items: new_items)
50
+ end
51
+ EOM
52
+ end
53
+
137
54
  private
138
55
 
139
56
  def read_all_lines
140
- return if @read
57
+ return if @items
141
58
 
142
59
  @lock.synchronize do
143
- next if @read
144
-
145
- _read_all_lines
146
- @read = true
60
+ _read_all_lines unless @items
147
61
  end
148
62
  end
149
63
 
150
64
  def _read_all_lines
151
65
  categories = []
66
+ @items = []
152
67
 
153
68
  File.new(@file).each do |line|
154
69
  case line
155
- when ITEM_PREFIX
70
+ when Item::PREFIX
156
71
  item = Item.new(line, categories.dup)
157
72
  @items.push(item)
158
- when CATEGORY_START
73
+ when Category::START
159
74
  categories.push(Category.new(line))
160
- when CATEGORY_END
75
+ when Category::ENDIND
161
76
  categories.pop
162
77
  end
163
78
  end
164
79
  end
80
+
81
+ def sort_by_add_date!
82
+ return if @sorted
83
+
84
+ @lock.synchronize do
85
+ next if @sorted
86
+
87
+ @items.sort!{ |i1, i2| i2.add_date <=> i1.add_date }
88
+ @sorted = true
89
+ end
90
+ end
165
91
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Enumark
4
+ class Category
5
+
6
+ START = /^\s.*<DT><H3/
7
+ ENDIND = /^\s.*<\/DL><p>/
8
+ PATTERN = /ADD_DATE="(.*?)".*LAST_MODIFIED="(.*?)".*>(.*)<\/H3/
9
+
10
+ attr_reader :name
11
+ alias_method :inspect, :name
12
+ alias_method :to_s, :name
13
+
14
+ def initialize(line)
15
+ m = line.match(PATTERN)
16
+ @add_date = m[1]
17
+ @last_mod = m[2]
18
+ @name = m[3]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Enumark
4
+ class Dir
5
+ def initialize(dir)
6
+ @enumarks = ::Dir.glob(dir).map{ |f| ::Enumark.new(f) }
7
+ raise 'Not enough to process' if @enumarks.count <= 1
8
+ end
9
+
10
+ def added
11
+ @added ||= (@enumarks[-1] - @enumarks[-2])
12
+ end
13
+
14
+ def deleted
15
+ @deleted ||= @enumarks[0..-2].reverse_each.reduce(&:|) - @enumarks[-1]
16
+ end
17
+
18
+ def uniq
19
+ @uniq ||= @enumarks.reverse_each.reduce(&:|)
20
+ end
21
+
22
+ def static
23
+ @static ||= @enumarks.reverse_each.reduce(&:&)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Enumark
4
+
5
+ class Grouping
6
+ Group = Struct.new(:name, :items)
7
+
8
+ def initialize(enumark, key, &post)
9
+ @lock = Mutex.new
10
+ @collection = nil
11
+
12
+ @enumark = enumark
13
+ @key = key
14
+ @post = post
15
+ end
16
+
17
+ def each(&block)
18
+ unless @collection
19
+ @lock.synchronize do
20
+ @collection = @enumark.group_by(&@key)
21
+ @collection = @post.call(@collection) if @post
22
+ @collection = @collection.map{ |k, items| Group.new(k, items) }
23
+ end
24
+ end
25
+
26
+ @collection.each(&block)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Enumark
4
+ class Item
5
+
6
+ PREFIX = /^\s.*<DT><A/
7
+ PATTERN = /HREF="(.*?)".*ADD_DATE="(.*?)".*>(.*)<\/A>/
8
+ USELESS_SHARP = /\#.*$/
9
+
10
+ attr_reader :name, :href, :add_date, :categories
11
+
12
+ def initialize(line, categories)
13
+ m = line.match(PATTERN)
14
+ @href = m[1].gsub(USELESS_SHARP, '')
15
+ @add_date = Time.at(m[2].to_i)
16
+ @name = m[3]
17
+ @categories = categories
18
+ end
19
+
20
+ def inspect
21
+ @inspect ||= "#{add_date.strftime('%F %T')} #{categories_str}> #{name}"
22
+ end
23
+
24
+ def categories_str
25
+ @categories_str ||= "/#{categories.join('/')}"
26
+ end
27
+
28
+ def to_s
29
+ inspect
30
+ end
31
+
32
+ def hash
33
+ href.hash
34
+ end
35
+
36
+ def eql?(another)
37
+ href.eql?(another.href)
38
+ end
39
+
40
+ def host
41
+ @host ||= (URI.parse(href).host rescue 'unknown')
42
+ end
43
+ end
44
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Enumark
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.4"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enumark
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - ken
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-14 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -41,6 +41,10 @@ files:
41
41
  - bin/setup
42
42
  - enumark.gemspec
43
43
  - lib/enumark.rb
44
+ - lib/enumark/category.rb
45
+ - lib/enumark/dir.rb
46
+ - lib/enumark/grouping.rb
47
+ - lib/enumark/item.rb
44
48
  - lib/enumark/version.rb
45
49
  homepage: https://github.com/turnon/enumark
46
50
  licenses: