Skip to content

Instantly share code, notes, and snippets.

@knewter
Created March 11, 2014 05:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save knewter/9479989 to your computer and use it in GitHub Desktop.
Save knewter/9479989 to your computer and use it in GitHub Desktop.
defmodule BeamToolbox.Models.Project do
defstruct [:name, :website, :github]
use BeamToolbox.Model
alias BeamToolbox.GitHub
alias BeamToolbox.Data
@time_to_live 600 # 10 minutes
def category(project) do
Data.categories
|> Enum.filter(fn(c) -> Enum.member?(c.projects, project) end)
|> hd
end
def related_projects(project) do
category(project).projects
|> Enum.filter(fn(proj) -> proj !== project end)
end
def readme_raw(project), do: GitHub.Raw.readme(project.github)
def readme(project), do: project |> readme_raw |> Markdown.to_html(tables: true, fenced_code: true, autolink: true)
def readme_caching(project) do
{:ok, value} = :cadfaerl.get_or_fetch_ttl(:github, :"readme#{project.github}", &readme/1, @time_to_live)
value
end
defmodule Statistics do
import Enum
def stargazers_count(""), do: "N/A"
def stargazers_count(repo_ident), do: repo_ident |> GitHub.stargazers |> count
def forks_count(""), do: "N/A"
def forks_count(repo_ident), do: repo_ident |> GitHub.forks |> count
def latest_commit_date(""), do: "N/A"
def latest_commit_date(repo_ident) do
GitHub.latest_commit(repo_ident)["commit"]["committer"]["date"]
end
def description(""), do: "N/A"
def description(repo_ident) do
repo = repo_ident |> GitHub.repo
repo["description"]
end
defmodule Cached do
# This is a cached version of the statistics module. It just wraps
# cadfaerl, deferring to the Statistics module for its values.
# We want to configure the time to live for each cache entry. Here, I'll
# just set it to 10 minutes
@time_to_live 600 # 10 minutes
# Now, for each function in the Statistics module, let's build a caching
# version of it that defers to it. For now I'm hard-coding the list of
# functions, but you could derive it using Statistics.__info__(:functions)
# as well.
[:stargazers_count, :forks_count, :latest_commit_date, :description]
|> Enum.each fn(fun_name) ->
# Now, for each function we want to define a function on this module.
# We'll need to unquote the fun_name in order to define a function of
# that name.
def unquote(fun_name)(repo_ident) do
# Next, we want to just unquote the fun_name going forward as we
# intend to use it a few times in unquoted form
fun_name = unquote(fun_name)
# Finally, the body of each function will just be getting the cached
# version of the function, or if it isn't cached yet, deferring to
# the uncached Statistics module.
{:ok, value} = :cadfaerl.get_or_fetch_ttl(:github, :"#{fun_name}#{repo_ident}", fn() ->
apply(BeamToolbox.Models.Project.Statistics, fun_name, [repo_ident])
end, @time_to_live)
value
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment