Skip to content

Commit

Permalink
Merge pull request #18 from fahrenq/master
Browse files Browse the repository at this point in the history
User repos caching improvements
  • Loading branch information
edgarjs authored Jan 20, 2020
2 parents 39499b9 + c900d1c commit f954aad
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 53 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ You can also check the [releases history](https://github.com/edgarjs/alfred-gith

---

## Actions
## Authentication

1. Call `gh-token` to generate personal access token.
2. Login by calling the `gh-login <email> <token>` action.
3. Search any repository by calling the `gh <term>` action.

## Usage

1. Search your repositories by calling the `gh <term>` action.
2. Search all repositories by calling the `gha <term>` action.
3. Your repositories are cached and updated every 24 hours. To force re-download cache use `gh-reset-cache` action.

### Other Actions

Expand Down
1 change: 0 additions & 1 deletion bin/github-repos
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# frozen_string_literal: true

require_relative '../lib/github_repos'
require 'github/repo_formatter'
require 'github/authorization'
require 'json'

Expand Down
2 changes: 1 addition & 1 deletion info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@
<key>queuedelayimmediatelyinitially</key>
<false/>
<key>queuedelaymode</key>
<integer>1</integer>
<integer>0</integer>
<key>queuemode</key>
<integer>1</integer>
<key>runningsubtext</key>
Expand Down
59 changes: 44 additions & 15 deletions lib/github/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'json'
require 'uri'
require 'cgi'
require 'github/repo'
require 'github/authorization'
require 'local_storage'
require 'config_path'
Expand All @@ -14,6 +15,10 @@ class Api
DEFAULT_HOST = 'https://api.github.com'
HOST_FILE_NAME = 'host'
CACHE_FILE_NAME = 'cache'
CACHE_TIMESTAMP_FILE_NAME = 'cache-timestamp'

# Remember to update Readme if changed.
CACHE_LIFETIME = 86_400 # 24 hours

# 100 is maximum items per page
LIST_USER_REPOS_PATH = '/user/repos?per_page=100'
Expand All @@ -22,21 +27,24 @@ def search_all_repos(query)
path = "/search/repositories?q=#{escape(query)}"

repos = get(path)[:body][:items]
Github::RepoFormatter.new(repos).to_formatted_hash

repos.map do |i|
Repo.from_api_response(i).to_alfred_hash
end
end

def search_repos(query)
query_downcase = query.downcase

repos = cached_repos
repos = read_cached_repos
repos = reset_cache if repos.empty?

repos_filtered = repos.filter do |i|
title_downcase = i[:title].downcase
title_downcase = i.name.downcase
title_downcase.include?(query_downcase)
end

repos_filtered
repos_filtered.map(&:to_alfred_hash)
end

def reset_cache
Expand All @@ -45,14 +53,15 @@ def reset_cache

until next_page.nil?
response = get(LIST_USER_REPOS_PATH + "&page=#{next_page}")
repos.push(*response[:body])
repos_from_response = response[:body].map do |i|
Repo.from_api_response(i)
end
repos.push(*repos_from_response)
next_page = response[:next_page]
end

repos_formatted = Github::RepoFormatter.new(repos).to_formatted_hash

save_repos_to_disk(repos_formatted)
repos_formatted
save_repos_to_disk(repos)
repos
end

class << self
Expand Down Expand Up @@ -126,15 +135,35 @@ def get_next_page(header)
header.split(',').map { |i| i[regex, 1] }.find(&:itself)
end

def cache_storage
@cache_path ||= ConfigPath.new(CACHE_FILE_NAME)
@cache_storage ||= LocalStorage.new(@cache_path.get, serialize: false)
end

def cache_timestamp_storage
@cache_timestamp_path ||= ConfigPath.new(CACHE_TIMESTAMP_FILE_NAME)
@cache_timestamp_storage ||=
LocalStorage.new(@cache_timestamp_path.get, serialize: false)
end

def save_repos_to_disk(repos)
cache = LocalStorage.new(ConfigPath.new(CACHE_FILE_NAME).get)
cache.put(repos.to_json)
content = repos.map(&:to_storage_string).join("\n")
cache_storage.put(content)
cache_timestamp_storage.put(Time.now.to_i)
end

def read_cache_timestamp
cache_timestamp = cache_timestamp_storage.get
cache_timestamp.nil? ? 0 : cache_timestamp.to_i
end

def cached_repos
cache_path = ConfigPath.new(CACHE_FILE_NAME).get
cache_string = LocalStorage.new(cache_path).get
cache_string.nil? ? [] : JSON.parse(cache_string, symbolize_names: true)
def read_cached_repos
cache_string = cache_storage.get
cache_expired = (read_cache_timestamp + CACHE_LIFETIME) < Time.now.to_i

return [] if cache_string.nil? || cache_expired

cache_string.split("\n").map { |i| Repo.from_storage_string(i) }
end
end
end
41 changes: 41 additions & 0 deletions lib/github/repo.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

require 'json'

module Github
class Repo
attr_reader :name, :link

def initialize(name, link)
@name = name
@link = link
end

def to_storage_string
"#{@name},#{@link}"
end

def to_alfred_hash
{
title: @name,
subtitle: @link,
arg: @link,
text: {
copy: @link,
largetype: @link
}
}
end

class << self
def from_storage_string(storage_string)
name, link = storage_string.split(',')
new(name, link)
end

def from_api_response(api_response)
new(api_response[:full_name], api_response[:html_url])
end
end
end
end
31 changes: 0 additions & 31 deletions lib/github/repo_formatter.rb

This file was deleted.

9 changes: 6 additions & 3 deletions lib/local_storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ class LocalStorage
attr_reader :location

# @param [String] filepath
def initialize(filepath)
def initialize(filepath, serialize: true)
@location = File.expand_path(filepath)
@serialize = serialize
create_parent_dir
end

def put(object)
File.open(location, 'w') do |f|
f.puts serialize(object)
to_insert = @serialize ? serialize(object) : object
f.puts to_insert
end

object
Expand All @@ -23,7 +25,8 @@ def put(object)
def get
return unless exists?

deserialize File.read(location)
raw_content = File.read(location)
@serialize ? deserialize(raw_content) : raw_content
end

private
Expand Down

0 comments on commit f954aad

Please sign in to comment.