syclink 0.0.2 → 0.1.0
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/Gemfile.lock +5 -3
- data/README.md +84 -6
- data/bin/syclink +189 -39
- data/lib/syclink/chrome.rb +37 -0
- data/lib/syclink/designer.rb +34 -1
- data/lib/syclink/exporter.rb +6 -0
- data/lib/syclink/file_importer.rb +19 -0
- data/lib/syclink/firefox.rb +36 -0
- data/lib/syclink/formatter.rb +32 -10
- data/lib/syclink/importer.rb +49 -0
- data/lib/syclink/internet_explorer.rb +27 -0
- data/lib/syclink/link.rb +9 -2
- data/lib/syclink/version.rb +1 -1
- data/lib/syclink/website.rb +35 -0
- data/lib/syclink.rb +6 -0
- data/spec/syclink/designer_spec.rb +25 -1
- data/spec/syclink/fi/a/two.pdf +0 -0
- data/spec/syclink/fi/a.txt +0 -0
- data/spec/syclink/fi/b/a/four.pdf +0 -0
- data/spec/syclink/fi/b/three.pdf +0 -0
- data/spec/syclink/fi/one.pdf +0 -0
- data/spec/syclink/formatter_spec.rb +53 -0
- data/spec/syclink/gc/Bookmarks +61 -0
- data/spec/syclink/ie/ie.txt +7 -0
- data/spec/syclink/ie/one/ie.txt +7 -0
- data/spec/syclink/ie/one/two/ie.txt +7 -0
- data/spec/syclink/importer_spec.rb +151 -0
- data/spec/syclink/link_spec.rb +9 -2
- data/spec/syclink/website_spec.rb +50 -4
- data/syclink.gemspec +2 -1
- metadata +34 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 757f2615ff72bd3c25ef404172faa9308e2a0c7f
|
|
4
|
+
data.tar.gz: a0a0ccac857393f6a4beae8a50a0f356e5faf578
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 737469dcc6463c9e13dc21b8cc310c93206bdd18f3a8a9a6ecaf5e164930a48291c4d42ecab3bbee81cc0e7a854cb6a66e27034cf73d14df068b4a16eb9ab48f
|
|
7
|
+
data.tar.gz: 0dadc454dcba9d28a8b4123a680a109dc860b216274e3800ce6c94259b3f088f3b86e1f6a3e36fb415a8980f2248568b0fbc6607cbdb6af119aaa69a3cd74fe5
|
data/Gemfile.lock
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
syclink (0.0.
|
|
4
|
+
syclink (0.0.2)
|
|
5
5
|
gli (= 2.13.1)
|
|
6
|
+
sqlite3 (= 1.3.10)
|
|
6
7
|
|
|
7
8
|
GEM
|
|
8
9
|
remote: https://rubygems.org/
|
|
@@ -23,11 +24,12 @@ GEM
|
|
|
23
24
|
rspec-support (~> 3.3.0)
|
|
24
25
|
rspec-support (3.3.0)
|
|
25
26
|
sass (3.4.15)
|
|
27
|
+
sqlite3 (1.3.10)
|
|
26
28
|
|
|
27
29
|
PLATFORMS
|
|
28
30
|
ruby
|
|
29
31
|
|
|
30
32
|
DEPENDENCIES
|
|
31
|
-
rspec
|
|
32
|
-
sass
|
|
33
|
+
rspec (= 3.3.0)
|
|
34
|
+
sass (= 3.4.15)
|
|
33
35
|
syclink!
|
data/README.md
CHANGED
|
@@ -27,14 +27,29 @@ _Website commands_
|
|
|
27
27
|
* website show - show all websites or search for websites
|
|
28
28
|
* website remove - Remove website
|
|
29
29
|
* website create - Create a HTML representation of the website
|
|
30
|
+
* website check - Check from links that are not active anymore (pending)
|
|
31
|
+
* website edit - Open the YAML file for editing (pending)
|
|
30
32
|
|
|
31
33
|
_Link commands_
|
|
32
|
-
* add - Add a link
|
|
33
|
-
* file
|
|
34
|
-
* update - Update a link
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
34
|
+
* add link - Add a link
|
|
35
|
+
* add file - Add links from a file
|
|
36
|
+
* update link - Update a link
|
|
37
|
+
* update file - Update links saved to a file
|
|
38
|
+
* delete - Delete one or more links
|
|
39
|
+
* list - List all links with an optional filter
|
|
40
|
+
* find - Find links based on a search string
|
|
41
|
+
* merge - Merge multiple links with same URL
|
|
42
|
+
|
|
43
|
+
_Import commands_
|
|
44
|
+
* import mf - Import Mozilla Firefox bookmarks
|
|
45
|
+
* import gc - Import Google Chrome bookmarks
|
|
46
|
+
* import ie - Import Internet Explorer bookmarks
|
|
47
|
+
* import dir - Import links to files from a directory
|
|
48
|
+
|
|
49
|
+
_Export commands_
|
|
50
|
+
* export xml - Export links in XML fromat (pending)
|
|
51
|
+
* export json - Export links in JSON format (pending)
|
|
52
|
+
* export csv - Export links in csv format
|
|
38
53
|
|
|
39
54
|
Commands
|
|
40
55
|
========
|
|
@@ -189,3 +204,66 @@ Following is showing the above sequence in commands
|
|
|
189
204
|
$ syclink add "http://github.com" --tag DEVELOPMENT
|
|
190
205
|
$ syclink website create
|
|
191
206
|
|
|
207
|
+
Importing Bookmarks from Webrowsers
|
|
208
|
+
===================================
|
|
209
|
+
|
|
210
|
+
Firefox
|
|
211
|
+
-------
|
|
212
|
+
The bookmarks of _Firefox_ are located in the user's home folder in
|
|
213
|
+
`~/.mozilla/SOME_CRYPTIC_NAME.default/places.sqlite`.
|
|
214
|
+
|
|
215
|
+
The database can be explored with _sqlite3_ from the command line
|
|
216
|
+
|
|
217
|
+
$ cd ~/.mozilla/SOME_CRYPTIC_NAME.default/
|
|
218
|
+
$ sqlite3 places.sqlite
|
|
219
|
+
>
|
|
220
|
+
|
|
221
|
+
We want to retrieve url, title, description, tag, key and bookmark. tag, key
|
|
222
|
+
and bookmark are good candidates for tags for the application.
|
|
223
|
+
|
|
224
|
+
At the command prompt of SQLite3 We can issue the query
|
|
225
|
+
|
|
226
|
+
````
|
|
227
|
+
sqlite> select p.id, p.url, p.title, b.id, b.fk, b.parent, b.title,
|
|
228
|
+
...> k.keyword, a.content, b_t.title from moz_bookmarks b
|
|
229
|
+
...> left outer join moz_keywords k on b.keyword_id = k.id
|
|
230
|
+
...> left outer join moz_items_annos a on a.item_id = b.id
|
|
231
|
+
...> left outer join moz_bookmarks b_t on b.parent = b_t.id
|
|
232
|
+
...> join moz_places p on p.id = b.fk where p.url like "http%";
|
|
233
|
+
1|https://www.mozilla.org/en-US/firefox/central/||6|1|3|Getting Started|||\
|
|
234
|
+
Bookmarks Toolbar
|
|
235
|
+
2|http://www.ubuntu.com/||8|2|7|Ubuntu|||Ubuntu and Free Software links
|
|
236
|
+
3|http://wiki.ubuntu.com/||9|3|7|Ubuntu Wiki (community-edited website)|||\
|
|
237
|
+
Ubuntu and Free Software links
|
|
238
|
+
4|https://answers.launchpad.net/ubuntu/+addquestion||10|4|7|Make a Support \
|
|
239
|
+
Request to the Ubuntu Community|||Ubuntu and Free Software links
|
|
240
|
+
5|http://www.debian.org/||11|5|7|Debian (Ubuntu is based on Debian)|||Ubuntu \
|
|
241
|
+
and Free Software links
|
|
242
|
+
6|https://one.ubuntu.com/||12|6|7|Ubuntu One - The personal cloud that brings\
|
|
243
|
+
your digital life together|||Ubuntu and Free Software links
|
|
244
|
+
7|https://www.mozilla.org/en-US/firefox/help/||14|7|13|Help and Tutorials|||\
|
|
245
|
+
Mozilla Firefox
|
|
246
|
+
8|https://www.mozilla.org/en-US/firefox/customize/||15|8|13|Customize \
|
|
247
|
+
Firefox|||Mozilla Firefox
|
|
248
|
+
9|https://www.mozilla.org/en-US/contribute/||16|9|13|Get Involved|||Mozilla \
|
|
249
|
+
Firefox
|
|
250
|
+
10|https://www.mozilla.org/en-US/about/||17|10|13|About Us|||Mozilla Firefox
|
|
251
|
+
4717|http://codekata.com/|CodeKata|30|4717|5|CodeKata|liklo|How do you get \
|
|
252
|
+
to be a great musician? It helps to know the theory,
|
|
253
|
+
and to understand the mechanics of your instrument. It helps to have
|
|
254
|
+
talent. But …|Unsorted Bookmarks
|
|
255
|
+
399|http://localhost:3000/|Secondhand | Home|34|399|2|Secondhand | Home|||\
|
|
256
|
+
Bookmarks Menu
|
|
257
|
+
12870|https://www.sqlite.org/cli.html|Command Line Shell For SQLite|35|12870|\
|
|
258
|
+
5|Command Line Shell For SQLite|dark|What is this sqlite all about?|Unsorted \
|
|
259
|
+
Bookmarks
|
|
260
|
+
4717|http://codekata.com/|CodeKata|37|4717|36||||wenga
|
|
261
|
+
12870|https://www.sqlite.org/cli.html|Command Line Shell For SQLite|39|12870|\
|
|
262
|
+
38||||lite
|
|
263
|
+
12883|http://ruby.bastardsbook.com/chapters/sql/#h-2-5|SQL | The Bastards \
|
|
264
|
+
Book of Ruby|40|12883|5|SQL | The Bastards Book of Ruby|||Unsorted Bookmarks
|
|
265
|
+
12883|http://ruby.bastardsbook.com/chapters/sql/#h-2-5|SQL | The Bastards \
|
|
266
|
+
Book of Ruby|42|12883|41||||Ruby
|
|
267
|
+
sqlite>
|
|
268
|
+
````
|
|
269
|
+
|
data/bin/syclink
CHANGED
|
@@ -14,7 +14,8 @@ include SycLink::Infrastructure
|
|
|
14
14
|
include SycLink::Formatter
|
|
15
15
|
|
|
16
16
|
# Commands that need to have a website and a designer object
|
|
17
|
-
WEBSITE_COMMANDS = [ :create, :
|
|
17
|
+
WEBSITE_COMMANDS = [ :create, :link, :file, :update, :delete, :list, :find,
|
|
18
|
+
:dir, :mf, :gc, :ie, :csv, :merge ]
|
|
18
19
|
|
|
19
20
|
# syclink's configuration directory
|
|
20
21
|
syclink_directory = File.expand_path("~/.syc/syclink")
|
|
@@ -54,7 +55,7 @@ copy_file_if_missing(File.join(File.dirname(__FILE__),
|
|
|
54
55
|
|
|
55
56
|
config = load_config(syclink_file)
|
|
56
57
|
|
|
57
|
-
program_desc 'Create a link
|
|
58
|
+
program_desc 'Create a link-list and display it as an html page'
|
|
58
59
|
|
|
59
60
|
version SycLink::VERSION
|
|
60
61
|
|
|
@@ -65,63 +66,89 @@ desc 'Website to operate on'
|
|
|
65
66
|
arg_name 'WEBSITE'
|
|
66
67
|
flag [:w,:website]
|
|
67
68
|
|
|
68
|
-
desc 'Add a link to the website'
|
|
69
|
-
arg_name 'URL'
|
|
69
|
+
desc 'Add a link from command line or links from a file to the website'
|
|
70
70
|
command :add do |c|
|
|
71
71
|
|
|
72
|
-
c.desc '
|
|
73
|
-
c.arg_name '
|
|
74
|
-
c.
|
|
72
|
+
c.desc 'Add a link from the command line to the website'
|
|
73
|
+
c.arg_name 'URL'
|
|
74
|
+
c.command :link do |s|
|
|
75
|
+
s.desc 'Name of the link'
|
|
76
|
+
s.arg_name 'NAME'
|
|
77
|
+
s.flag [:n, :name]
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
s.desc 'Description of the link'
|
|
80
|
+
s.arg_name 'DESCRIPTION'
|
|
81
|
+
s.flag [:d, :description]
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
s.desc 'Tag the link is associated to'
|
|
84
|
+
s.arg_name 'TAG'
|
|
85
|
+
s.flag [:t, :tag]
|
|
83
86
|
|
|
84
|
-
|
|
87
|
+
s.action do |global_options,options,args|
|
|
85
88
|
|
|
86
|
-
|
|
89
|
+
@designer.add_link(args[0], options)
|
|
87
90
|
|
|
91
|
+
end
|
|
88
92
|
end
|
|
89
|
-
end
|
|
90
93
|
|
|
91
|
-
desc 'Add links from a file to the website'
|
|
92
|
-
arg_name 'FILE'
|
|
93
|
-
command :file do |
|
|
94
|
+
c.desc 'Add links from a file to the website'
|
|
95
|
+
c.arg_name 'FILE'
|
|
96
|
+
c.command :file do |s|
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
s.action do |global_options,options,args|
|
|
96
99
|
|
|
97
|
-
|
|
100
|
+
@designer.add_links_from_file(args[0])
|
|
98
101
|
|
|
102
|
+
end
|
|
99
103
|
end
|
|
100
104
|
end
|
|
101
105
|
|
|
102
|
-
desc 'Update a link'
|
|
103
|
-
arg_name 'URL'
|
|
106
|
+
desc 'Update a link from command line or links from file'
|
|
104
107
|
command :update do |c|
|
|
105
108
|
|
|
106
|
-
c.desc '
|
|
107
|
-
c.arg_name '
|
|
108
|
-
c.
|
|
109
|
+
c.desc 'Update a link from the command line'
|
|
110
|
+
c.arg_name 'URL'
|
|
111
|
+
c.command :link do |s|
|
|
109
112
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
s.desc 'Name of the link'
|
|
114
|
+
s.arg_name 'NAME'
|
|
115
|
+
s.flag [:n, :name]
|
|
113
116
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
+
s.desc 'Description of the link'
|
|
118
|
+
s.arg_name 'DESCRIPTION'
|
|
119
|
+
s.flag [:d, :description]
|
|
117
120
|
|
|
118
|
-
|
|
121
|
+
s.desc 'Tag the link is associated to'
|
|
122
|
+
s.arg_name 'TAG'
|
|
123
|
+
s.flag [:t, :tag]
|
|
124
|
+
|
|
125
|
+
s.action do |global_options,options,args|
|
|
119
126
|
|
|
120
|
-
|
|
127
|
+
@designer.update_link(args[0], options)
|
|
128
|
+
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
c.desc "Update links by reading from file"
|
|
133
|
+
c.arg_name 'FILE'
|
|
134
|
+
c.command :file do |s|
|
|
135
|
+
|
|
136
|
+
s.action do |global_options,options,args|
|
|
137
|
+
|
|
138
|
+
@designer.update_links_from_file(args[0])
|
|
139
|
+
|
|
140
|
+
end
|
|
121
141
|
|
|
122
142
|
end
|
|
123
143
|
end
|
|
124
144
|
|
|
145
|
+
desc 'Merge links with same URL'
|
|
146
|
+
command :merge do |c|
|
|
147
|
+
c.action do |global_options,options,args|
|
|
148
|
+
@designer.merge_links
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
125
152
|
desc 'Find a link'
|
|
126
153
|
arg_name 'FIND_STRING'
|
|
127
154
|
command :find do |c|
|
|
@@ -131,17 +158,31 @@ command :find do |c|
|
|
|
131
158
|
c.arg_name 'URL, NAME, DESCRIPTION, TAG'
|
|
132
159
|
c.flag [:c, :columns]
|
|
133
160
|
|
|
161
|
+
c.desc 'Table width'
|
|
162
|
+
c.arg_name 'WIDTH'
|
|
163
|
+
c.flag [:w, :width], :type => Integer
|
|
164
|
+
|
|
165
|
+
c.desc 'Expand table to full width of specified WIDTH'
|
|
166
|
+
c.default_value true
|
|
167
|
+
c.switch [:e, :expand]
|
|
168
|
+
|
|
134
169
|
c.action do |global_options,options,args|
|
|
135
170
|
|
|
136
|
-
|
|
171
|
+
if args[0].nil?
|
|
172
|
+
STDERR.puts "Warning: You need to specify a FIND_STRING"
|
|
173
|
+
STDERR.puts "If you want to list all links use 'syclink list'"
|
|
174
|
+
else
|
|
175
|
+
print_links(@designer.find_links(args[0]), options[:c], options)
|
|
176
|
+
end
|
|
137
177
|
|
|
138
178
|
end
|
|
139
179
|
end
|
|
140
180
|
|
|
141
181
|
desc 'Remove one or more links'
|
|
142
|
-
arg_name 'URL[URL
|
|
182
|
+
arg_name 'URL [URL URL]'
|
|
143
183
|
command :delete do |c|
|
|
144
184
|
c.action do |global_options,options,args|
|
|
185
|
+
p args
|
|
145
186
|
@designer.remove_links(args)
|
|
146
187
|
end
|
|
147
188
|
end
|
|
@@ -170,9 +211,17 @@ command :list do |c|
|
|
|
170
211
|
c.arg_name 'URL, NAME, DESCRIPTION, TAG'
|
|
171
212
|
c.flag [:c, :columns]
|
|
172
213
|
|
|
214
|
+
c.desc 'Table width'
|
|
215
|
+
c.arg_name 'WIDTH'
|
|
216
|
+
c.flag [:w, :width], :type => Integer
|
|
217
|
+
|
|
218
|
+
c.desc 'Expand table to full width of specified WIDTH'
|
|
219
|
+
c.default_value true
|
|
220
|
+
c.switch [:e, :expand]
|
|
221
|
+
|
|
173
222
|
c.action do |global_options,options,args|
|
|
174
223
|
|
|
175
|
-
print_links(@designer.list_links(options), options[:c])
|
|
224
|
+
print_links(@designer.list_links(options), options[:c], options)
|
|
176
225
|
|
|
177
226
|
end
|
|
178
227
|
end
|
|
@@ -232,6 +281,107 @@ command :website do |c|
|
|
|
232
281
|
c.default_command :create
|
|
233
282
|
end
|
|
234
283
|
|
|
284
|
+
desc "Import links from Firefox, Chrome, Internet Explorer or directory"
|
|
285
|
+
command :import do |c|
|
|
286
|
+
|
|
287
|
+
c.desc 'Import links from Mozilla Firefox'
|
|
288
|
+
c.arg_name 'PATH_TO_FIREFOX_DATABASE'
|
|
289
|
+
c.command :mf do |s|
|
|
290
|
+
|
|
291
|
+
s.action do |global_options,options,args|
|
|
292
|
+
unless File.exists? args[0]
|
|
293
|
+
STDERR.puts <<-HERE.gsub(/^ {10}/, '')
|
|
294
|
+
Error: #{args[0]} doesn't exist!
|
|
295
|
+
Firefox stores its bookmarks in a SQLite3 database called
|
|
296
|
+
places.sqlite. With Ubuntu this database is usually located in
|
|
297
|
+
'~/.mozilla/firefox/*.default/places.sqlite'.
|
|
298
|
+
If you are on Windows
|
|
299
|
+
the file is located in the user's home directory
|
|
300
|
+
'~/AppData/Roaming/Mozilla/Profiles/*.default/places.sqlite'.
|
|
301
|
+
HERE
|
|
302
|
+
exit(0)
|
|
303
|
+
else
|
|
304
|
+
@designer.import_links(SycLink::Firefox.new(args.shift))
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
c.desc 'Import links from Google Chrome'
|
|
310
|
+
c.arg_name 'PATH_TO_CHROME_BOOKMARKS'
|
|
311
|
+
c.command :gc do |s|
|
|
312
|
+
|
|
313
|
+
s.action do |global_options,options,args|
|
|
314
|
+
unless File.exists? args[0]
|
|
315
|
+
STDERR.puts <<-HERE.gsub(/^ {10}/, '')
|
|
316
|
+
Error: #{args[0]} doesn't exist!
|
|
317
|
+
Google Chrome stores its bookmarks in a JSON file called
|
|
318
|
+
Bookmarks. With Ubuntu this file is usually located in
|
|
319
|
+
'~/.config/chromium/Default/Bookmarks'.
|
|
320
|
+
If you are on Windows
|
|
321
|
+
the file is located in the user's home directory
|
|
322
|
+
'~/AppData/Local/Google/Chrome/User Data/Bookmarks'.
|
|
323
|
+
HERE
|
|
324
|
+
exit(0)
|
|
325
|
+
else
|
|
326
|
+
@designer.import_links(SycLink::Chrome.new(args.shift))
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
c.desc 'Import links from Internet Explorer'
|
|
332
|
+
c.arg_name 'PATH_TO_INTERNET_EXPLORER_BOOKMARKS'
|
|
333
|
+
c.command :ie do |s|
|
|
334
|
+
|
|
335
|
+
s.action do |global_options,options,args|
|
|
336
|
+
unless File.exists? args[0]
|
|
337
|
+
STDERR.puts <<-HERE.gsub(/^ {10}/, '')
|
|
338
|
+
Error: #{args[0]} doesn't exist!
|
|
339
|
+
Internet Explorer stores its bookmarks in a directory structure.
|
|
340
|
+
the bookmarks are located in the user's home directory
|
|
341
|
+
'~/AppData/Favorites'.
|
|
342
|
+
HERE
|
|
343
|
+
exit(0)
|
|
344
|
+
else
|
|
345
|
+
@designer.import_links(SycLink::InternetExplorer.new(args.shift))
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
c.desc 'Import links from a Directory'
|
|
351
|
+
c.long_desc <<-HERE.gsub(/^ {4}/, '')
|
|
352
|
+
The PATH_TO_DIRECTORY can have patterns that allows to import specific
|
|
353
|
+
files.
|
|
354
|
+
|
|
355
|
+
Examples:
|
|
356
|
+
|
|
357
|
+
PATH_TO_DIRECTORY/**/*.pdf will import all pdf-files in the directories and
|
|
358
|
+
sub-directory
|
|
359
|
+
|
|
360
|
+
PATH_TO_DIRECTORY/**/* will import all files and sub-directories
|
|
361
|
+
HERE
|
|
362
|
+
|
|
363
|
+
c.arg_name 'PATH_TO_DIRECTORY'
|
|
364
|
+
c.command :dir do |s|
|
|
365
|
+
|
|
366
|
+
s.action do |global_options,options,args|
|
|
367
|
+
@designer.import_links(SycLink::FileImporter.new(args.shift))
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
desc 'Export to csv'
|
|
373
|
+
command :export do |c|
|
|
374
|
+
|
|
375
|
+
c.desc 'Export links to csv'
|
|
376
|
+
c.command :csv do |s|
|
|
377
|
+
|
|
378
|
+
s.action do |global_options,options,args|
|
|
379
|
+
puts @designer.export(:csv)
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
end
|
|
384
|
+
|
|
235
385
|
pre do |global,command,options,args|
|
|
236
386
|
|
|
237
387
|
if WEBSITE_COMMANDS.include?(command.name)
|
|
@@ -281,10 +431,10 @@ on_error do |exception|
|
|
|
281
431
|
end
|
|
282
432
|
end
|
|
283
433
|
|
|
284
|
-
def print_links(links, columns)
|
|
434
|
+
def print_links(links, columns, opts = {})
|
|
285
435
|
allowed_cols = %w{ url name description tag }
|
|
286
436
|
cols = columns.delete(' ').downcase.split(',') & allowed_cols
|
|
287
|
-
SycLink::Formatter.table(links, cols)
|
|
437
|
+
SycLink::Formatter.table(links, cols, opts)
|
|
288
438
|
end
|
|
289
439
|
|
|
290
440
|
exit run(ARGV)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
# Module that creates a link list and generates an html representation
|
|
4
|
+
module SycLink
|
|
5
|
+
|
|
6
|
+
# Importer for Google Chrome links
|
|
7
|
+
class Chrome < Importer
|
|
8
|
+
|
|
9
|
+
# Reads the content of the Google Chrome bookmarks file
|
|
10
|
+
def read
|
|
11
|
+
serialized = File.read(path)
|
|
12
|
+
extract_links(JSON.parse(serialized)).flatten.each_slice(4).to_a
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
# Extracts the links from the JSON file
|
|
18
|
+
def extract_links(json)
|
|
19
|
+
json["roots"].collect do |key, children|
|
|
20
|
+
extract_children(children["name"], children["children"])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Extracts the children from the JSON file
|
|
25
|
+
def extract_children(tag, children)
|
|
26
|
+
children.map do |child|
|
|
27
|
+
if child["children"]
|
|
28
|
+
extract_children("#{tag},#{child['name']}", child["children"])
|
|
29
|
+
else
|
|
30
|
+
[child["url"], child["name"], "", tag]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
data/lib/syclink/designer.rb
CHANGED
|
@@ -29,13 +29,31 @@ module SycLink
|
|
|
29
29
|
# are added to the websie
|
|
30
30
|
def add_links_from_file(file)
|
|
31
31
|
File.foreach(file) do |line|
|
|
32
|
-
|
|
32
|
+
next if line.chomp.empty?
|
|
33
|
+
url, name, description, tag = line.chomp.split(';')
|
|
33
34
|
website.add_link(Link.new(url, { name: name,
|
|
34
35
|
description: description,
|
|
35
36
|
tag: tag }))
|
|
36
37
|
end
|
|
37
38
|
end
|
|
38
39
|
|
|
40
|
+
# Accepts and SycLink::Importer to import Links and add them to the website
|
|
41
|
+
def import_links(importer)
|
|
42
|
+
importer.links.each do |link|
|
|
43
|
+
website.add_link(link)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Export links to specified format
|
|
48
|
+
def export(format)
|
|
49
|
+
message = "to_#{format.downcase}"
|
|
50
|
+
if website.respond_to? message
|
|
51
|
+
website.send(message)
|
|
52
|
+
else
|
|
53
|
+
raise "cannot export to #{format}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
39
57
|
# List links contained in the website and optionally filter on attributes
|
|
40
58
|
def list_links(args = {})
|
|
41
59
|
website.list_links(args)
|
|
@@ -52,6 +70,21 @@ module SycLink
|
|
|
52
70
|
website.find_links(url).first.update(args)
|
|
53
71
|
end
|
|
54
72
|
|
|
73
|
+
def update_links_from_file(file)
|
|
74
|
+
File.foreach(file) do |line|
|
|
75
|
+
next if line.chomp.empty?
|
|
76
|
+
url, name, description, tag = line.chomp.split(';')
|
|
77
|
+
website.find_links(url).first.update({ name: name,
|
|
78
|
+
description: description,
|
|
79
|
+
tag: tag })
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Merge links with same URL
|
|
84
|
+
def merge_links
|
|
85
|
+
website.merge_links_on(:url)
|
|
86
|
+
end
|
|
87
|
+
|
|
55
88
|
# Deletes one or more links from the website. Returns the deleted links.
|
|
56
89
|
# Expects the links provided in an array
|
|
57
90
|
def remove_links(urls)
|
data/lib/syclink/exporter.rb
CHANGED
|
@@ -12,6 +12,12 @@ module SycLink
|
|
|
12
12
|
renderer.result(binding)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
# Takes an array of row values and converts them to a csv string. Expects
|
|
16
|
+
# that the importing class is having a method rows.
|
|
17
|
+
def to_csv
|
|
18
|
+
rows.map { |row| row.join(';') }.join("\n")
|
|
19
|
+
end
|
|
20
|
+
|
|
15
21
|
end
|
|
16
22
|
|
|
17
23
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module SycLink
|
|
2
|
+
|
|
3
|
+
class FileImporter < Importer
|
|
4
|
+
|
|
5
|
+
def read
|
|
6
|
+
root_dir = File.dirname(path).scan(/^[^\*|\?]*/).first
|
|
7
|
+
regex = Regexp.new("(?<=#{root_dir}).*")
|
|
8
|
+
Dir.glob(path).map do |file|
|
|
9
|
+
url = file
|
|
10
|
+
name = File.basename(file)
|
|
11
|
+
description = ""
|
|
12
|
+
tags = extract_tags(File.dirname(file).scan(regex))
|
|
13
|
+
[url, name, description, tags]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'sqlite3'
|
|
2
|
+
require_relative 'importer'
|
|
3
|
+
|
|
4
|
+
# Module that creates a link list and generates an html representation
|
|
5
|
+
module SycLink
|
|
6
|
+
|
|
7
|
+
# Importer for Firefox links
|
|
8
|
+
class Firefox < Importer
|
|
9
|
+
|
|
10
|
+
# Query strig to read links from the Firefox database places.sqlite
|
|
11
|
+
QUERY_STRING = "select p.url, p.title, b.title, a.content, k.keyword, b_t.title from moz_bookmarks b left outer join moz_keywords k on b.keyword_id = k.id left outer join moz_items_annos a on a.item_id = b.id left outer join moz_bookmarks b_t on b.parent = b_t.id join moz_places p on p.id = b.fk where p.url like 'http%';"
|
|
12
|
+
|
|
13
|
+
# Reads the links from the Firefox database places.sqlite
|
|
14
|
+
def read
|
|
15
|
+
bookmark_file = Dir.glob(File.expand_path(path)).shift
|
|
16
|
+
raise "Did not find file #{path}" unless bookmark_file
|
|
17
|
+
|
|
18
|
+
db = SQLite3::Database.new(path)
|
|
19
|
+
|
|
20
|
+
import = db.execute(QUERY_STRING)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Returns row values in Arrays
|
|
24
|
+
def rows
|
|
25
|
+
read.map do |row|
|
|
26
|
+
a = row[0]; b = row[1]; c = row[2]; d = row[3]; e = row[4]; f = row[5]
|
|
27
|
+
[a,
|
|
28
|
+
b || c,
|
|
29
|
+
(d || '').gsub("\n", ' '),
|
|
30
|
+
[e, f].join(',').gsub(/^,|,$/, '')]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|