chromarks 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bkmrk.gemspec
4
+ gemspec
5
+
6
+ group :extras do
7
+ gem 'rb-fsevent', '~> 0.9'
8
+ gem 'guard-rspec'
9
+ end
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ guard 'rspec' do
2
+ watch('bin/chromarks') { 'spec' }
3
+ watch('spec/spec_helper.rb') { 'spec' }
4
+ watch(%r{^spec/.+_spec\.rb$})
5
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
6
+ watch(%r{^lib/.+\.rb$}) { 'spec' }
7
+ end
8
+
9
+ # vim: ft=ruby
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jesper Kjeldgaard
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Chromarks
2
+
3
+ Currently only support for bookmarks at this location:
4
+
5
+ * Chrome (OSX)
6
+
7
+ ~/Library/Application\ Support/Google/Chrome/Default/Bookmarks
8
+
9
+ ## Installation
10
+
11
+ Install via Rubygems.org:
12
+
13
+ $ gem install chromarks
14
+
15
+ ## Usage
16
+
17
+ Running Bkmrk without any parameters output all bookmarks:
18
+
19
+ $ chromarks
20
+
21
+ To open a given bookmark run:
22
+
23
+ $ chromarks <ID>
24
+
25
+ To search bookmarks, provide a search term like so:
26
+
27
+ $ chromarks '<search term(s)>'
28
+
29
+ ### Useful alias
30
+
31
+ alias cm='chromarks'
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/chromarks ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'chromarks'
4
+
5
+ if ARGV.empty?
6
+ Chromarks.list
7
+ else
8
+ if ARGV.first =~ /^\d+$/
9
+ Chromarks.open(ARGV.first.to_i)
10
+ else
11
+ Chromarks.search(ARGV.join(' ').chomp)
12
+ end
13
+ end
data/chromarks.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chromarks/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'chromarks'
8
+ gem.version = Chromarks::VERSION
9
+ gem.authors = ['Jesper Kjeldgaard']
10
+ gem.email = ['thejspr@gmail.com']
11
+ gem.description = %q{Search, list and open Chrome bookmarks in your terminal.}
12
+ gem.summary = %q{Search, list and open Chrome bookmarks in your terminal.}
13
+ gem.homepage = 'https://github.com/thejspr/chromarks'
14
+ gem.license = 'MIT'
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ['lib']
20
+
21
+ gem.add_development_dependency 'pry'
22
+ gem.add_development_dependency 'rake'
23
+ gem.add_development_dependency 'rspec', '~> 2.12'
24
+ end
@@ -0,0 +1,69 @@
1
+ require 'json'
2
+
3
+ module Chromarks
4
+ class CLI
5
+ def initialize(options = {})
6
+ @options = options
7
+ parse_bookmarks
8
+ sort_bookmarks
9
+ end
10
+
11
+ def open
12
+ system("open '#{find(@options[:id])['url']}'")
13
+ end
14
+
15
+ def search
16
+ bookmarks.collect do |bookmark|
17
+ bookmark if bookmark['name'] =~ /#{@options[:query]}/i
18
+ end.compact
19
+ end
20
+
21
+ def bookmarks
22
+ @bookmarks ||= Array.new
23
+ end
24
+
25
+ private
26
+
27
+ def find(id)
28
+ bookmarks.select { |bookmark| bookmark['id'] == id }.first
29
+ end
30
+
31
+ def parse_bookmarks
32
+ bookmarks_json.each do |node|
33
+ scan_node(node)
34
+ end
35
+ end
36
+
37
+ def sort_bookmarks
38
+ bookmarks.sort! { |first,second| first['id'] <=> second['id'] }
39
+ end
40
+
41
+ def scan_node(node)
42
+ if node['type'] == 'url'
43
+ bookmarks << node_to_bookmark(node)
44
+ elsif node['type'] == 'folder'
45
+ node['children'].each { |node| scan_node(node) }
46
+ end
47
+ end
48
+
49
+ def node_to_bookmark(node)
50
+ {
51
+ 'id' => node['id'].to_i,
52
+ 'name' => node['name'],
53
+ 'url' => node['url']
54
+ }
55
+ end
56
+
57
+ def bookmarks_json
58
+ json = JSON.parse(File.read(bookmarks_file))['roots']
59
+ result = json['bookmark_bar']['children']
60
+ result << json['other']
61
+
62
+ result
63
+ end
64
+
65
+ def bookmarks_file
66
+ File.expand_path(BOOKMARKS_FILE)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ module Chromarks
2
+ VERSION = "0.0.1"
3
+ end
data/lib/chromarks.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'chromarks/version'
2
+ require 'chromarks/cli'
3
+
4
+ module Chromarks
5
+ BOOKMARKS_FILE = '~/Library/Application Support/Google/Chrome/Default/Bookmarks'
6
+
7
+ def self.list
8
+ print_bookmarks(CLI.new.bookmarks)
9
+ end
10
+
11
+ def self.open(id)
12
+ CLI.new(id: id).open
13
+ end
14
+
15
+ def self.search(query)
16
+ print_bookmarks(CLI.new(query: query).search)
17
+ end
18
+
19
+ def self.print_bookmarks(bookmarks)
20
+ bookmarks.each do |bookmark|
21
+ puts "##{bookmark['id']}: #{bookmark['name']}"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chromarks::CLI do
4
+ before(:each) do
5
+ stub_const("Chromarks::BOOKMARKS_FILE", 'spec/fixtures/bookmarks.json')
6
+ end
7
+
8
+ describe '#new' do
9
+ let(:cli) { Chromarks::CLI.new }
10
+
11
+ it 'parses bookmarks' do
12
+ cli.bookmarks.size.should eq(3)
13
+ end
14
+ end
15
+
16
+ describe '#search' do
17
+ let(:cli) { Chromarks::CLI.new(query: 'clean') }
18
+ let(:results) { cli.search }
19
+
20
+ it 'returns matches for a given keyword' do
21
+ results.first['name'].should eq('Clean Coders')
22
+ results.size.should eq(1)
23
+ end
24
+ end
25
+
26
+ describe '#open' do
27
+ let(:cli) { Chromarks::CLI.new(id: 476) }
28
+ let(:expected_url) { 'http://wireframe.cc/' }
29
+
30
+ it 'finds and opens a bookmark' do
31
+ cli.should_receive(:system).with("open '#{expected_url}'")
32
+ cli.open
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chromarks do
4
+ it 'should have a version number' do
5
+ Chromarks::VERSION.should_not be_nil
6
+ end
7
+ end
@@ -0,0 +1,68 @@
1
+ {
2
+ "checksum" : "ee4e33746ab38ff2ac77dfd9c562ba5a",
3
+ "roots" : {
4
+ "meta_info" : "{\"sync\":{\"transaction_version\":\"419\"}}",
5
+ "other" : {
6
+ "date_added" : "12987524147420117",
7
+ "date_modified" : "12998672354629561",
8
+ "name" : "Other Bookmarks",
9
+ "children" : [
10
+ {
11
+ "date_added" : "12987524248810977",
12
+ "date_modified" : "13002118537391007",
13
+ "name" : "Tools",
14
+ "children" : [
15
+ {
16
+ "meta_info" : "{\"sync\":{\"transaction_version\":\"194\"}}",
17
+ "date_added" : "13001956877366454",
18
+ "name" : "wireframe.cc",
19
+ "url" : "http://wireframe.cc/",
20
+ "id" : "476",
21
+ "type" : "url"
22
+ }
23
+ ],
24
+ "id" : "22",
25
+ "type" : "folder"
26
+ }
27
+ ],
28
+ "id" : "2",
29
+ "type" : "folder"
30
+ },
31
+ "bookmark_bar" : {
32
+ "date_added" : "12987524147420105",
33
+ "date_modified" : "13003699479604625",
34
+ "name" : "Bookmarks Bar",
35
+ "children" : [
36
+ {
37
+ "meta_info" : "{\"sync\":{\"transaction_version\":\"197\"}}",
38
+ "date_added" : "12987524248809558",
39
+ "date_modified" : "13003699474315565",
40
+ "name" : "Learn stuff",
41
+ "children" : [
42
+ {
43
+ "meta_info" : "{\"sync\":{\"transaction_version\":\"194\"}}",
44
+ "date_added" : "12992087065239493",
45
+ "name" : "High Scalability - High Scalability - 7 Lessons Learned While Building Reddit to 270 Million Page Views a Month",
46
+ "url" : "http://highscalability.com/blog/2010/5/17/7-lessons-learned-while-building-reddit-to-270-million-page.html",
47
+ "id" : "451",
48
+ "type" : "url"
49
+ },
50
+ {
51
+ "meta_info" : "{\"sync\":{\"transaction_version\":\"194\"}}",
52
+ "date_added" : "13001987013560386",
53
+ "name" : "Clean Coders",
54
+ "url" : "http://www.cleancoders.com/",
55
+ "id" : "479",
56
+ "type" : "url"
57
+ }
58
+ ],
59
+ "id" : "4",
60
+ "type" : "folder"
61
+ }
62
+ ],
63
+ "id" : "1",
64
+ "type" : "folder"
65
+ }
66
+ },
67
+ "version" : 1
68
+ }
@@ -0,0 +1,14 @@
1
+ ENV['RACK_ENV'] ||= 'test'
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
+
5
+ require 'chromarks'
6
+
7
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
8
+
9
+ RSpec.configure do |config|
10
+ include CLIHelpers
11
+ include FixtureHelpers
12
+
13
+ config.mock_with :rspec
14
+ end
@@ -0,0 +1,34 @@
1
+ module CLIHelpers
2
+ def run(&block)
3
+ capture_stdout do
4
+ yield
5
+ end
6
+ end
7
+
8
+ def run_silent(cmd)
9
+ silence_stream($stdout) { run(cmd) }
10
+ end
11
+
12
+ def run_silent!(cmd)
13
+ silence_stream($stderr) { run_silent(cmd) }
14
+ end
15
+
16
+ def capture_stdout
17
+ real_stdout, $stdout = $stdout, StringIO.new
18
+ yield
19
+ $stdout.string
20
+ ensure
21
+ $stdout = real_stdout
22
+ end
23
+
24
+ private
25
+
26
+ def silence_stream(stream)
27
+ orig_stream = stream.dup
28
+ stream.reopen('/dev/null')
29
+ stream.sync = true
30
+ yield
31
+ ensure
32
+ stream.reopen(orig_stream)
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ module FixtureHelpers
2
+ def load_bookmarks
3
+ JSON.parse(File.read('spec/fixtures/bookmarks.json'))
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chromarks
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Jesper Kjeldgaard
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ prerelease: false
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ none: false
22
+ type: :development
23
+ name: pry
24
+ requirement: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ! '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ none: false
30
+ - !ruby/object:Gem::Dependency
31
+ prerelease: false
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ! '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ none: false
38
+ type: :development
39
+ name: rake
40
+ requirement: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ none: false
46
+ - !ruby/object:Gem::Dependency
47
+ prerelease: false
48
+ version_requirements: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ~>
51
+ - !ruby/object:Gem::Version
52
+ version: '2.12'
53
+ none: false
54
+ type: :development
55
+ name: rspec
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ version: '2.12'
61
+ none: false
62
+ description: Search, list and open Chrome bookmarks in your terminal.
63
+ email:
64
+ - thejspr@gmail.com
65
+ executables:
66
+ - chromarks
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - .rspec
72
+ - Gemfile
73
+ - Guardfile
74
+ - LICENSE.txt
75
+ - README.md
76
+ - Rakefile
77
+ - bin/chromarks
78
+ - chromarks.gemspec
79
+ - lib/chromarks.rb
80
+ - lib/chromarks/cli.rb
81
+ - lib/chromarks/version.rb
82
+ - spec/chromarks/cli_spec.rb
83
+ - spec/chromarks_spec.rb
84
+ - spec/fixtures/bookmarks.json
85
+ - spec/spec_helper.rb
86
+ - spec/support/cli_helpers.rb
87
+ - spec/support/fixture_helpers.rb
88
+ homepage: https://github.com/thejspr/chromarks
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ none: false
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ none: false
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 1.8.25
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Search, list and open Chrome bookmarks in your terminal.
113
+ test_files:
114
+ - spec/chromarks/cli_spec.rb
115
+ - spec/chromarks_spec.rb
116
+ - spec/fixtures/bookmarks.json
117
+ - spec/spec_helper.rb
118
+ - spec/support/cli_helpers.rb
119
+ - spec/support/fixture_helpers.rb
120
+ has_rdoc: