igist 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .tags
7
+ .tags_sorted_by_file
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in igist.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Yu Wang <wangyuhere@gmail.com>
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,31 @@
1
+ # IGist
2
+
3
+ IGist is a command line tool used to search your gists and starred gists by keyword of gist description. All your gists will be indexed using simple inversed index algorithm. And the index data is saved locally (~/.igist).
4
+
5
+ ## Installation
6
+
7
+ $ gem install igist
8
+
9
+ ## Usage
10
+
11
+ Before search your gists, authorize and index first:
12
+
13
+ $ igist -i
14
+
15
+ Search by keywords in description
16
+
17
+ $ igist -s ruby
18
+ $ igist -s "ruby rails"
19
+
20
+ For other options
21
+
22
+ $ igist -h
23
+
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task default: :spec
7
+ task test: :spec
data/bin/igist ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'igist'
4
+
5
+ IGist::CLI.new.run
data/igist.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'igist/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "igist"
8
+ spec.version = IGist::VERSION
9
+ spec.authors = ["Yu Wang"]
10
+ spec.email = ["wangyuhere@gmail.com"]
11
+ spec.description = %q{IGist is a command line tool used to search your gists and starred gists by keyword of gist description.}
12
+ spec.summary = %q{Search your gists and starred gists by keyword of gist description}
13
+ spec.homepage = "https://github.com/wangyuhere/igist"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
data/lib/igist/api.rb ADDED
@@ -0,0 +1,106 @@
1
+ module IGist
2
+ class API
3
+
4
+ def initialize(options={})
5
+ @username = options[:username]
6
+ @token = options[:token]
7
+ @api_uri = URI("https://api.github.com")
8
+ end
9
+
10
+ def has_token?
11
+ !@token.nil?
12
+ end
13
+
14
+ def create_authorization(username, password)
15
+ request = Net::HTTP::Post.new(authorization_url)
16
+ request.body = JSON.dump({
17
+ scopes: [:gist],
18
+ note: "The igist gem",
19
+ note_url: ""
20
+ })
21
+ request.content_type = "application/json"
22
+ request.basic_auth(username, password)
23
+ response = send_request(request)
24
+
25
+ if response.is_a?(Net::HTTPUnauthorized) && response["X-GitHub-OTP"]
26
+ print "two factor authentication code: "
27
+ otp = $stdin.gets.strip
28
+ puts ""
29
+ request["X-GitHub-OTP"] = otp
30
+ response = send_request(request)
31
+ end
32
+
33
+ if response.is_a?(Net::HTTPCreated)
34
+ result = JSON.parse(response.body)
35
+ @token = result["token"]
36
+ @username = username
37
+ yield result if block_given?
38
+ else
39
+ raise "Can not authorize because: #{response.body}"
40
+ end
41
+ end
42
+
43
+ def each_my_gist(&block)
44
+ each_gist(gists_url, &block)
45
+ end
46
+
47
+ def each_starred_gist(&block)
48
+ each_gist(starred_gists_url, &block)
49
+ end
50
+
51
+ private
52
+
53
+ def each_gist(url, &block)
54
+ request = Net::HTTP::Get.new(url)
55
+ connection.start do |http|
56
+ while true
57
+ response = http.request(request)
58
+ gists = JSON.parse(response.body)
59
+ gists.each { |g| block.call(g) }
60
+ break if response["Links"].nil?
61
+ if match = response["Links"].match(/<(.*)>;\s*rel=\"next\"/)
62
+ request = Net::HTTP::Get.new(match.captures[0])
63
+ else
64
+ raise "Invalid Links format: #{response['Links']}"
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ def connection
71
+ connection = Net::HTTP.new(@api_uri.host, @api_uri.port)
72
+ connection.use_ssl = true
73
+ connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
74
+ connection.open_timeout = 10
75
+ connection.read_timeout = 10
76
+ connection
77
+ end
78
+
79
+ def send_request(request)
80
+ connection.start do |http|
81
+ http.request(request)
82
+ end
83
+ end
84
+
85
+ def api_url
86
+ "https://api.github.com"
87
+ end
88
+
89
+ def authorization_url
90
+ "#{api_url}/authorizations"
91
+ end
92
+
93
+ def gists_url
94
+ append_token "#{api_url}/users/#{@username}/gists"
95
+ end
96
+
97
+ def starred_gists_url
98
+ append_token "#{api_url}/gists/starred"
99
+ end
100
+
101
+ def append_token(url)
102
+ "#{url}?access_token=#{@token}"
103
+ end
104
+
105
+ end
106
+ end
data/lib/igist/cli.rb ADDED
@@ -0,0 +1,118 @@
1
+ require "io/console"
2
+ require "optparse"
3
+ require "igist/version"
4
+ require "igist/igist"
5
+
6
+ module IGist
7
+
8
+ class CLI
9
+
10
+ def initialize(igist=nil)
11
+ @igist = igist || IGist.new
12
+ end
13
+
14
+ def run
15
+ options = {}
16
+ opts = OptionParser.new do |opt|
17
+
18
+ opt.banner = <<-EOS
19
+ Index and search your gists on github.
20
+
21
+ Note: Run "igist -i" before your first search or if your gists are changed.
22
+ You can also "igist -i -s KEYWORD" to first index and then search.
23
+
24
+ Usage: igist [-i|-u|-v]
25
+ igist [-t|-a] -s KEYWORD
26
+
27
+ Options:
28
+ EOS
29
+
30
+ opt.on("-v", "--version", "Show version") do
31
+ puts VERSION
32
+ end
33
+
34
+ opt.on("-i", "--index", "Index your gists") do
35
+ index
36
+ end
37
+
38
+ opt.on("-u", "--auth", "Authorize igist") do
39
+ authorize
40
+ end
41
+
42
+ opt.on("-s", "--search KEYWORD", "Search your own gists by keyword in description") do |keyword|
43
+ options[:search] = keyword
44
+ end
45
+
46
+ opt.on("-t", "--starred", "Only your starred gists") do
47
+ options[:starred] = true
48
+ end
49
+
50
+ opt.on("-a", "--all", "Both your gists and starred gists") do
51
+ options[:all] = true
52
+ end
53
+
54
+ opt.on("--clear", "Remove your gists index data locally") do
55
+ clear
56
+ end
57
+
58
+ end
59
+
60
+ opts.parse!
61
+
62
+ if options[:search]
63
+ search(options)
64
+ end
65
+
66
+ end
67
+
68
+ def authorize
69
+ puts "Authorize igist and fetch access token from Github."
70
+ print "Github username: "
71
+ username = $stdin.gets.strip
72
+ print "Github password: "
73
+ password = $stdin.noecho(&:gets).strip
74
+ puts ""
75
+
76
+ @igist.authorize(username, password)
77
+ puts "Authorized!"
78
+ end
79
+
80
+ def index
81
+ authorize unless @igist.has_token?
82
+ puts "Fetching and indexing your gists ..."
83
+ @igist.index
84
+ puts "Indexed #{@igist.my_gists.size} gists and #{@igist.starred_gists.size} starred gists!"
85
+ end
86
+
87
+ def search(options)
88
+ keyword = options[:search]
89
+
90
+ unless options[:starred]
91
+ print_result("My Own Gists", @igist.search(keyword))
92
+ end
93
+
94
+ if options[:all] or options[:starred]
95
+ print_result("My Starred Gists", @igist.search_starred(keyword))
96
+ end
97
+ end
98
+
99
+ def clear
100
+ @igist.clear
101
+ puts "Your local index files are deleted!"
102
+ end
103
+
104
+ private
105
+
106
+ def print_result(title, result)
107
+ puts "#{title}: "
108
+ if result.empty?
109
+ puts "Nothing found."
110
+ else
111
+ result.each { |gist| puts "#{gist[:id]} \t #{gist[:description]}" }
112
+ end
113
+ puts ""
114
+ end
115
+
116
+ end
117
+
118
+ end
@@ -0,0 +1,107 @@
1
+ require "json"
2
+ require "net/https"
3
+ require "uri"
4
+ require "igist/api"
5
+ require "igist/search"
6
+
7
+ module IGist
8
+
9
+ class IGist
10
+ include Search
11
+
12
+ attr_reader :path, :token_file, :my_gists_file, :my_gists_index_file, :starred_gists_file, :starred_gists_index_file
13
+
14
+ def initialize(options={})
15
+ @path = options[:path] || File.expand_path("~/.igist")
16
+ @token_file = options[:token_file] || File.join(@path, "token")
17
+ @my_gists_file = options[:my_gists_file] || File.join(@path, "my_gists")
18
+ @my_gists_index_file = options[:my_gists_index_file] || File.join(@path, "my_gists_index")
19
+ @starred_gists_file = options[:starred_gists_file] || File.join(@path, "starred_gists")
20
+ @starred_gists_index_file = options[:starred_gists_index_file] || File.join(@path, "starred_gists_index")
21
+ Dir.mkdir(@path) unless File.exists?(@path)
22
+ @api = options[:api]
23
+ end
24
+
25
+ # igist is authorized or not
26
+ def has_token?
27
+ api.has_token?
28
+ end
29
+
30
+ def api
31
+ if @api.nil?
32
+ token_json = read_json_file(token_file)
33
+ @api = API.new({username: token_json['username'], token: token_json['token']})
34
+ end
35
+ @api
36
+ end
37
+
38
+ def my_gists
39
+ @my_gists ||= read_json_file(my_gists_file)
40
+ end
41
+
42
+ def starred_gists
43
+ @starred_gists ||= read_json_file(starred_gists_file)
44
+ end
45
+
46
+ def my_gists_index
47
+ @my_gists_index ||= read_json_file(my_gists_index_file)
48
+ end
49
+
50
+ def starred_gists_index
51
+ @starred_gists_index ||= read_json_file(starred_gists_index_file)
52
+ end
53
+
54
+ # authorize igist and save username and token in token file
55
+ def authorize(username, password)
56
+ api.create_authorization(username, password) do |res|
57
+ write_json_file({username: username, token: res["token"]}, token_file)
58
+ end
59
+ end
60
+
61
+ # fetch all gists data from api and write data and index files
62
+ def index
63
+ @my_gists = {}
64
+ @starred_gists = {}
65
+
66
+ api.each_my_gist { |g| @my_gists[g["id"]] = g["description"]}
67
+ api.each_starred_gist { |g| @starred_gists[g["id"]] = g["description"]}
68
+ write_json_file(my_gists, my_gists_file)
69
+ write_json_file(starred_gists, starred_gists_file)
70
+
71
+ @my_gists_index = build_index(my_gists)
72
+ @starred_gists_index = build_index(starred_gists)
73
+ write_json_file(my_gists_index, my_gists_index_file)
74
+ write_json_file(starred_gists_index, starred_gists_index_file)
75
+ end
76
+
77
+ def search(keyword)
78
+ search_index(my_gists_index, keyword).map { |id| {id: id, description: my_gists[id]} }
79
+ end
80
+
81
+ def search_starred(keyword)
82
+ search_index(starred_gists_index, keyword).map { |id| {id: id, description: starred_gists[id]} }
83
+ end
84
+
85
+ def clear
86
+ File.delete(my_gists_file, my_gists_index_file, starred_gists_file, starred_gists_index_file)
87
+ end
88
+
89
+ private
90
+
91
+ def read_json_file(file)
92
+ if File.exists?(file)
93
+ JSON.parse(File.read(file))
94
+ else
95
+ {}
96
+ end
97
+ end
98
+
99
+ def write_json_file(data, file)
100
+ File.open(file, 'w', 0600) do |f|
101
+ f.write(data.to_json)
102
+ end
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,35 @@
1
+ require "set"
2
+
3
+ module IGist
4
+ module Search
5
+ def build_index(data)
6
+ index = {}
7
+ data.each { |id, desc| add_to_index(index, id, desc) }
8
+ index.each { |key, value| index[key].uniq! }
9
+ index
10
+ end
11
+
12
+ def search_index(index, keyword)
13
+ result = []
14
+ split_words(keyword).each { |p| result.concat(index[p]) if index.has_key?(p)}
15
+ result.uniq
16
+ end
17
+
18
+ private
19
+
20
+ def add_to_index(index, id, desc)
21
+ split_words(desc).each do |w|
22
+ if index.has_key? w
23
+ index[w] << id
24
+ else
25
+ index[w] = [id]
26
+ end
27
+ end
28
+ end
29
+
30
+ def split_words(str)
31
+ str.downcase.split(/\W/).reject { |s| s.empty? }
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module IGist
2
+ VERSION = "0.0.1"
3
+ end
data/lib/igist.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "igist/version"
2
+ require "igist/igist"
3
+ require "igist/cli"
@@ -0,0 +1,170 @@
1
+ [
2
+ {
3
+ "url": "https://api.github.com/gists/3976350",
4
+ "forks_url": "https://api.github.com/gists/3976350/forks",
5
+ "commits_url": "https://api.github.com/gists/3976350/commits",
6
+ "id": "3976350",
7
+ "git_pull_url": "https://gist.github.com/3976350.git",
8
+ "git_push_url": "https://gist.github.com/3976350.git",
9
+ "html_url": "https://gist.github.com/3976350",
10
+ "files": {
11
+ "gistfile1.py": {
12
+ "filename": "gistfile1.py",
13
+ "type": "application/python",
14
+ "language": "Python",
15
+ "raw_url": "https://gist.github.com/raw/3976350/34d9d2aaee91d9a9143920520978a7af8aa7cf38/gistfile1.py",
16
+ "size": 996
17
+ }
18
+ },
19
+ "public": true,
20
+ "created_at": "2012-10-29T20:34:15Z",
21
+ "updated_at": "2012-10-29T20:34:15Z",
22
+ "description": "Python: decorator example",
23
+ "comments": 0,
24
+ "user": {
25
+ "login": "wangyuhere",
26
+ "id": 507117,
27
+ "avatar_url": "https://1.gravatar.com/avatar/6180782d31832757305473d48edf3b17?d=https%3A%2F%2Fidenticons.github.com%2F0c8d010a6fd398b2b1c4ef3c635922c6.png",
28
+ "gravatar_id": "6180782d31832757305473d48edf3b17",
29
+ "url": "https://api.github.com/users/wangyuhere",
30
+ "html_url": "https://github.com/wangyuhere",
31
+ "followers_url": "https://api.github.com/users/wangyuhere/followers",
32
+ "following_url": "https://api.github.com/users/wangyuhere/following{/other_user}",
33
+ "gists_url": "https://api.github.com/users/wangyuhere/gists{/gist_id}",
34
+ "starred_url": "https://api.github.com/users/wangyuhere/starred{/owner}{/repo}",
35
+ "subscriptions_url": "https://api.github.com/users/wangyuhere/subscriptions",
36
+ "organizations_url": "https://api.github.com/users/wangyuhere/orgs",
37
+ "repos_url": "https://api.github.com/users/wangyuhere/repos",
38
+ "events_url": "https://api.github.com/users/wangyuhere/events{/privacy}",
39
+ "received_events_url": "https://api.github.com/users/wangyuhere/received_events",
40
+ "type": "User"
41
+ },
42
+ "comments_url": "https://api.github.com/gists/3976350/comments"
43
+ },
44
+ {
45
+ "url": "https://api.github.com/gists/2926498",
46
+ "forks_url": "https://api.github.com/gists/2926498/forks",
47
+ "commits_url": "https://api.github.com/gists/2926498/commits",
48
+ "id": "2926498",
49
+ "git_pull_url": "https://gist.github.com/2926498.git",
50
+ "git_push_url": "https://gist.github.com/2926498.git",
51
+ "html_url": "https://gist.github.com/2926498",
52
+ "files": {
53
+ "ubuntu_install.sh": {
54
+ "filename": "ubuntu_install.sh",
55
+ "type": "application/sh",
56
+ "language": "Shell",
57
+ "raw_url": "https://gist.github.com/raw/2926498/323ee03f4386492a575a913c4a0c1d073727f914/ubuntu_install.sh",
58
+ "size": 855
59
+ }
60
+ },
61
+ "public": true,
62
+ "created_at": "2012-06-13T21:04:04Z",
63
+ "updated_at": "2012-10-07T20:46:24Z",
64
+ "description": "sh: Install LAMP/nginx/ssh/java on ubuntu server",
65
+ "comments": 0,
66
+ "user": {
67
+ "login": "wangyuhere",
68
+ "id": 507117,
69
+ "avatar_url": "https://1.gravatar.com/avatar/6180782d31832757305473d48edf3b17?d=https%3A%2F%2Fidenticons.github.com%2F0c8d010a6fd398b2b1c4ef3c635922c6.png",
70
+ "gravatar_id": "6180782d31832757305473d48edf3b17",
71
+ "url": "https://api.github.com/users/wangyuhere",
72
+ "html_url": "https://github.com/wangyuhere",
73
+ "followers_url": "https://api.github.com/users/wangyuhere/followers",
74
+ "following_url": "https://api.github.com/users/wangyuhere/following{/other_user}",
75
+ "gists_url": "https://api.github.com/users/wangyuhere/gists{/gist_id}",
76
+ "starred_url": "https://api.github.com/users/wangyuhere/starred{/owner}{/repo}",
77
+ "subscriptions_url": "https://api.github.com/users/wangyuhere/subscriptions",
78
+ "organizations_url": "https://api.github.com/users/wangyuhere/orgs",
79
+ "repos_url": "https://api.github.com/users/wangyuhere/repos",
80
+ "events_url": "https://api.github.com/users/wangyuhere/events{/privacy}",
81
+ "received_events_url": "https://api.github.com/users/wangyuhere/received_events",
82
+ "type": "User"
83
+ },
84
+ "comments_url": "https://api.github.com/gists/2926498/comments"
85
+ },
86
+ {
87
+ "url": "https://api.github.com/gists/2926422",
88
+ "forks_url": "https://api.github.com/gists/2926422/forks",
89
+ "commits_url": "https://api.github.com/gists/2926422/commits",
90
+ "id": "2926422",
91
+ "git_pull_url": "https://gist.github.com/2926422.git",
92
+ "git_push_url": "https://gist.github.com/2926422.git",
93
+ "html_url": "https://gist.github.com/2926422",
94
+ "files": {
95
+ "install_vmware_tools.sh": {
96
+ "filename": "install_vmware_tools.sh",
97
+ "type": "application/sh",
98
+ "language": "Shell",
99
+ "raw_url": "https://gist.github.com/raw/2926422/0a446cb5b96fb553cc624f7bc87ccd1cb40d5499/install_vmware_tools.sh",
100
+ "size": 722
101
+ }
102
+ },
103
+ "public": true,
104
+ "created_at": "2012-06-13T20:46:03Z",
105
+ "updated_at": "2012-10-07T20:44:58Z",
106
+ "description": "sh: Install VMWare Tools Ubuntu Server",
107
+ "comments": 0,
108
+ "user": {
109
+ "login": "wangyuhere",
110
+ "id": 507117,
111
+ "avatar_url": "https://1.gravatar.com/avatar/6180782d31832757305473d48edf3b17?d=https%3A%2F%2Fidenticons.github.com%2F0c8d010a6fd398b2b1c4ef3c635922c6.png",
112
+ "gravatar_id": "6180782d31832757305473d48edf3b17",
113
+ "url": "https://api.github.com/users/wangyuhere",
114
+ "html_url": "https://github.com/wangyuhere",
115
+ "followers_url": "https://api.github.com/users/wangyuhere/followers",
116
+ "following_url": "https://api.github.com/users/wangyuhere/following{/other_user}",
117
+ "gists_url": "https://api.github.com/users/wangyuhere/gists{/gist_id}",
118
+ "starred_url": "https://api.github.com/users/wangyuhere/starred{/owner}{/repo}",
119
+ "subscriptions_url": "https://api.github.com/users/wangyuhere/subscriptions",
120
+ "organizations_url": "https://api.github.com/users/wangyuhere/orgs",
121
+ "repos_url": "https://api.github.com/users/wangyuhere/repos",
122
+ "events_url": "https://api.github.com/users/wangyuhere/events{/privacy}",
123
+ "received_events_url": "https://api.github.com/users/wangyuhere/received_events",
124
+ "type": "User"
125
+ },
126
+ "comments_url": "https://api.github.com/gists/2926422/comments"
127
+ },
128
+ {
129
+ "url": "https://api.github.com/gists/2414378",
130
+ "forks_url": "https://api.github.com/gists/2414378/forks",
131
+ "commits_url": "https://api.github.com/gists/2414378/commits",
132
+ "id": "2414378",
133
+ "git_pull_url": "https://gist.github.com/2414378.git",
134
+ "git_push_url": "https://gist.github.com/2414378.git",
135
+ "html_url": "https://gist.github.com/2414378",
136
+ "files": {
137
+ "git_commands.sh": {
138
+ "filename": "git_commands.sh",
139
+ "type": "application/sh",
140
+ "language": "Shell",
141
+ "raw_url": "https://gist.github.com/raw/2414378/048a659535b0595a427a3bed21a71d8e61b0eac5/git_commands.sh",
142
+ "size": 688
143
+ }
144
+ },
145
+ "public": true,
146
+ "created_at": "2012-04-18T15:34:11Z",
147
+ "updated_at": "2013-05-04T09:40:35Z",
148
+ "description": "git: basic git command",
149
+ "comments": 0,
150
+ "user": {
151
+ "login": "wangyuhere",
152
+ "id": 507117,
153
+ "avatar_url": "https://1.gravatar.com/avatar/6180782d31832757305473d48edf3b17?d=https%3A%2F%2Fidenticons.github.com%2F0c8d010a6fd398b2b1c4ef3c635922c6.png",
154
+ "gravatar_id": "6180782d31832757305473d48edf3b17",
155
+ "url": "https://api.github.com/users/wangyuhere",
156
+ "html_url": "https://github.com/wangyuhere",
157
+ "followers_url": "https://api.github.com/users/wangyuhere/followers",
158
+ "following_url": "https://api.github.com/users/wangyuhere/following{/other_user}",
159
+ "gists_url": "https://api.github.com/users/wangyuhere/gists{/gist_id}",
160
+ "starred_url": "https://api.github.com/users/wangyuhere/starred{/owner}{/repo}",
161
+ "subscriptions_url": "https://api.github.com/users/wangyuhere/subscriptions",
162
+ "organizations_url": "https://api.github.com/users/wangyuhere/orgs",
163
+ "repos_url": "https://api.github.com/users/wangyuhere/repos",
164
+ "events_url": "https://api.github.com/users/wangyuhere/events{/privacy}",
165
+ "received_events_url": "https://api.github.com/users/wangyuhere/received_events",
166
+ "type": "User"
167
+ },
168
+ "comments_url": "https://api.github.com/gists/2414378/comments"
169
+ }
170
+ ]
@@ -0,0 +1,170 @@
1
+ [
2
+ {
3
+ "url": "https://api.github.com/gists/3976350",
4
+ "forks_url": "https://api.github.com/gists/3976350/forks",
5
+ "commits_url": "https://api.github.com/gists/3976350/commits",
6
+ "id": "3976350",
7
+ "git_pull_url": "https://gist.github.com/3976350.git",
8
+ "git_push_url": "https://gist.github.com/3976350.git",
9
+ "html_url": "https://gist.github.com/3976350",
10
+ "files": {
11
+ "gistfile1.py": {
12
+ "filename": "gistfile1.py",
13
+ "type": "application/python",
14
+ "language": "Python",
15
+ "raw_url": "https://gist.github.com/raw/3976350/34d9d2aaee91d9a9143920520978a7af8aa7cf38/gistfile1.py",
16
+ "size": 996
17
+ }
18
+ },
19
+ "public": true,
20
+ "created_at": "2012-10-29T20:34:15Z",
21
+ "updated_at": "2012-10-29T20:34:15Z",
22
+ "description": "Python: decorator example",
23
+ "comments": 0,
24
+ "user": {
25
+ "login": "wangyuhere",
26
+ "id": 507117,
27
+ "avatar_url": "https://1.gravatar.com/avatar/6180782d31832757305473d48edf3b17?d=https%3A%2F%2Fidenticons.github.com%2F0c8d010a6fd398b2b1c4ef3c635922c6.png",
28
+ "gravatar_id": "6180782d31832757305473d48edf3b17",
29
+ "url": "https://api.github.com/users/wangyuhere",
30
+ "html_url": "https://github.com/wangyuhere",
31
+ "followers_url": "https://api.github.com/users/wangyuhere/followers",
32
+ "following_url": "https://api.github.com/users/wangyuhere/following{/other_user}",
33
+ "gists_url": "https://api.github.com/users/wangyuhere/gists{/gist_id}",
34
+ "starred_url": "https://api.github.com/users/wangyuhere/starred{/owner}{/repo}",
35
+ "subscriptions_url": "https://api.github.com/users/wangyuhere/subscriptions",
36
+ "organizations_url": "https://api.github.com/users/wangyuhere/orgs",
37
+ "repos_url": "https://api.github.com/users/wangyuhere/repos",
38
+ "events_url": "https://api.github.com/users/wangyuhere/events{/privacy}",
39
+ "received_events_url": "https://api.github.com/users/wangyuhere/received_events",
40
+ "type": "User"
41
+ },
42
+ "comments_url": "https://api.github.com/gists/3976350/comments"
43
+ },
44
+ {
45
+ "url": "https://api.github.com/gists/2926498",
46
+ "forks_url": "https://api.github.com/gists/2926498/forks",
47
+ "commits_url": "https://api.github.com/gists/2926498/commits",
48
+ "id": "2926498",
49
+ "git_pull_url": "https://gist.github.com/2926498.git",
50
+ "git_push_url": "https://gist.github.com/2926498.git",
51
+ "html_url": "https://gist.github.com/2926498",
52
+ "files": {
53
+ "ubuntu_install.sh": {
54
+ "filename": "ubuntu_install.sh",
55
+ "type": "application/sh",
56
+ "language": "Shell",
57
+ "raw_url": "https://gist.github.com/raw/2926498/323ee03f4386492a575a913c4a0c1d073727f914/ubuntu_install.sh",
58
+ "size": 855
59
+ }
60
+ },
61
+ "public": true,
62
+ "created_at": "2012-06-13T21:04:04Z",
63
+ "updated_at": "2012-10-07T20:46:24Z",
64
+ "description": "sh: Install LAMP/nginx/ssh/java on ubuntu server",
65
+ "comments": 0,
66
+ "user": {
67
+ "login": "wangyuhere",
68
+ "id": 507117,
69
+ "avatar_url": "https://1.gravatar.com/avatar/6180782d31832757305473d48edf3b17?d=https%3A%2F%2Fidenticons.github.com%2F0c8d010a6fd398b2b1c4ef3c635922c6.png",
70
+ "gravatar_id": "6180782d31832757305473d48edf3b17",
71
+ "url": "https://api.github.com/users/wangyuhere",
72
+ "html_url": "https://github.com/wangyuhere",
73
+ "followers_url": "https://api.github.com/users/wangyuhere/followers",
74
+ "following_url": "https://api.github.com/users/wangyuhere/following{/other_user}",
75
+ "gists_url": "https://api.github.com/users/wangyuhere/gists{/gist_id}",
76
+ "starred_url": "https://api.github.com/users/wangyuhere/starred{/owner}{/repo}",
77
+ "subscriptions_url": "https://api.github.com/users/wangyuhere/subscriptions",
78
+ "organizations_url": "https://api.github.com/users/wangyuhere/orgs",
79
+ "repos_url": "https://api.github.com/users/wangyuhere/repos",
80
+ "events_url": "https://api.github.com/users/wangyuhere/events{/privacy}",
81
+ "received_events_url": "https://api.github.com/users/wangyuhere/received_events",
82
+ "type": "User"
83
+ },
84
+ "comments_url": "https://api.github.com/gists/2926498/comments"
85
+ },
86
+ {
87
+ "url": "https://api.github.com/gists/2926422",
88
+ "forks_url": "https://api.github.com/gists/2926422/forks",
89
+ "commits_url": "https://api.github.com/gists/2926422/commits",
90
+ "id": "2926422",
91
+ "git_pull_url": "https://gist.github.com/2926422.git",
92
+ "git_push_url": "https://gist.github.com/2926422.git",
93
+ "html_url": "https://gist.github.com/2926422",
94
+ "files": {
95
+ "install_vmware_tools.sh": {
96
+ "filename": "install_vmware_tools.sh",
97
+ "type": "application/sh",
98
+ "language": "Shell",
99
+ "raw_url": "https://gist.github.com/raw/2926422/0a446cb5b96fb553cc624f7bc87ccd1cb40d5499/install_vmware_tools.sh",
100
+ "size": 722
101
+ }
102
+ },
103
+ "public": true,
104
+ "created_at": "2012-06-13T20:46:03Z",
105
+ "updated_at": "2012-10-07T20:44:58Z",
106
+ "description": "sh: Install VMWare Tools Ubuntu Server",
107
+ "comments": 0,
108
+ "user": {
109
+ "login": "wangyuhere",
110
+ "id": 507117,
111
+ "avatar_url": "https://1.gravatar.com/avatar/6180782d31832757305473d48edf3b17?d=https%3A%2F%2Fidenticons.github.com%2F0c8d010a6fd398b2b1c4ef3c635922c6.png",
112
+ "gravatar_id": "6180782d31832757305473d48edf3b17",
113
+ "url": "https://api.github.com/users/wangyuhere",
114
+ "html_url": "https://github.com/wangyuhere",
115
+ "followers_url": "https://api.github.com/users/wangyuhere/followers",
116
+ "following_url": "https://api.github.com/users/wangyuhere/following{/other_user}",
117
+ "gists_url": "https://api.github.com/users/wangyuhere/gists{/gist_id}",
118
+ "starred_url": "https://api.github.com/users/wangyuhere/starred{/owner}{/repo}",
119
+ "subscriptions_url": "https://api.github.com/users/wangyuhere/subscriptions",
120
+ "organizations_url": "https://api.github.com/users/wangyuhere/orgs",
121
+ "repos_url": "https://api.github.com/users/wangyuhere/repos",
122
+ "events_url": "https://api.github.com/users/wangyuhere/events{/privacy}",
123
+ "received_events_url": "https://api.github.com/users/wangyuhere/received_events",
124
+ "type": "User"
125
+ },
126
+ "comments_url": "https://api.github.com/gists/2926422/comments"
127
+ },
128
+ {
129
+ "url": "https://api.github.com/gists/2414378",
130
+ "forks_url": "https://api.github.com/gists/2414378/forks",
131
+ "commits_url": "https://api.github.com/gists/2414378/commits",
132
+ "id": "2414378",
133
+ "git_pull_url": "https://gist.github.com/2414378.git",
134
+ "git_push_url": "https://gist.github.com/2414378.git",
135
+ "html_url": "https://gist.github.com/2414378",
136
+ "files": {
137
+ "git_commands.sh": {
138
+ "filename": "git_commands.sh",
139
+ "type": "application/sh",
140
+ "language": "Shell",
141
+ "raw_url": "https://gist.github.com/raw/2414378/048a659535b0595a427a3bed21a71d8e61b0eac5/git_commands.sh",
142
+ "size": 688
143
+ }
144
+ },
145
+ "public": true,
146
+ "created_at": "2012-04-18T15:34:11Z",
147
+ "updated_at": "2013-05-04T09:40:35Z",
148
+ "description": "git: basic git command",
149
+ "comments": 0,
150
+ "user": {
151
+ "login": "wangyuhere",
152
+ "id": 507117,
153
+ "avatar_url": "https://1.gravatar.com/avatar/6180782d31832757305473d48edf3b17?d=https%3A%2F%2Fidenticons.github.com%2F0c8d010a6fd398b2b1c4ef3c635922c6.png",
154
+ "gravatar_id": "6180782d31832757305473d48edf3b17",
155
+ "url": "https://api.github.com/users/wangyuhere",
156
+ "html_url": "https://github.com/wangyuhere",
157
+ "followers_url": "https://api.github.com/users/wangyuhere/followers",
158
+ "following_url": "https://api.github.com/users/wangyuhere/following{/other_user}",
159
+ "gists_url": "https://api.github.com/users/wangyuhere/gists{/gist_id}",
160
+ "starred_url": "https://api.github.com/users/wangyuhere/starred{/owner}{/repo}",
161
+ "subscriptions_url": "https://api.github.com/users/wangyuhere/subscriptions",
162
+ "organizations_url": "https://api.github.com/users/wangyuhere/orgs",
163
+ "repos_url": "https://api.github.com/users/wangyuhere/repos",
164
+ "events_url": "https://api.github.com/users/wangyuhere/events{/privacy}",
165
+ "received_events_url": "https://api.github.com/users/wangyuhere/received_events",
166
+ "type": "User"
167
+ },
168
+ "comments_url": "https://api.github.com/gists/2414378/comments"
169
+ }
170
+ ]
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+ require "fileutils"
3
+
4
+ describe "IGist" do
5
+
6
+ let(:igist) {
7
+ path = File.expand_path("tmp", File.dirname(__FILE__))
8
+ FileUtils.rm_rf(path)
9
+ IGist::IGist.new(path: path, api: double("api"))
10
+ }
11
+
12
+ after(:each) do
13
+ FileUtils.rm_rf(igist.path)
14
+ end
15
+
16
+ shared_context "index" do
17
+ let(:gists) { load_json_fixture :gists }
18
+ let(:starred_gists) { load_json_fixture :starred_gists }
19
+
20
+ def add_index
21
+ each_my_gist = receive(:each_my_gist)
22
+ gists.each { |g| each_my_gist.and_yield(g) }
23
+ allow(igist.api).to each_my_gist
24
+
25
+ each_starred_gist = receive(:each_starred_gist)
26
+ starred_gists.each { |g| each_starred_gist.and_yield(g) }
27
+ allow(igist.api).to each_starred_gist
28
+
29
+ igist.index
30
+ end
31
+ end
32
+
33
+ describe "authorize" do
34
+ it "should call api authorize, save username and token to json file" do
35
+ token_data = {username: "test", token: "token"}
36
+ password = "password"
37
+
38
+ allow(igist.api).to receive(:create_authorization).with(token_data[:username], password).and_yield("token" => token_data[:token])
39
+ igist.authorize(token_data[:username], password)
40
+ expect(File.read(igist.token_file)).to eql(token_data.to_json)
41
+ end
42
+ end
43
+
44
+ describe "index" do
45
+ include_context "index"
46
+ it "should write gists and starred gists data and index files" do
47
+ add_index
48
+ expect(File.exists?(igist.my_gists_index_file)).to be_true
49
+ expect(File.exists?(igist.starred_gists_index_file)).to be_true
50
+ expect(igist.my_gists.size).to eql(gists.size)
51
+ end
52
+ end
53
+
54
+ describe "search" do
55
+ include_context "index"
56
+ it "should search the gists description based on keyword" do
57
+ add_index
58
+ result = igist.search("sh")
59
+ expect(result.size).to eql(2)
60
+ expect(result.first[:id]).to eql("2926498")
61
+ expect(result.last[:id]).to eql("2926422")
62
+ expect(igist.search_starred("sh").size).to eql(2)
63
+ end
64
+ end
65
+
66
+ describe "clear" do
67
+ include_context "index"
68
+ it "should delete data and index files" do
69
+ add_index
70
+ igist.clear
71
+ files = [:my_gists_file, :my_gists_index_file, :starred_gists_file, :starred_gists_index_file]
72
+ files.each { |f| expect(File.exists?(igist.send(f))).to be_false }
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ describe "Search" do
4
+ include IGist::Search
5
+
6
+ let(:data) {
7
+ {
8
+ "1" => "a b a",
9
+ "2" => "b c b",
10
+ "3" => "c"
11
+ }
12
+ }
13
+
14
+ let(:index) {
15
+ {
16
+ "a" => ["1"],
17
+ "b" => ["1", "2"],
18
+ "c" => ["2", "3"]
19
+ }
20
+ }
21
+
22
+ describe "build_index" do
23
+ it "should build inverse index" do
24
+ expect(build_index(data)).to eql(index)
25
+ end
26
+ end
27
+
28
+ describe "search_index" do
29
+ it "should return correct search result" do
30
+ expect(search_index(index, "a")).to eql(["1"])
31
+ expect(search_index(index, "a b")).to eql(["1", "2"])
32
+ expect(search_index(index, "xxx")).to eql([])
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,7 @@
1
+ require "igist"
2
+
3
+ def load_json_fixture(name)
4
+ path = File.expand_path("fixtures", File.dirname(__FILE__))
5
+ file = File.join(path, "#{name.to_s}.json")
6
+ JSON.parse(File.read(file))
7
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: igist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yu Wang
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: IGist is a command line tool used to search your gists and starred gists
63
+ by keyword of gist description.
64
+ email:
65
+ - wangyuhere@gmail.com
66
+ executables:
67
+ - igist
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - .gitignore
72
+ - Gemfile
73
+ - LICENSE.txt
74
+ - README.md
75
+ - Rakefile
76
+ - bin/igist
77
+ - igist.gemspec
78
+ - lib/igist.rb
79
+ - lib/igist/api.rb
80
+ - lib/igist/cli.rb
81
+ - lib/igist/igist.rb
82
+ - lib/igist/search.rb
83
+ - lib/igist/version.rb
84
+ - spec/fixtures/gists.json
85
+ - spec/fixtures/starred_gists.json
86
+ - spec/igist/igist_spec.rb
87
+ - spec/igist/search_spec.rb
88
+ - spec/spec_helper.rb
89
+ homepage: https://github.com/wangyuhere/igist
90
+ licenses:
91
+ - MIT
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ segments:
103
+ - 0
104
+ hash: -1414565074206882299
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ segments:
112
+ - 0
113
+ hash: -1414565074206882299
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 1.8.25
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: Search your gists and starred gists by keyword of gist description
120
+ test_files:
121
+ - spec/fixtures/gists.json
122
+ - spec/fixtures/starred_gists.json
123
+ - spec/igist/igist_spec.rb
124
+ - spec/igist/search_spec.rb
125
+ - spec/spec_helper.rb