enumark 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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: