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 +4 -4
- data/README.md +11 -0
- data/lib/enumark.rb +33 -107
- data/lib/enumark/category.rb +21 -0
- data/lib/enumark/dir.rb +26 -0
- data/lib/enumark/grouping.rb +29 -0
- data/lib/enumark/item.rb +44 -0
- data/lib/enumark/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b85bfbf07990e9f2a38461056ade65766019e3b322c7f4f64778d8627a1c6561
|
4
|
+
data.tar.gz: 5c42a625adbfd33c04d8d5cec939fb7fc91355e127dfe6181328433a7c7f7dc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
@
|
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 @
|
57
|
+
return if @items
|
141
58
|
|
142
59
|
@lock.synchronize do
|
143
|
-
|
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
|
70
|
+
when Item::PREFIX
|
156
71
|
item = Item.new(line, categories.dup)
|
157
72
|
@items.push(item)
|
158
|
-
when
|
73
|
+
when Category::START
|
159
74
|
categories.push(Category.new(line))
|
160
|
-
when
|
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
|
data/lib/enumark/dir.rb
ADDED
@@ -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
|
data/lib/enumark/item.rb
ADDED
@@ -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
|
data/lib/enumark/version.rb
CHANGED
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.
|
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-
|
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:
|