bananajour 2.1.9
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/Rakefile +66 -0
- data/Readme.md +86 -0
- data/bin/bananajour +58 -0
- data/lib/bananajour.rb +99 -0
- data/lib/bananajour/bonjour.rb +9 -0
- data/lib/bananajour/bonjour/advertiser.rb +57 -0
- data/lib/bananajour/bonjour/bananajour_browser.rb +24 -0
- data/lib/bananajour/bonjour/browser.rb +52 -0
- data/lib/bananajour/bonjour/person.rb +21 -0
- data/lib/bananajour/bonjour/repository.rb +39 -0
- data/lib/bananajour/bonjour/repository_browser.rb +36 -0
- data/lib/bananajour/commands.rb +80 -0
- data/lib/bananajour/gem_dependencies.rb +34 -0
- data/lib/bananajour/grit_extensions.rb +11 -0
- data/lib/bananajour/helpers.rb +100 -0
- data/lib/bananajour/repository.rb +85 -0
- data/lib/bananajour/version.rb +3 -0
- data/sinatra/app.rb +87 -0
- data/sinatra/lib/browsers.rb +2 -0
- data/sinatra/lib/diff_helpers.rb +92 -0
- data/sinatra/lib/mock_browsers.rb +55 -0
- data/sinatra/public/jquery-1.3.2.min.js +19 -0
- data/sinatra/public/loader.gif +0 -0
- data/sinatra/public/logo.png +0 -0
- data/sinatra/public/pbjt.swf +0 -0
- data/sinatra/public/peanut.png +0 -0
- data/sinatra/views/commit.haml +112 -0
- data/sinatra/views/home.haml +305 -0
- data/sinatra/views/layout.haml +119 -0
- data/sinatra/views/readme.haml +52 -0
- metadata +183 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
class Bananajour::Bonjour::Person
|
2
|
+
|
3
|
+
attr_accessor :name, :email, :uri , :gravatar
|
4
|
+
|
5
|
+
def initialize(name, email, uri, gravatar)
|
6
|
+
@name, @email, @uri, @gravatar = name, email, uri, gravatar
|
7
|
+
end
|
8
|
+
|
9
|
+
def ==(other)
|
10
|
+
self.uri == other.uri
|
11
|
+
end
|
12
|
+
|
13
|
+
def hash
|
14
|
+
to_hash.hash
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
{"name" => name, "email" => email, "uri" => uri, "gravatar" => gravatar}
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Bananajour::Bonjour::Repository
|
2
|
+
|
3
|
+
attr_accessor :name, :uri, :person
|
4
|
+
|
5
|
+
def initialize(name, uri, person)
|
6
|
+
@name, @uri, @person = name, uri, person
|
7
|
+
end
|
8
|
+
|
9
|
+
def html_id
|
10
|
+
Bananajour::Repository.html_id(name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
self.uri == other.uri
|
15
|
+
end
|
16
|
+
|
17
|
+
def hash
|
18
|
+
to_hash.hash
|
19
|
+
end
|
20
|
+
|
21
|
+
def json_uri
|
22
|
+
"#{person.uri}#{name}.json"
|
23
|
+
end
|
24
|
+
|
25
|
+
def web_uri
|
26
|
+
"#{person.uri}##{html_id}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_hash
|
30
|
+
{
|
31
|
+
"name" => name,
|
32
|
+
"uri" => uri,
|
33
|
+
"json_uri" => json_uri,
|
34
|
+
"web_uri" => web_uri,
|
35
|
+
"person" => person.to_hash
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Bananajour::Bonjour
|
2
|
+
class RepositoryBrowser
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@browser = Browser.new('_bananajour._git._tcp')
|
6
|
+
end
|
7
|
+
|
8
|
+
def repositories
|
9
|
+
@browser.replies.map do |reply|
|
10
|
+
Repository.new(
|
11
|
+
reply.text_record["name"],
|
12
|
+
reply.text_record["uri"],
|
13
|
+
Person.new(
|
14
|
+
reply.text_record["bjour-name"],
|
15
|
+
reply.text_record["bjour-email"],
|
16
|
+
reply.text_record["bjour-uri"],
|
17
|
+
reply.text_record["bjour-gravatar"]
|
18
|
+
)
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def other_repositories
|
24
|
+
repositories.reject {|r| Bananajour.repositories.any? {|my_rep| my_rep.name == r.name}}
|
25
|
+
end
|
26
|
+
|
27
|
+
def repositories_similar_to(repository)
|
28
|
+
repositories.select {|r| r.name == repository.name}
|
29
|
+
end
|
30
|
+
|
31
|
+
def repositories_for(person)
|
32
|
+
repositories.select {|r| r.person == person}
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Bananajour::Commands
|
2
|
+
|
3
|
+
def check_git!
|
4
|
+
if (version = `git --version`.strip) =~ /git version 1\.[12345]/
|
5
|
+
abort "You have #{version}, you need at least 1.6"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def check_git_config!
|
10
|
+
config_message = lambda {|key, example| "You haven't set your #{key} in your git config yet. To set it: git config --global #{key} '#{example}'"}
|
11
|
+
abort(config_message["user.name", "My Name"]) if config.name.empty?
|
12
|
+
abort(config_message["user.email", "name@domain.com"]) if config.email.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def serve_web!
|
16
|
+
fork { exec "/usr/bin/env ruby #{File.dirname(__FILE__)}/../../sinatra/app.rb -p #{web_port} -e production" }
|
17
|
+
puts "* Started " + web_uri.foreground(:yellow)
|
18
|
+
end
|
19
|
+
|
20
|
+
def serve_git!
|
21
|
+
fork { exec "git daemon --base-path=#{repositories_path} --export-all" }
|
22
|
+
puts "* Started " + "#{git_uri}".foreground(:yellow)
|
23
|
+
end
|
24
|
+
|
25
|
+
def advertise!
|
26
|
+
fork { Bananajour::Bonjour::Advertiser.new.go! }
|
27
|
+
end
|
28
|
+
|
29
|
+
def add!(dir, name = nil)
|
30
|
+
dir = Fancypath(dir)
|
31
|
+
|
32
|
+
unless dir.join(".git").directory?
|
33
|
+
abort "Can't init project #{dir}, no .git directory found."
|
34
|
+
end
|
35
|
+
|
36
|
+
if name.nil?
|
37
|
+
default_name = dir.basename.to_s
|
38
|
+
print "Project Name?".foreground(:yellow) + " [#{default_name}] "
|
39
|
+
name = (STDIN.gets || "").strip
|
40
|
+
name = default_name if name.empty?
|
41
|
+
end
|
42
|
+
|
43
|
+
repo = Bananajour::Repository.for_name(name)
|
44
|
+
|
45
|
+
if repo.exists?
|
46
|
+
abort "You've already a project #{repo}."
|
47
|
+
end
|
48
|
+
|
49
|
+
repo.init!
|
50
|
+
Dir.chdir(dir) { `git remote add banana #{repo.path.expand_path}` }
|
51
|
+
puts init_success_message(repo.dirname)
|
52
|
+
|
53
|
+
repo
|
54
|
+
end
|
55
|
+
|
56
|
+
def init_success_message(repo_dirname)
|
57
|
+
plain_init_success_message(repo_dirname).gsub("git push banana master", "git push banana master".foreground(:yellow))
|
58
|
+
end
|
59
|
+
|
60
|
+
def plain_init_success_message(repo_dirname)
|
61
|
+
"Bananajour repository #{repo_dirname} initialised and remote banana added.\nNext: git push banana master"
|
62
|
+
end
|
63
|
+
|
64
|
+
def clone!(url, clone_name)
|
65
|
+
dir = clone_name || File.basename(url).chomp('.git')
|
66
|
+
|
67
|
+
if File.exists?(dir)
|
68
|
+
abort "Can't clone #{url} to #{dir}, the directory already exists."
|
69
|
+
end
|
70
|
+
|
71
|
+
`git clone #{url} #{dir}`
|
72
|
+
if $? != 0
|
73
|
+
abort "Failed to clone bananajour repository #{url} to #{dir}."
|
74
|
+
else
|
75
|
+
puts "Bananajour repository #{url} cloned to #{dir}."
|
76
|
+
add!(dir, dir)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Bananajour
|
2
|
+
# DRYs version number dependencies and provides a simple way require them
|
3
|
+
module GemDependencies
|
4
|
+
DEPENDENCIES = [
|
5
|
+
%w( sinatra 0.9.2 ),
|
6
|
+
%w( json 1.1.7 ),
|
7
|
+
%w( chrislloyd-fancypath 0.5.8 ),
|
8
|
+
%w( rainbow 1.0.1 ),
|
9
|
+
%w( mojombo-grit 1.1.1 ),
|
10
|
+
%w( dnssd 0.7.1 ),
|
11
|
+
%w( rack 1.0.0 ),
|
12
|
+
%w( thin 1.0.0 ),
|
13
|
+
%w( haml 2.0.9 ),
|
14
|
+
%w( activesupport 2.3.2 )
|
15
|
+
]
|
16
|
+
class Dependency < Struct.new(:name, :version)
|
17
|
+
def require_gem; gem name, version end
|
18
|
+
end
|
19
|
+
def self.all
|
20
|
+
DEPENDENCIES.map {|(name, version)| Dependency.new(name, version)}
|
21
|
+
end
|
22
|
+
def self.for_name(name)
|
23
|
+
all.find {|d| d.name == name }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.gem(name)
|
28
|
+
Bananajour::GemDependencies.for_name(name).require_gem
|
29
|
+
end
|
30
|
+
def self.require_gem(name, lib=nil)
|
31
|
+
self.gem(name)
|
32
|
+
Kernel.require(lib || name)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'md5'
|
2
|
+
|
3
|
+
module Bananajour
|
4
|
+
module GravatarHelpers
|
5
|
+
def gravatar
|
6
|
+
gravatar_uri(self.config.email)
|
7
|
+
end
|
8
|
+
def gravatar_uri(email)
|
9
|
+
"http://gravatar.com/avatar/#{MD5.md5(email)}.png"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Lifted from Rails
|
14
|
+
module DateHelpers
|
15
|
+
# Reports the approximate distance in time between two Time or Date objects or integers as seconds.
|
16
|
+
# Set <tt>include_seconds</tt> to true if you want more detailed approximations when distance < 1 min, 29 secs
|
17
|
+
# Distances are reported based on the following table:
|
18
|
+
#
|
19
|
+
# 0 <-> 29 secs # => less than a minute
|
20
|
+
# 30 secs <-> 1 min, 29 secs # => 1 minute
|
21
|
+
# 1 min, 30 secs <-> 44 mins, 29 secs # => [2..44] minutes
|
22
|
+
# 44 mins, 30 secs <-> 89 mins, 29 secs # => about 1 hour
|
23
|
+
# 89 mins, 29 secs <-> 23 hrs, 59 mins, 29 secs # => about [2..24] hours
|
24
|
+
# 23 hrs, 59 mins, 29 secs <-> 47 hrs, 59 mins, 29 secs # => 1 day
|
25
|
+
# 47 hrs, 59 mins, 29 secs <-> 29 days, 23 hrs, 59 mins, 29 secs # => [2..29] days
|
26
|
+
# 29 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs # => about 1 month
|
27
|
+
# 59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec # => [2..12] months
|
28
|
+
# 1 yr <-> 2 yrs minus 1 secs # => about 1 year
|
29
|
+
# 2 yrs <-> max time or date # => over [2..X] years
|
30
|
+
#
|
31
|
+
# With <tt>include_seconds</tt> = true and the difference < 1 minute 29 seconds:
|
32
|
+
# 0-4 secs # => less than 5 seconds
|
33
|
+
# 5-9 secs # => less than 10 seconds
|
34
|
+
# 10-19 secs # => less than 20 seconds
|
35
|
+
# 20-39 secs # => half a minute
|
36
|
+
# 40-59 secs # => less than a minute
|
37
|
+
# 60-89 secs # => 1 minute
|
38
|
+
#
|
39
|
+
# ==== Examples
|
40
|
+
# from_time = Time.now
|
41
|
+
# distance_of_time_in_words(from_time, from_time + 50.minutes) # => about 1 hour
|
42
|
+
# distance_of_time_in_words(from_time, 50.minutes.from_now) # => about 1 hour
|
43
|
+
# distance_of_time_in_words(from_time, from_time + 15.seconds) # => less than a minute
|
44
|
+
# distance_of_time_in_words(from_time, from_time + 15.seconds, true) # => less than 20 seconds
|
45
|
+
# distance_of_time_in_words(from_time, 3.years.from_now) # => over 3 years
|
46
|
+
# distance_of_time_in_words(from_time, from_time + 60.hours) # => about 3 days
|
47
|
+
# distance_of_time_in_words(from_time, from_time + 45.seconds, true) # => less than a minute
|
48
|
+
# distance_of_time_in_words(from_time, from_time - 45.seconds, true) # => less than a minute
|
49
|
+
# distance_of_time_in_words(from_time, 76.seconds.from_now) # => 1 minute
|
50
|
+
# distance_of_time_in_words(from_time, from_time + 1.year + 3.days) # => about 1 year
|
51
|
+
# distance_of_time_in_words(from_time, from_time + 4.years + 15.days + 30.minutes + 5.seconds) # => over 4 years
|
52
|
+
#
|
53
|
+
# to_time = Time.now + 6.years + 19.days
|
54
|
+
# distance_of_time_in_words(from_time, to_time, true) # => over 6 years
|
55
|
+
# distance_of_time_in_words(to_time, from_time, true) # => over 6 years
|
56
|
+
# distance_of_time_in_words(Time.now, Time.now) # => less than a minute
|
57
|
+
#
|
58
|
+
def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
|
59
|
+
from_time = from_time.to_time if from_time.respond_to?(:to_time)
|
60
|
+
to_time = to_time.to_time if to_time.respond_to?(:to_time)
|
61
|
+
distance_in_minutes = (((to_time - from_time).abs)/60).round
|
62
|
+
distance_in_seconds = ((to_time - from_time).abs).round
|
63
|
+
|
64
|
+
case distance_in_minutes
|
65
|
+
when 0..1
|
66
|
+
return (distance_in_minutes == 0) ? 'less than a minute' : '1 minute' unless include_seconds
|
67
|
+
case distance_in_seconds
|
68
|
+
when 0..4 then 'less than 5 seconds'
|
69
|
+
when 5..9 then 'less than 10 seconds'
|
70
|
+
when 10..19 then 'less than 20 seconds'
|
71
|
+
when 20..39 then 'half a minute'
|
72
|
+
when 40..59 then 'less than a minute'
|
73
|
+
else '1 minute'
|
74
|
+
end
|
75
|
+
|
76
|
+
when 2..44 then "#{distance_in_minutes} minutes"
|
77
|
+
when 45..89 then 'about 1 hour'
|
78
|
+
when 90..1439 then "about #{(distance_in_minutes.to_f / 60.0).round} hours"
|
79
|
+
when 1440..2879 then '1 day'
|
80
|
+
when 2880..43199 then "#{(distance_in_minutes / 1440).round} days"
|
81
|
+
when 43200..86399 then 'about 1 month'
|
82
|
+
when 86400..525599 then "#{(distance_in_minutes / 43200).round} months"
|
83
|
+
when 525600..1051199 then 'about 1 year'
|
84
|
+
else "over #{(distance_in_minutes / 525600).round} years"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Like distance_of_time_in_words, but where <tt>to_time</tt> is fixed to <tt>Time.now</tt>.
|
89
|
+
#
|
90
|
+
# ==== Examples
|
91
|
+
# time_ago_in_words(3.minutes.from_now) # => 3 minutes
|
92
|
+
# time_ago_in_words(Time.now - 15.hours) # => 15 hours
|
93
|
+
# time_ago_in_words(Time.now) # => less than a minute
|
94
|
+
#
|
95
|
+
# from_time = Time.now - 3.days - 14.minutes - 25.seconds # => 3 days
|
96
|
+
def time_ago_in_words(from_time, include_seconds = false)
|
97
|
+
distance_of_time_in_words(from_time, Time.now, include_seconds)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
Bananajour.require_gem 'mojombo-grit', 'grit'
|
2
|
+
|
3
|
+
module Bananajour
|
4
|
+
class Repository
|
5
|
+
def self.for_name(name)
|
6
|
+
new(Bananajour.repositories_path.join(name + ".git"))
|
7
|
+
end
|
8
|
+
def self.html_id(name)
|
9
|
+
name.gsub(/[^A-Za-z-]+/, '').downcase
|
10
|
+
end
|
11
|
+
def initialize(path)
|
12
|
+
@path = Fancypath(path)
|
13
|
+
end
|
14
|
+
def ==(other)
|
15
|
+
other.respond_to?(:path) && self.path == other.path
|
16
|
+
end
|
17
|
+
attr_reader :path
|
18
|
+
def exists?
|
19
|
+
path.exists?
|
20
|
+
end
|
21
|
+
def init!
|
22
|
+
path.create_dir
|
23
|
+
Dir.chdir(path) { `git init --bare` }
|
24
|
+
end
|
25
|
+
def name
|
26
|
+
dirname.sub(".git",'')
|
27
|
+
end
|
28
|
+
def html_id
|
29
|
+
self.class.html_id(name)
|
30
|
+
end
|
31
|
+
def dirname
|
32
|
+
path.split.last.to_s
|
33
|
+
end
|
34
|
+
def to_s
|
35
|
+
name
|
36
|
+
end
|
37
|
+
def uri
|
38
|
+
Bananajour.git_uri + dirname
|
39
|
+
end
|
40
|
+
def web_uri
|
41
|
+
Bananajour.web_uri + "#" + html_id
|
42
|
+
end
|
43
|
+
def grit_repo
|
44
|
+
@grit_repo ||= Grit::Repo.new(path)
|
45
|
+
end
|
46
|
+
def recent_commits
|
47
|
+
@commits ||= grit_repo.commits(nil, 10)
|
48
|
+
end
|
49
|
+
def readme_file
|
50
|
+
grit_repo.tree.contents.find {|c| c.name =~ /readme/i}
|
51
|
+
end
|
52
|
+
def rendered_readme
|
53
|
+
case File.extname(readme_file.name)
|
54
|
+
when /\.md/i, /\.markdown/i
|
55
|
+
require 'rdiscount'
|
56
|
+
RDiscount.new(readme_file.data).to_html
|
57
|
+
when /\.textile/i
|
58
|
+
require 'redcloth'
|
59
|
+
RedCloth.new(readme_file.data).to_html(:textile)
|
60
|
+
end
|
61
|
+
rescue LoadError
|
62
|
+
""
|
63
|
+
end
|
64
|
+
def remove!
|
65
|
+
path.rmtree
|
66
|
+
end
|
67
|
+
def to_hash
|
68
|
+
heads = grit_repo.heads
|
69
|
+
{
|
70
|
+
"name" => name,
|
71
|
+
"html_friendly_name" => html_id, # TODO: Deprecate in v3. Renamed to html_id since 2.1.4
|
72
|
+
"html_id" => html_id,
|
73
|
+
"uri" => uri,
|
74
|
+
"heads" => heads.map {|h| h.name},
|
75
|
+
"recent_commits" => recent_commits.collect do |c|
|
76
|
+
c.to_hash.merge(
|
77
|
+
"head" => (head = heads.find {|h| h.commit == c}) && head.name,
|
78
|
+
"gravatar" => c.author.gravatar_uri
|
79
|
+
)
|
80
|
+
end,
|
81
|
+
"bananajour" => Bananajour.to_hash
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/sinatra/app.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
Thread.abort_on_exception = true
|
2
|
+
|
3
|
+
__DIR__ = File.dirname(__FILE__)
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
|
7
|
+
require "#{__DIR__}/../lib/bananajour"
|
8
|
+
|
9
|
+
Bananajour.require_gem 'rack'
|
10
|
+
|
11
|
+
# Must require 'sinatra' from this file for Sinatra's magic to pick up lots of free stuff
|
12
|
+
Bananajour::GemDependencies.for_name('sinatra').require_gem
|
13
|
+
require 'sinatra'
|
14
|
+
|
15
|
+
Bananajour.require_gem 'haml'
|
16
|
+
Bananajour.require_gem 'json'
|
17
|
+
|
18
|
+
Bananajour.gem 'activesupport'
|
19
|
+
require 'active_support/core_ext/enumerable'
|
20
|
+
require 'active_support/core_ext/array'
|
21
|
+
|
22
|
+
require 'forwardable' # Fix for issue #8 - Thin borking on uninitialized constant Forwardable
|
23
|
+
|
24
|
+
set :server, 'thin' # Things go weird with anything else - let's lock it down to thin
|
25
|
+
set :haml, {:format => :html5, :attr_wrapper => '"'}
|
26
|
+
set :logging, false
|
27
|
+
|
28
|
+
require "#{__DIR__}/lib/browsers" # to prevent reloading
|
29
|
+
require "#{__DIR__}/lib/mock_browsers" if Sinatra::Application.development?
|
30
|
+
before do
|
31
|
+
@bananajour_browser = BANANAJOUR_BROWSER
|
32
|
+
@repository_browser = REPO_BROWSER
|
33
|
+
end
|
34
|
+
|
35
|
+
load "#{__DIR__}/lib/diff_helpers.rb"
|
36
|
+
helpers DiffHelpers
|
37
|
+
|
38
|
+
require "bananajour/helpers"
|
39
|
+
helpers Bananajour::GravatarHelpers, Bananajour::DateHelpers
|
40
|
+
|
41
|
+
helpers do
|
42
|
+
def json(body)
|
43
|
+
content_type "application/json"
|
44
|
+
params[:callback] ? "#{params[:callback]}(#{body});" : body
|
45
|
+
end
|
46
|
+
def local?
|
47
|
+
[
|
48
|
+
"0.0.0.0",
|
49
|
+
"127.0.0.1",
|
50
|
+
Socket.getaddrinfo(request.env["SERVER_NAME"], nil).map {|a| a[3]}
|
51
|
+
].flatten.include? request.env["REMOTE_ADDR"]
|
52
|
+
end
|
53
|
+
def pluralize(number, singular, plural)
|
54
|
+
"#{number} #{number == 1 ? singular : plural}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
get "/" do
|
59
|
+
@my_repositories = Bananajour.repositories
|
60
|
+
@other_repos_by_name = @repository_browser.other_repositories.group_by {|r| r.name}
|
61
|
+
@people = @bananajour_browser.other_bananajours
|
62
|
+
haml :home
|
63
|
+
end
|
64
|
+
|
65
|
+
get "/:repository/readme" do
|
66
|
+
@repository = Bananajour::Repository.for_name(params[:repository])
|
67
|
+
readme_file = @repository.readme_file
|
68
|
+
@rendered_readme = @repository.rendered_readme
|
69
|
+
@plain_readme = readme_file.data
|
70
|
+
haml :readme
|
71
|
+
end
|
72
|
+
|
73
|
+
get "/:repository/:commit" do
|
74
|
+
@repository = Bananajour::Repository.for_name(params[:repository])
|
75
|
+
@commit = @repository.grit_repo.commit(params[:commit])
|
76
|
+
haml :commit
|
77
|
+
end
|
78
|
+
|
79
|
+
get "/index.json" do
|
80
|
+
json Bananajour.to_hash.to_json
|
81
|
+
end
|
82
|
+
|
83
|
+
get "/:repository.json" do
|
84
|
+
response = Bananajour::Repository.for_name(params[:repository]).to_hash
|
85
|
+
response["recent_commits"].map! { |c| c["committed_date_pretty"] = time_ago_in_words(Time.parse(c["committed_date"])).gsub("about ","") + " ago"; c }
|
86
|
+
json response.to_json
|
87
|
+
end
|