fundler 0.2.6 → 0.3.0

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
  SHA1:
3
- metadata.gz: c9e5cc9979b9b7356a8341a8bd13674dece28c55
4
- data.tar.gz: 0251f3debe730d261e4f47dcf035e3f2f8be4129
3
+ metadata.gz: da0902defdfad3f010e5eaccb203cb54c36d71c6
4
+ data.tar.gz: 8154e8189a025975c2703612b5ab45ecba37b59a
5
5
  SHA512:
6
- metadata.gz: d9f874b856944b3f6d20a16a0d91abc0e49cfec0363f941b5e4cf135c96f9dbb16acde8e693ce403e45c9e05fb2c96544f22d0983b493207e151b1f2d69c5b79
7
- data.tar.gz: cbbf396c02cc8b21d71ebd26914dcc63e5c6805e60fe3c021a22663428ad478508081efbcda8ebdaca549a6e41d579fb772eaee0ab143b63094bc28a18f9c2d2
6
+ metadata.gz: 5d9adfc90611ab96b05781356f0467a2d2309224f87ba78ccb9bc5f4ad20f0ca6b0e561c93f73fa6658702e749ecf0fdf7bd9cef56ae68942f6ceebac817aa17
7
+ data.tar.gz: 638b975cd75a57ad254ca5782afb9e5f2b72f79de16dd3f543f10e127e7c72b0e758279bb8ab554f6030a5fc8f47391d219b301921e3bad71eeab001a565bc15
@@ -11,7 +11,7 @@ class FundlerProgram
11
11
  attr_reader :input
12
12
 
13
13
  def err msg
14
- $stderr.puts "* error: #{msg}"
14
+ $stderr.puts "* : #{msg}"
15
15
  exit 1
16
16
  end
17
17
 
@@ -29,51 +29,59 @@ class FundlerProgram
29
29
  @debug = false
30
30
 
31
31
  # Parser
32
+ options = {}
32
33
  optparse = OptionParser.new do |opts|
33
34
  opts.banner = "Usage: #{opts.program_name} [OPTIONS] "
34
- opts.define_head 'file name cleaner'
35
+ opts.define_head 'Fundler: file name cleaner and bookmarks utility'
36
+ opts.program_name = 'Fundler'
35
37
  opts.separator ''
36
38
 
37
39
  opts.on('-d', '--debug', "Turn on debugging.") do
38
40
  @debug = true
39
41
  end
40
42
 
41
- opts.on('-o', '--output FILE', String,
42
- "Where to output the merged ruby script.") do |f|
43
- @output = File.open(f, 'w') unless '-' == f
44
- end
43
+ #opts.on('-o', '--output FILE', String,
44
+ # "Where to output the merged ruby script.") do |f|
45
+ # @output = File.open(f, 'w') unless '-' == f
46
+ #end
45
47
 
46
48
  opts.on('-c', '--clean_names',
47
49
  'clean, squeeze, downcase the filenames in pwd') do
48
50
  debug "Cleaning the pwd: #{fundler.pwd}"
49
51
  fundler.clean
50
52
  end
53
+
51
54
  opts.on('-l', '--list', 'listing files in pwd') do
52
55
  debug "List files in #{fundler.pwd}"
53
56
  fundler.list
54
57
  end
55
58
 
56
- opts.on('-b', '--bookmarks', 'a glance on firefox bookmarksdir') do
59
+ opts.on('-b', '--bookmarks FORMAT', String,
60
+ 'drop firefox bookmarks in txt, html, markdown, json') do |format|
57
61
  debug "Bookmarks util"
58
- fundler.bookmarks
62
+ options[:format] = format
63
+ fundler.bookmarks(format)
59
64
  end
65
+
60
66
  opts.on_tail('-V', '--version', 'Show the version.') do
61
- $stderr.puts "#{opts.program_name} version: #{Fundler::VERSION}"
62
- exit
67
+ err "#{opts.program_name} version: #{Fundler::VERSION}"
63
68
  end
64
69
 
65
70
  opts.on_tail('-h', '--help', 'This Help.') do
66
- $stderr.puts opts
67
- exit
71
+ err opts
68
72
  end
69
73
  end
70
74
 
71
- arguments = optparse.parse!
75
+ begin
76
+ arguments = optparse.parse!(ARGV)
77
+ rescue OptionParser::ParseError
78
+ err optparse.help
79
+ end
72
80
 
73
- if arguments.size == 0
74
- # err "Argument needed!\n#{optparse.banner}"
81
+ if arguments.size == 0
82
+ #err "Argument needed!\n#{optparse.banner}"
75
83
  elsif arguments.size > 1
76
- err "You can only specify one directory a time"
84
+ err "You can only specify one format a time"
77
85
  end
78
86
 
79
87
  if '-' == arguments.first
@@ -96,7 +104,6 @@ class FundlerProgram
96
104
  end
97
105
 
98
106
  #if __FILE__ == $0
99
- p Time.now
100
107
  FundlerProgram.new.run
101
108
  #end
102
109
 
@@ -13,13 +13,10 @@ class Fundler
13
13
  def pwd
14
14
  get_pwd
15
15
  end
16
- def bookmarks
17
- drop_bookmarks
16
+ def bookmarks(format)
17
+ drop_bookmarks(format)
18
18
  end
19
19
  def list
20
20
  get_list
21
21
  end
22
- def drop_bookmarks_file(format = :plain)
23
- drop_bookmarks(format)
24
- end
25
22
  end
@@ -1,105 +1,18 @@
1
1
  # coding: utf-8
2
- require 'sqlite3'
3
-
4
- =begin rdoc
5
-
6
- == Schema
7
- http://people.mozilla.org/~dietrich/places-erd.png
8
-
9
- == References
10
- http://stackoverflow.com/questions/464516/firefox-bookmarks-sqlite-structure
11
- https://developer.mozilla.org/en-US/docs/Places
12
- https://developer.mozilla.org/en-US/docs/Retrieving_part_of_the_bookmarks_tree
13
- https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsINavBookmarksService
14
- http://davidkoepi.wordpress.com/2010/11/27/firefoxforensics/
15
-
16
- == Queries
17
-
18
- select moz_places.url, moz_bookmarks.title
19
- from moz_places,moz_bookmarks
20
- where moz_places.id = moz_bookmarks.fk and moz_bookmarks.title != '';
21
2
 
22
- select keyword,url
23
- from moz_keywords
24
- left join moz_bookmarks on (moz_keywords.id = keyword_id)
25
- left join moz_places on (fk = moz_places.id);
3
+ require 'sqlite3'
4
+ require 'json'
5
+ require_relative 'fundler_utils'
26
6
 
27
- select moz_places.url, datetime((moz_historyvisits.visit_date/1000000), ‘unixepoch’, ‘localtime’), moz_historyvisits.visit_type
28
- from moz_places, moz_historyvisits
29
- where moz_historyvisits.place_id = moz_places.id
30
- order by moz_historyvisits.visit_date desc;
31
- =end
7
+ #TODO: make private methods... well, private!
32
8
 
33
9
  module BookmarksReader
34
10
 
11
+ include QueryConstants
12
+
35
13
  attr_reader :db
36
14
 
37
15
  MOZILLA_FIREFOX_CONF_DIR = File.expand_path('~') + '/.mozilla/firefox/'
38
-
39
- # all bookmarks
40
- BOOKMARKS_QUERY = <<-SQL
41
- SELECT DISTINCT
42
- moz_places.url AS url,
43
- moz_bookmarks.title AS title,
44
- moz_items_annos.content AS description
45
- FROM
46
- moz_places,
47
- moz_bookmarks,
48
- moz_items_annos,
49
- moz_anno_attributes
50
- WHERE
51
- moz_anno_attributes.name = 'bookmarkProperties/description' AND
52
- moz_items_annos.anno_attribute_id = moz_anno_attributes.id AND
53
- moz_items_annos.item_id = moz_bookmarks.id AND
54
- moz_places.id = moz_bookmarks.fk AND
55
- moz_places.id IN (
56
- SELECT DISTINCT fk
57
- FROM moz_bookmarks
58
- WHERE parent IN (
59
- SELECT moz_bookmarks.id
60
- FROM moz_bookmarks, moz_bookmarks_roots
61
- WHERE moz_bookmarks_roots.root_name = 'tags'
62
- AND moz_bookmarks.parent = moz_bookmarks_roots.folder_id
63
- )
64
- )
65
- ORDER BY UPPER(moz_bookmarks.title) ASC
66
- SQL
67
-
68
- # tag.id|tag.title
69
- QUERY_FOR_TAGS = <<-SQL
70
- SELECT id, title FROM moz_bookmarks WHERE parent = 4;
71
- SQL
72
-
73
- # all bookmarks with the "given" tag.id
74
- QUERY_BY_TAG = <<-SQL
75
- SELECT moz_places.id, moz_places.url, moz_places.title, moz_bookmarks.parent
76
- FROM moz_places
77
- LEFT OUTER JOIN moz_bookmarks
78
- ON moz_places.id = moz_bookmarks.fk
79
- WHERE moz_bookmarks.parent = @tag_id;
80
- SQL
81
-
82
- # bookmark.id|bookmark.fk|bookmark.title
83
- # ...
84
- #=> 1933|1387|SQLite Home Page
85
- # ...
86
- QUERY_FOR_SIMPLE_BOOKMARKS = <<-SQL
87
- SELECT id,fk,title FROM moz_bookmarks WHERE parent = 2;
88
- SQL
89
-
90
- # select the link between bookmars and tags
91
- # fk_id = 1387
92
- #=> 1934|1387|1144
93
- QUERY_FOR_LINK = <<-SQL
94
- SELECT id,fk,parent FROM moz_bookmarks WHERE title is null AND fk = @fk_id;
95
- SQL
96
-
97
- # tag.id|tag.title
98
- # parent = 1144
99
- #=> 1144|coding
100
- QUERY_FOR_TAG_BY_ID = <<-SQL
101
- SELECT id, title FROM moz_bookmarks WHERE parent = 4 AND id = @parent;
102
- SQL
103
16
 
104
17
  def find_bookmarks_by_tag(tag_id)
105
18
  query = QUERY_BY_TAG
@@ -124,28 +37,49 @@ module BookmarksReader
124
37
  db.get_first_row(query)
125
38
  end
126
39
 
40
+ def stored_bookmarks
41
+ # humm... I don't like this choice
42
+ @stored_bookmarks ||= get_bookmarks_with_tags
43
+ end
44
+
45
+ def bookmarks_count
46
+ stored_bookmarks.size
47
+ end
48
+
127
49
  def get_bookmarks_with_tags
128
- bookmarks = []
129
- result = {}
130
- db.execute(QUERY_FOR_SIMPLE_BOOKMARKS) do |bookmark|
131
- bookmarks << bookmark
132
- end
133
- bookmarks.each do |bookmark|
134
- bookmark_id, bookmark_fk, bookmark_title = bookmark
135
- if bookmark_fk
136
- link_query = QUERY_FOR_LINK.sub(/@fk_id/, bookmark_fk.to_s)
137
- links = db.execute(link_query)
138
- links.each do |link|
139
- link_id, link_fk, link_parent = link
140
- tag_query = QUERY_FOR_TAG_BY_ID.gsub(/@parent/, link_parent.to_s)
141
- db.execute(tag_query) do |tag|
142
- tag_id, tag_title = tag
143
- result[bookmark_id] = "[#{tag_title}] #{bookmark_title}"
50
+ all = []
51
+ @stored_bookmarks = {}
52
+ if db
53
+ db.execute(QUERY_FOR_SIMPLE_BOOKMARKS) do |bookmark|
54
+ all << bookmark
55
+ end
56
+ all.each do |bookmark|
57
+ bookmark_id, bookmark_fk, bookmark_title = bookmark
58
+ if bookmark_fk
59
+ link_query = QUERY_FOR_LINK.sub(/@fk_id/, bookmark_fk.to_s)
60
+ links = db.execute(link_query)
61
+ links.each do |link|
62
+ link_id, link_fk, link_parent = link
63
+ tag_query = QUERY_FOR_TAG_BY_ID.gsub(/@parent/, link_parent.to_s)
64
+ db.execute(tag_query) do |tag|
65
+ tag_id, tag_title = tag
66
+ @stored_bookmarks[bookmark_id] = { tag: tag_title, title: bookmark_title }
67
+ end
144
68
  end
145
69
  end
146
70
  end
147
71
  end
148
- result
72
+ @stored_bookmarks.extend(HashBookmarksUtil)
73
+ end
74
+
75
+ def get_bookmarks_with_url_title_descr_tag
76
+ unless stored_bookmarks.empty?
77
+ db.execute(BOOKMARKS_QUERY).each do |bookmark|
78
+ url, title, id, description = bookmark
79
+ @stored_bookmarks[id].merge!({url: url, description: description})
80
+ end
81
+ end
82
+ @stored_bookmarks
149
83
  end
150
84
 
151
85
  # +drop_bookmarks+ browse the home directory of the current user,
@@ -154,18 +88,17 @@ module BookmarksReader
154
88
  def drop_bookmarks(format = :txt)
155
89
  output = []
156
90
  if db
157
- rows = db.execute(BOOKMARKS_QUERY)
158
- rows.each_with_index do |row, index|
159
- case format
91
+ get_bookmarks_with_url_title_descr_tag.each_with_index do |row, index|
92
+ case format.intern
160
93
  when :txt
161
- output << "#{index}: #{row.join(' | ')}"
94
+ output << "#{index}: #{row}"
162
95
  output << '---'
163
96
  when :html
164
97
  puts "TODO"
165
98
  when :markdown
166
99
  puts "TODO"
167
100
  when :json
168
- puts "TODO"
101
+ output << row.to_json
169
102
  else
170
103
  # exit 1
171
104
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # ---
2
3
 
3
4
  require 'fileutils'
@@ -47,4 +48,115 @@ module ExitCodeMatchers
47
48
  "expect block to call exit(#{code})"
48
49
  end
49
50
  end
50
- end
51
+ end # ExitCodeMatchers
52
+
53
+ =begin rdoc
54
+
55
+ == Schema
56
+ http://people.mozilla.org/~dietrich/places-erd.png
57
+
58
+ == References
59
+ http://stackoverflow.com/questions/464516/firefox-bookmarks-sqlite-structure
60
+ https://developer.mozilla.org/en-US/docs/Places
61
+ https://developer.mozilla.org/en-US/docs/Retrieving_part_of_the_bookmarks_tree
62
+ https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsINavBookmarksService
63
+ http://davidkoepi.wordpress.com/2010/11/27/firefoxforensics/
64
+
65
+ == Queries
66
+
67
+ select moz_places.url, moz_bookmarks.title
68
+ from moz_places,moz_bookmarks
69
+ where moz_places.id = moz_bookmarks.fk and moz_bookmarks.title != '';
70
+
71
+ select keyword,url
72
+ from moz_keywords
73
+ left join moz_bookmarks on (moz_keywords.id = keyword_id)
74
+ left join moz_places on (fk = moz_places.id);
75
+
76
+ select moz_places.url, datetime((moz_historyvisits.visit_date/1000000), ‘unixepoch’, ‘localtime’), moz_historyvisits.visit_type
77
+ from moz_places, moz_historyvisits
78
+ where moz_historyvisits.place_id = moz_places.id
79
+ order by moz_historyvisits.visit_date desc;
80
+ =end
81
+
82
+ module QueryConstants
83
+
84
+ # all bookmarks
85
+ BOOKMARKS_QUERY = <<-SQL
86
+ SELECT DISTINCT
87
+ moz_places.url AS url,
88
+ moz_bookmarks.title AS title,
89
+ moz_bookmarks.id AS id,
90
+ moz_items_annos.content AS description
91
+ FROM
92
+ moz_places,
93
+ moz_bookmarks,
94
+ moz_items_annos,
95
+ moz_anno_attributes
96
+ WHERE
97
+ moz_anno_attributes.name = 'bookmarkProperties/description' AND
98
+ moz_items_annos.anno_attribute_id = moz_anno_attributes.id AND
99
+ moz_items_annos.item_id = moz_bookmarks.id AND
100
+ moz_places.id = moz_bookmarks.fk AND
101
+ moz_places.id IN (
102
+ SELECT DISTINCT fk
103
+ FROM moz_bookmarks
104
+ WHERE parent IN (
105
+ SELECT moz_bookmarks.id
106
+ FROM moz_bookmarks, moz_bookmarks_roots
107
+ WHERE moz_bookmarks_roots.root_name = 'tags'
108
+ AND moz_bookmarks.parent = moz_bookmarks_roots.folder_id
109
+ )
110
+ )
111
+ ORDER BY UPPER(moz_bookmarks.title) ASC
112
+ SQL
113
+
114
+ # tag.id|tag.title
115
+ QUERY_FOR_TAGS = <<-SQL
116
+ SELECT id, title FROM moz_bookmarks WHERE parent = 4;
117
+ SQL
118
+
119
+ # all bookmarks with the "given" tag.id
120
+ QUERY_BY_TAG = <<-SQL
121
+ SELECT moz_places.id, moz_places.url, moz_places.title, moz_bookmarks.parent
122
+ FROM moz_places
123
+ LEFT OUTER JOIN moz_bookmarks
124
+ ON moz_places.id = moz_bookmarks.fk
125
+ WHERE moz_bookmarks.parent = @tag_id;
126
+ SQL
127
+
128
+ # bookmark.id|bookmark.fk|bookmark.title
129
+ # ...
130
+ #=> 1933|1387|SQLite Home Page
131
+ # ...
132
+ QUERY_FOR_SIMPLE_BOOKMARKS = <<-SQL
133
+ SELECT id,fk,title FROM moz_bookmarks WHERE parent = 2;
134
+ SQL
135
+
136
+ # select the link between bookmars and tags
137
+ # fk_id = 1387
138
+ #=> 1934|1387|1144
139
+ QUERY_FOR_LINK = <<-SQL
140
+ SELECT id,fk,parent FROM moz_bookmarks WHERE title is null AND fk = @fk_id;
141
+ SQL
142
+
143
+ # tag.id|tag.title
144
+ # parent = 1144
145
+ #=> 1144|coding
146
+ QUERY_FOR_TAG_BY_ID = <<-SQL
147
+ SELECT id, title FROM moz_bookmarks WHERE parent = 4 AND id = @parent;
148
+ SQL
149
+
150
+ end # QueryConstants
151
+
152
+ module HashBookmarksUtil
153
+ def sort_bookmarks_by(field)
154
+ if [:tag, :tile].include?(field.intern)
155
+ self.sort_by do |key, value|
156
+ value[field.intern]
157
+ end
158
+ else
159
+ self
160
+ end
161
+ end
162
+ end # HashBookmarksUtil
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
  class Fundler
3
3
  # The version of the Fundler Utility.
4
- VERSION = "0.2.6"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -2,6 +2,7 @@ require 'fundler_spec_helper'
2
2
 
3
3
  class TestBookmarksFundler
4
4
  describe Fundler do
5
+
5
6
  context 'bookmarks functions' do
6
7
  let(:fundler) { Fundler.new }
7
8
  before(:each) do
@@ -12,10 +13,21 @@ class TestBookmarksFundler
12
13
  FileUtils::rm_rf 'test'
13
14
  end
14
15
 
15
- it 'finds bookmarks file' do
16
+ it 'drop txt bookmarks file' do
16
17
  FileUtils::cd './test' do
17
- fundler.drop_bookmarks_file(:txt)
18
+ fundler.bookmarks(:txt)
18
19
  expect(fundler.all_files).to include('bookmarks_dump.txt')
20
+ file_line_count = File.foreach('bookmarks_dump.txt').inject(0) { |c, line| c+=1 }
21
+ expect(fundler.bookmarks_count).to eq (file_line_count/2)
22
+ end
23
+ end
24
+
25
+ it 'drop json bookmarks file' do
26
+ FileUtils::cd './test' do
27
+ fundler.bookmarks(:json)
28
+ expect(fundler.all_files).to include('bookmarks_dump.json')
29
+ file_line_count = File.foreach('bookmarks_dump.json').inject(0) { |c, line| c+=1 }
30
+ expect(fundler.bookmarks_count).to eq (file_line_count)
19
31
  end
20
32
  end
21
33
 
@@ -23,6 +35,10 @@ class TestBookmarksFundler
23
35
  expect { fundler.get_bookmarks_with_tags }.to_not raise_error
24
36
  end
25
37
 
38
+ it 'get bookmarks url, title, descr and tag' do
39
+ expect { fundler.get_bookmarks_with_url_title_descr_tag }.to_not raise_error
40
+ end
26
41
  end # context
42
+
27
43
  end # describe
28
44
  end # TestBookmarksFundler
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - zeroed
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-09 00:00:00.000000000 Z
11
+ date: 2013-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sqlite3