Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
edgarjs committed Jul 25, 2014
0 parents commit c6aba0f
Show file tree
Hide file tree
Showing 8 changed files with 525 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
repos.cache
.auth_token
Binary file added EFFBF4FD-3C90-4266-BE53-DE912E5FAFC4.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added FE3390F7-206C-45C4-94BB-5DD14DE23A1B.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions README.md
@@ -0,0 +1,35 @@
Quickly find your github repositories from [Alfred](http://www.alfredapp.com/).

# Usage

### Identify yourself

This workflow search within your public and private repositories (including organizations you belong to). So you need to provide an access token to make things easy.

So go to [create a new personal access token](https://github.com/settings/tokens/new). You can enter any description and it just need to be checked the `repo` option (read private repositories).

![New personal access token](http://cloud.edgar.sh/2z7pq.png)

Then **copy the token** (as it will be visible only that time!). And authenticate in alfred:

gh-auth YOURTOKEN

This will store your token and you will be able to use the following commands...

### Search your repositories

To search your repos, just type in alfred:

gh YOUR-REPO-NAME

And that's it, you'll see a list of matching repositories.

### Rebuild local cache

To avoid hitting the github API every time you do a search, and to return results faster, the workflow caches all your repositories the first time you authenticate or do a search. If you create a new repository, you'll need to update your local cache with:

gh-update

# Feedback

[@edgarjs](http://twitter.com/edgarjs)
161 changes: 161 additions & 0 deletions github
@@ -0,0 +1,161 @@
#!/usr/bin/env ruby

require './xml_builder'

require 'json'
require 'net/http'
require 'cgi'

class InvalidToken < StandardError; end

class Github
def initialize
@base_uri = "https://api.github.com"
@cache_file = "repos.cache"
@token_file = ".auth_token"
end

def store_token(token)
if token && token.length > 0
File.open(@token_file, 'w') do |f|
f.write(token)
end
rebuild_cache
end
end

def search_repo(query)
repos = load_or_initialize_cache
results = repos.select do |repo|
repo['name'] =~ Regexp.new(query, 'i')
end
results.length > 0 ? results : repos
end

def rebuild_cache
File.delete(@cache_file) if File.exists?(@cache_file)
cache_all_repos_for_user
end

def test_authentication
load_token
return false if !@token || @token.length == 0
res = get "/"
!res.has_key?('error')
end

private

def load_token
@token = File.read(@token_file).strip if File.exists?(@token_file)
end

def load_or_initialize_cache
if File.exists?(@cache_file)
JSON.parse(File.read(@cache_file))
else
cache_all_repos_for_user
end
end

# TODO: probably will do a search request instead of fetching all at once
def cache_all_repos_for_user
raise InvalidToken unless test_authentication
repos = []
repos += get_user_repos
get_user_orgs.each do |org|
repos += get_org_repos( org['login'] )
end
File.open(@cache_file, 'w') do |f|
f.write repos.to_json
end
repos
end

def get_user_repos
res = get "/user/repos"
if res.is_a?(Array)
res.map do |repo|
{ 'name' => repo['full_name'], 'url' => repo['html_url'] }
end
else # TODO: handle error
[]
end
end

def get_user_orgs
res = get "/user/orgs"
if res.is_a?(Array)
res.map do |org|
{ 'login' => org['login'] }
end
else # TODO: handle error
[]
end
end

def get_org_repos(org)
res = get "/orgs/#{org}/repos"
if res.is_a?(Array)
res.map do |repo|
{ 'name' => repo['full_name'], 'url' => repo['html_url'] }
end
else # TODO: handle error
[]
end
end

def get(path, params = {})
qs = ''
if params.any?
qs = '?' + params.map {|k, v| "#{CGI.escape k}=#{CGI.escape v}"}.join("&")
end
uri = URI("#{@base_uri}#{path}#{qs}")

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
req = Net::HTTP::Get.new(uri)
req['Accept'] = "application/vnd.github.v3+json"
req['Authorization'] = "token #{@token}"
http.request(req)
end

json = JSON.parse(res.body)

if res.kind_of? Net::HTTPSuccess
json
else
{ 'error' => json['message'] }
end
end
end

query = ARGV[0]
github = Github.new

begin
if query == '--update'
github.rebuild_cache
elsif query == '--auth'
github.store_token(ARGV[1])
else
results = github.search_repo(query || '')

output = XmlBuilder.build do |xml|
xml.items do
results.each do |repo|
xml.item Item.new(repo['url'], repo['url'], repo['name'], repo['url'], 'yes')
end
end
end

puts output
end
rescue InvalidToken
output = XmlBuilder.build do |xml|
xml.items do
xml.item Item.new('gh-error', '', "Invalid token!", "Please set your token with gh-auth", 'no')
end
end

puts output
end
Binary file added icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c6aba0f

Please sign in to comment.