From 372f50bef0cab04414fce52a22d76f232dd3b800 Mon Sep 17 00:00:00 2001 From: Lee Reilly Date: Wed, 18 May 2011 13:57:11 -0700 Subject: [PATCH] Initial commit --- app.rb | 173 ++++++++++++++++++++++++++++++++++ config.ru | 10 ++ db/db.db | Bin 0 -> 10240 bytes lib/Contributor.rb | 48 ++++++++++ lib/Repo.rb | 84 +++++++++++++++++ lib/User.rb | 83 ++++++++++++++++ lib/tasks/migrate.task | 3 + public/css/style.css | 93 ++++++++++++++++++ public/font/ArcadeClassic.otf | Bin 0 -> 4176 bytes public/img/bg.png | Bin 0 -> 42196 bytes public/img/favicon.png | Bin 0 -> 3145 bytes public/img/octocat.png | Bin 0 -> 4530 bytes public/index.html | 76 +++++++++++++++ test/app_test.rb | 66 +++++++++++++ views/about.erb | 9 ++ views/credits.erb | 7 ++ views/footer.erb | 11 +++ views/header.erb | 12 +++ views/help.erb | 29 ++++++ views/high_scores.erb | 24 +++++ views/index.erb | 9 ++ views/not_found.erb | 11 +++ views/random.erb | 0 views/recent.erb | 9 ++ views/repo.erb | 26 +++++ views/search_form.erb | 6 ++ views/small_search.erb | 5 + views/user.erb | 43 +++++++++ 28 files changed, 837 insertions(+) create mode 100644 app.rb create mode 100644 config.ru create mode 100644 db/db.db create mode 100644 lib/Contributor.rb create mode 100644 lib/Repo.rb create mode 100644 lib/User.rb create mode 100644 lib/tasks/migrate.task create mode 100644 public/css/style.css create mode 100644 public/font/ArcadeClassic.otf create mode 100644 public/img/bg.png create mode 100644 public/img/favicon.png create mode 100644 public/img/octocat.png create mode 100644 public/index.html create mode 100644 test/app_test.rb create mode 100644 views/about.erb create mode 100644 views/credits.erb create mode 100644 views/footer.erb create mode 100644 views/header.erb create mode 100644 views/help.erb create mode 100644 views/high_scores.erb create mode 100644 views/index.erb create mode 100644 views/not_found.erb create mode 100644 views/random.erb create mode 100644 views/recent.erb create mode 100644 views/repo.erb create mode 100644 views/search_form.erb create mode 100644 views/small_search.erb create mode 100644 views/user.erb diff --git a/app.rb b/app.rb new file mode 100644 index 0000000..9dd9d16 --- /dev/null +++ b/app.rb @@ -0,0 +1,173 @@ +$:.unshift File.join(File.dirname(__FILE__),'lib') + +require 'rubygems' +require 'net/http' +require 'sinatra' +require 'json' +require 'erb' +require 'uri' + +require 'User' +require 'Repo' + +DataMapper::Logger.new(STDOUT, :debug) + +disable :show_exceptions +set :environment, :production + +configure :development do + DataMapper.setup(:default, 'sqlite:////Users/lreilly/Projects/github-scores.com/db/dbdb') +end + +configure :production do + DataMapper.setup(:default, 'sqlite:////Users/lreilly/Projects/github-scores.com/db/db.db') +end + +error do + @title = "404" + @text = "Sorry, but this cat is in another castle!" + @display_small_search = false + erb :not_found +end + +get '/' do + begin + if params[:github_url] + @title = 'High Scores' + @github_url = sanitize_input params[:github_url] + @user = get_user_from_github_url(@github_url) + @repo = get_repo_from_github_url(@github_url) + @high_scores = get_high_scores(@user, @repo) + @display_small_search = true + redirect "/#{@user}/#{@repo}/high_scores/" + else + @title = 'High Scores' + @text = 'Please enter a Github repository URL' + @display_small_search = false + erb :index + end + rescue + @title = "404" + @text = "Sorry, but this cat is in another castle!" + @display_small_search = false + erb :not_found + end +end + +get '/recent/?' do + @repos = Repo.all(:limit => 5, :order => [ :updated_at.desc ]) + @display_small_search = true + erb :recent +end + + +get '/credits/?' do + erb :credits +end + +get '/help/?' do + @display_small_search = true + erb :help +end + +get '/about/?' do + @display_small_search = true + erb :about +end + +get '/:user/:repo/?' do + @user = User::create_from_username(params[:user]) + @repo = Repo::create_from_username_and_repo(params[:user], params[:repo]) + @display_small_search = true + erb :repo +end + +get '/:user/?' do + @user = User::create_from_username(params[:user]) + @display_small_search = true + erb :user +end + +not_found do + @title = "404" + @text = "Sorry, but this cat is in another castle!" + erb :not_found +end + +def sanitize_input(url) + url = url.downcase + + # Special rules for Github URLs starting with 'github.com' + if url[0..9] == 'github.com' + url = 'https://www.github.com' + url[9..url.size] + + # Special rules for Github URLs starting with 'www.github.com' + elsif url[0..13] == 'www.github.com' + url = 'https://www.github.com' + url[13..url.size] + end + + # Special rules for Github URLs ending in 'git' + if url[-4,4] == '.git' + url = url[0..-5] + end + + url = url.gsub("http://", "https://") + url = url.gsub("git@github.com:", "https://www.github.com/") + url = url.gsub("git://", "https://www.") + + # If someone just passes in user/repo e.g. leereilly/leereilly.net + tokens = url.split('/') + if tokens.size == 2 + url = "https://www.github.com/#{tokens[0]}/#{tokens[1]}" + end + + return url +end + +def get_user_from_github_url(sanitized_github_url) + return sanitized_github_url.split('/')[3] +end + +def get_repo_from_github_url(sanitized_github_url) + return sanitized_github_url.split('/')[4] +end + +def get_high_scores(user, repo) + begin + # Kludge - three API calls + stored_user = User::create_from_username(user) + puts "Storing user: #{stored_user}" + stored_repo = Repo::create_from_username_and_repo(user, repo) + puts "Storing repo: #{stored_repo}" + + contributors_url = "http://github.com/api/v2/json/repos/show/#{user}/#{repo}/contributors" + + contributors_feed = Net::HTTP.get_response(URI.parse(contributors_url)) + contributors = contributors_feed.body + contributors_result = JSON.parse(contributors) + repository_contributors = contributors_result['contributors'] + contributors_array = Array.new + repository_contributors.each do |repository_contributor| + user_hash = Hash.new + user_hash[:login] = repository_contributor['login'] + user_hash[:email] = repository_contributor['email'] + user_hash[:gravatar_id] = repository_contributor['gravatar_id'] + user_hash[:location] = repository_contributor['location'] + user_hash[:contributions] = repository_contributor['contributions'].to_i + contributors_array << user_hash + end + return contributors_array + rescue + raise "Sorry, this GitHub repository doesn't seem to exist or is private" + end +end + + +get '/:user/:repo/high_scores/?' do + @title = "New" + @user = params[:user] + @repo = params[:repo] + @high_scores = get_high_scores(@user, @repo) + @display_small_search = true + erb :high_scores +end diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..88fffe3 --- /dev/null +++ b/config.ru @@ -0,0 +1,10 @@ +require 'rubygems' +require 'sinatra.rb' + +# Sinatra defines #set at the top level as a way to set application configuration +set :views, File.join(File.dirname(__FILE__), 'app','views') +set :run, false +set :env, (ENV['RACK_ENV'] ? ENV['RACK_ENV'].to_sym : :development) + +require 'app/main' +run Sinatra.application \ No newline at end of file diff --git a/db/db.db b/db/db.db new file mode 100644 index 0000000000000000000000000000000000000000..cbe814f84688e308ec7d7fe4dd7b7c6a071dafa1 GIT binary patch literal 10240 zcmeHM&u`l{6qal!S`UGj7KS(E5H3K_1Whbaviw8X;JAU88jI7^QC8$I7?ecYT4hP4 zq!~G8MX`Tk*q^Zb{)64N!j5MXU}zT zc6oXV&b#eSvwH=;XLYN z4e-3(MWY3qg#(k=en{(?5BCwlZa8lpqM&C7L4?!g(@X*{BId#k#waw0m@Guc*Rg0t zj)$xTC;gjzHGkvSwh$O!Wo*B)=Y#zy7-Fl37Si{8?0z8s$hS~99i+EAtqZ-`Ip2Rn zf(fn139V5;Ye`O-G_8s4qi7x2;V?3mOtw4b;nI1FN622749iG2=OOmE~P_j=y! zcqUplIl^myfodO<5uF-KrjkkU4BGSqeE(&bb$(e?Uj>$7^$D9dSZ= z9j*PG`*TJ9mRXt%0fqoWU;%-fcJ3kfd1qVv;w!FM;2N9xe7*r?sK_$xBclSXs$o?v z)ha7hqpw)VtW~5sG!(2j7!zze&NXcu%{nC)ho=~WZsHn-p|6SJcswqpA}){%z9z^u zZTeaWo}z2eq)W>IIBs6jg;|!Qx+v8|MFO&{$u+H92ZvHsl4J?Okjm1~hTT8?yco_WaSJ6rqkWcP7Q$mV8&5~7+_6V_x|=^JGkmCXvm(5zWT zrLRi;x-s&;_eO>ndZVMsYe`o_qKb6Z+CQrGti*{HbG{IO6aVJA4)y z2cYemr4&C?N~$81L|9KKDQmQmP*Sc}DiFeIRf)+-c&X`7(G;l3@;hGmmF4AKEmD0_ zOT7MPg}*rAU*RA6!w!Z3Lx3T`5MT%}1XdV!&1Q37X2UK!- zF9V2Ek7y2w=i25}1eo?pBr>k)p3DH3=xJ&^oht50xk+8f*jx=cM#Ey zDG+b80J^_KHJegMB21;B_@|GY08>pMZc|l&ss@rM%K(-&wW7i5L^x2&9~KNgqk_RU z+IYM{>&q94`9dS#nCVALDxCSmSu56|Qk^&%_&&R7Zcvm|QBnX@HC546b&}hAjcM8U ze@^(46aEl>5k|DZ4u$|jfFZyTU; Dm2e^! literal 0 HcmV?d00001 diff --git a/lib/Contributor.rb b/lib/Contributor.rb new file mode 100644 index 0000000..d4c3792 --- /dev/null +++ b/lib/Contributor.rb @@ -0,0 +1,48 @@ +require 'rubygems' +require 'data_mapper' +require 'net/http' +require 'json' +require 'uri' + +DataMapper::Logger.new($stdout, :debug) +DataMapper.setup(:default, 'sqlite:////Users/lreilly/Projects/github-scores.com/db/db.db') + +class Contributor + include DataMapper::Resource + + API_VERSION = 'v2' + BASE_URL = 'http://github.com/api/' + API_VERSION + '/json/user/show/' + + property :id, Serial + property :login, String + property :gravatar_id, String + property :contributions, String + + def self.create_from_user_and_repo(user, repo) + stored_user = User::create_from_username(user) + stored_repo = Repo::create_from_username_and_repo(user, repo) + + contributors_url = "http://github.com/api/v2/json/repos/show/#{user}/#{repo}/contributors" + contributors_feed = Net::HTTP.get_response(URI.parse(contributors_url)) + contributors = contributors_feed.body + contributors_result = JSON.parse(contributors) + repository_contributors = contributors_result['contributors'] + contributors_array = Array.new + + repository_contributors.each do |repository_contributor| + contributor = Contributor.new + contributor.login = repository_contributor['login'] + contributor.gravatar_id = repository_contributor['gravatar_id'] + contributor.contributions = repository_contributor['contributions'] + contributor.save + end + end + + def self.get_json_response(url) + Net::HTTP.get_response(URI.parse(url)) + end +end + +DataMapper::auto_upgrade! +contributors = Contributor::create_from_user_and_repo('leereilly', 'leereilly.net') + diff --git a/lib/Repo.rb b/lib/Repo.rb new file mode 100644 index 0000000..0ca0f35 --- /dev/null +++ b/lib/Repo.rb @@ -0,0 +1,84 @@ +require 'rubygems' +require 'data_mapper' +require 'net/http' +require 'json' +require 'uri' + +DataMapper::Logger.new($stdout, :debug) +DataMapper.setup(:default, 'sqlite:////Users/lreilly/Projects/github-scores.com/db/db.db') + +class Repo + include DataMapper::Resource + + API_VERSION = 'v2' + BASE_URL = 'http://github.com/api/' + API_VERSION + '/json/repos/show/' + + property :id, Serial + property :owner, String + property :url, String + property :homepage, String + property :name, String + property :description, String + property :parent, String + property :has_issues, String + property :source, String + property :watchers, String + property :has_downloads, String + property :fork, String + property :forks, String + property :has_wiki, String + property :pushed_at, String + property :open_issues, String + property :updated_at, DateTime + + def self.create_from_username_and_repo(username, repo) + repo_data_url = Repo.get_repo_data_url(username, repo) + + if found_repo = Repo.first(:owner => username, :name => repo) + if Time.now - Time.parse(found_repo.updated_at.to_s) <= 60*60*24 + puts "Repo created less than 24 hours ago. Returning DB record" + return found_repo + else + puts "Updating current repo" + repo = found_repo + end + else + puts "User not found; using web services" + repo = Repo.new + end + + repo_data_response = get_json_response(repo_data_url) + repo_data = JSON.parse(repo_data_response.body) + repo_data = repo_data['repository'] + + repo.owner = repo_data['owner'] + repo.name = repo_data['name'] + repo.url = repo_data['url'] + repo.homepage = repo_data['homepage'] + repo.description = repo_data['description'] + repo.parent = repo_data['parent'] + repo.has_issues = repo_data['has_issues'] + repo.source = repo_data['source'] + repo.watchers = repo_data['watchers'] + repo.has_downloads = repo_data['has_downloads'] + repo.fork = repo_data['fork'] + repo.forks = repo_data['forks'] + repo.has_wiki = repo_data['has_wiki'] + repo.pushed_at = repo_data['pushed_at'] + repo.open_issues = repo_data['open_issues'] + repo.updated_at = Time.now + repo.save! + return repo + end + + def self.get_json_response(url) + Net::HTTP.get_response(URI.parse(url)) + end + + def self.get_repo_data_url(username, repo) + return BASE_URL + username + '/' + repo + end +end + +DataMapper.auto_upgrade! + diff --git a/lib/User.rb b/lib/User.rb new file mode 100644 index 0000000..ecabbae --- /dev/null +++ b/lib/User.rb @@ -0,0 +1,83 @@ +require 'rubygems' +require 'data_mapper' +require 'net/http' +require 'json' +require 'uri' + +DataMapper::Logger.new($stdout, :debug) +DataMapper.setup(:default, 'sqlite:////Users/lreilly/Projects/github-scores.com/db/db.db') + +class User + include DataMapper::Resource + + API_VERSION = 'v2' + BASE_URL = 'http://github.com/api/' + API_VERSION + '/json/user/show/' + + property :id, Serial + property :github_id, String + property :gravatar_id, String + property :login, String + property :email, String + property :name, String + property :blog, String + property :company, String + property :location, String + property :type, String + property :permission, String + property :created_at, String + property :public_repo_count, String + property :public_gist_count, String + property :following_count, String + property :followers_count, String + property :updated_at, DateTime + + + def self.create_from_username(username) + if found_user = User.first(:login => username) + if Time.now - Time.parse(found_user.updated_at.to_s) <= 60*60*24 + puts "User created less than 24 hours ago. Returning DB record" + return found_user + else + puts "Updating current user" + user = found_user + end + else + puts "User not found; using web services" + user = User.new + end + + user_data_url = User.get_user_data_url(username) + user_data_response = get_json_response(user_data_url) + user_data = JSON.parse(user_data_response.body) + user_data = user_data['user'] + + user.github_id = user_data['id'] + user.gravatar_id = user_data['gravatar_id'] + user.login = user_data['login'] + user.email = user_data['email'] + user.name = user_data['name'] + user.blog = user_data['blog'] + user.company = user_data['company'] + user.location = user_data['location'] + user.type = user_data['type'] + user.permission = user_data['permission'] + user.created_at = user_data['created_at'] + user.public_repo_count = user_data['public_repo_count'] + user.public_gist_count = user_data['public_gist_count'] + user.following_count = user_data['following_count'] + user.followers_count = user_data['followers_count'] + user.updated_at = Time.now + user.save! + return user + end + + def self.get_json_response(url) + Net::HTTP.get_response(URI.parse(url)) + end + + def self.get_user_data_url(username) + return BASE_URL + username + end +end + +DataMapper::auto_upgrade! diff --git a/lib/tasks/migrate.task b/lib/tasks/migrate.task new file mode 100644 index 0000000..0b43835 --- /dev/null +++ b/lib/tasks/migrate.task @@ -0,0 +1,3 @@ +task :migrate do + DataMapper.auto_migrate! +end diff --git a/public/css/style.css b/public/css/style.css new file mode 100644 index 0000000..a03b7d0 --- /dev/null +++ b/public/css/style.css @@ -0,0 +1,93 @@ +@font-face { + font-family: "ArcadeClassic"; + src: url("../font/ArcadeClassic.otf") format("opentype"); +} + +body { + font-family: "ArcadeClassic"; + letter-spacing: 2px; + word-spacing: 0.5em; + color: white; + background: #252525 url(/img/bg.png) top center no-repeat; +} + +#wrapper { + margin: 0 auto; + width: 700px; +} + +#content { + width: 100%; +} + +a { + text-decoration: none; + color: white; +} + +td { + font-size: 40px; +} + +th { + font-size: 40px; + font-weight: bold; +} + +td.small { + font-size: 20px; + padding:10px; +} + +th.small { + font-size: 20px; + font-weight: bold; + padding:10px; + color: yellow; +} + +table { + vertical-align: center; + margin-left: auto; + margin-right: auto; +} + +input { + color: #FFFFFF; + font-family: ArcadeClassic; + font-weight: bold; + font-size: 24px; + background-color: #72A4D2; +} + +input.small { + font-size: 12px; +} + +#header_search { + text-align: right; + float:right; +} + +.header_search { + text-align: right; + float: right; +} + +p.center { + text-align: center; +} + +h1 { + text-align: lightblue; +} + +h2 { + text-align: center; + color: lightblue; +} + +h3 { + /**text-align: center;*/ + color: lightblue; +} \ No newline at end of file diff --git a/public/font/ArcadeClassic.otf b/public/font/ArcadeClassic.otf new file mode 100644 index 0000000000000000000000000000000000000000..e346fd6e0ec4617f89091fe609fec8b95d7d14c4 GIT binary patch literal 4176 zcmd^CZE#dq8Gg^bo4t@tlk#zaVkmdBn}k3J`QZC|ckk|!76>K*tUAh)gzT~*#3V>d zXFAxaX=!K+YG<73kJeGAj8ce1oyt@P9W6tRll{Wcu~ivIr#k-WKs^g*X?)JTcloF| z!=H{n+`IR@ALqUAIp?|Oea>!MXJ;FE=qRbw7>Y!UfBf}3UnMFzN;G{>B+|L<(RaUb ziRi)QL{u3y!x4It{6yt{hP|k*V_9>@8(mFA%z(Y8>p*Ov`Gad6L}~%Pz44w{_tkeZ z@1gH4+$-a7lxXUH=+|)j;|GQx|JpC5UNH^vix0#eAE2!}(8cDVareg#^t}1Ei3seY zM9LEb2Zx5Io}$^9-yZZE#L(jI{L76iU#wXFA$ipI;h{@|7xxwA6h>zSwI22~Qlu9j zJfqf6tw#I4-EU>G`|P%r2=mwq!=)@@C#VGDzok46`z2elUr{qtWw1*&_Q$e|#BxB+x2-dp&q^F!p>np&(N*}Pj_!i~B}XqIg}vhFZuq}Ni>Qn0 zFz-hwMoBtId!a`tK|}DzsfPw($7mSsVe4w30rVch6{BuCgu90t&?XVF6t_ujXt$&7 zw5(R@fYwf}6r`Qd!tm~f)k#|rBRvKMEGg}FsztnkR~3f74RIZ~TG6weyx5>!b;cvH zO4d?Q32Lrn@64#AnU(J7OsbHNl~M&Qq#D%Ma$1Kvih{>Jjjec!enh{B z?Moz@8XMQFZs=`~Z*x%dt#6W!IYFn(im$j-Z-n?RkY?jMr zRr4oPWOt!)mmwi!VDcF>lV$-^o#xP7nnw@Oe5xWJPN!F!OHu3_XS__#Atd zJ;#o*=h-Mb&R$?IvX|Hic9OPA@aJI~>p+E1(f8;w-DFiP%J#GGvI+Kk_D^hIJ) zsDD(ibNb zfgEKlRoEnwJTH3fT-xnq_P7YjWq5B&j9ZKSp%buqj!}xqSx^;5Fp9GZ6M!TzWKxsB z6$kSRZ#vEWfNUK7{&YAjs*8#Eehac3kGlnTiL=}b?0A*49zJfvB>dSB9}5Reu`jIg zaSLni)2&HN=-$#}JgHa7838U|>1HG~N|CNONx#+AtyhK$;L`tu<=Kr+5NXiMl z&K8Ry1}F3-(n6|w+q)E^azbygt!1`olmanL$SLBSV*%1}T5q-;amUfEx0D95`f@A$ zw7#PBSVoVUcsa#@1^P<#Rpy`8S2-zHJF#n|oY2?WVjV;mzpAg7CXnA?yZ>(&f1|hj z%P866l^-g<{XIYXHGN_rW!kY{8L@vd>5j9a;Sc1z;sy4rqd!(oJ=@pL0aq$Y8fyp@VMdB zzOYCMi%Z&&V#PlG1HgKV9c09KIvq~sv`E_R!Q|6HtVh=5oljY_<8iD(3nNVODqvg4 zeG%@>7THOYOmjE40%)M(D{SEYe87Um4_FcwJU0DeE@y%3ek}BIi0>0#F`mVuKyulv z#e@#-;Z!hk3$1J>t=V|-YBK|d&ragtvC+~bTwpyj6%NW%L7oThw2a13aqAVzjpr3f zybsYUH-X$T+$f9$`52A}`v{Pyi6%MRnFVS<{=*_1%m!Ln6AULjes)=w{Sy^2>>6!C zh2UQv%~fiM;SM-b>i2uQJ{H?@+n##wwtlaC_w4uomuEhaaqNH3zy&yb{02UEek7`N T@uRUnNqIh5c}hzB?+*MM-J}6P literal 0 HcmV?d00001 diff --git a/public/img/bg.png b/public/img/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..e08e47d307a95a1eda87fc557d87c55ebcea951d GIT binary patch literal 42196 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 literal 0 HcmV?d00001 diff --git a/public/img/favicon.png b/public/img/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..ba3b4954844065003a73d507f16325e726aef738 GIT binary patch literal 3145 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 + + + + + + + + + + + + + + + +

!

+ + + + + + + + + + + + + + + + + + + + + + +
15600mojomboSan Francisco
5200schaconSan Francisco, CA
3400defunktSan Francisco, CA
+ + + + + \ No newline at end of file diff --git a/test/app_test.rb b/test/app_test.rb new file mode 100644 index 0000000..46fd2a6 --- /dev/null +++ b/test/app_test.rb @@ -0,0 +1,66 @@ +require 'rubygems' +require 'test/unit' +require 'rack/test' +require '../app' + +ENV['RACK_ENV'] = 'test' + +class AppTest < Test::Unit::TestCase + include Rack::Test::Methods + + def app + Sinatra::Application + end + + def test_a_variety_of_urls_work + valid_urls = [ + 'http://www.github.com/leereilly/leereilly.net', + 'https://www.github.com/leereilly/leereilly.net', + 'git@github.com:leereilly/leereilly.net.git', + 'git://github.com/leereilly/leereilly.net.git', + 'github.com/leereilly/leereilly.net.git', + 'www.github.com/leereilly/leereilly.net.git', + 'leereilly/leereilly.net' + ] + valid_urls.each do |valid_url| + get '/', params = {:github_url => valid_url} + assert_equal last_response.status, 302 + follow_redirect! + assert_equal last_response.status, 200 + end + end + + def test_landing_page_works_as_expected + get '/', params = {:github_url => 'http://www.github.com/leereilly/leereilly.net'} + assert_equal last_response.status, 302 + follow_redirect! + assert_equal last_response.status, 200 + end + + def test_search_redirected_to_seo_friendly_url + + end + + def test_cute_404_page + get '/lee/lee/lee' + assert_equal last_response.status, 404 + assert last_response.body.include? 'Sorry, but this cat is in another castle!' + end + + def test_that_peeps_get_credit_where_credit_is_deserved + get '/credits' + assert last_response.ok? + kudos_to = Array[ + 'Ruby', + 'Sinatra', + 'Passenger', + 'Dreamhost', + 'Github', + 'Lee Reilly', + 'Al Gore'] + kudos_to.pop + kudos_to.each do |kudo_to| + assert last_response.body.include?(kudo_to) + end + end +end \ No newline at end of file diff --git a/views/about.erb b/views/about.erb new file mode 100644 index 0000000..5176b43 --- /dev/null +++ b/views/about.erb @@ -0,0 +1,9 @@ +<%= erb :header %> +

About

+

Git is an extremely fast, efficient, distributed version control system ideal for the collaborative development of software.

+ +

git·hub is the best way to collaborate with others. Fork, send pull requests and manage all your public and private git repositories.

+ +

git·hub·scores is a fun way to rank software project contributors in a 8-bit, 80's-tastic viewing environment.

+ +<%= erb :footer %> \ No newline at end of file diff --git a/views/credits.erb b/views/credits.erb new file mode 100644 index 0000000..f265f9b --- /dev/null +++ b/views/credits.erb @@ -0,0 +1,7 @@ +<%= erb :header %> +

Credits

+

Running with Ruby, Sinatra, Passenger on a shared Dreamhost server

+

Powered by the Github API

+

Written by Lee Reilly

+

Octocat logo used with permission

+<%= erb :footer %> \ No newline at end of file diff --git a/views/footer.erb b/views/footer.erb new file mode 100644 index 0000000..0c9db45 --- /dev/null +++ b/views/footer.erb @@ -0,0 +1,11 @@ +

Credits 0

+

© Lee Reilly 2011 Fork me on Github! TWEET THIS!

+

+

[about] [contact] [help] [recent searches]

+ + + + + + + \ No newline at end of file diff --git a/views/header.erb b/views/header.erb new file mode 100644 index 0000000..9183d33 --- /dev/null +++ b/views/header.erb @@ -0,0 +1,12 @@ + + + + + + + + + <%= erb :small_search if @display_small_search == true %>

Github High Scores

+
+
+
\ No newline at end of file diff --git a/views/help.erb b/views/help.erb new file mode 100644 index 0000000..d6a3381 --- /dev/null +++ b/views/help.erb @@ -0,0 +1,29 @@ +<%= erb :header %> + +

Help

+ +

What on Earth is a Git? A Github? You did what with your what now?

+

Please check out the 'about' section for a general overview. + +

How do I view the high scores for my Github repository?

+

Simply enter the URL of your Github repository into the search box. Currently we support the following formats...

+
    +
  • http://www.github.com/mojombo/octobeer
  • +
  • https://www.github.com/mojombo/octobeer
  • +
  • git@github.com:mojombo/octobeer
  • +
  • git://github.com/mojombo/octobeer
  • +
  • github.com/mojombo/octobeer
  • +
  • www.github.com/mojombo/octobeer
  • +
  • mojombo/octobeer
  • +
+ +

It's Not Working!

+

Please create an issue in the Github repository

+ +

I'd Like To Contribute

+

You know what to do! #fork #pullRequest

+ +

This looks like a web site from the 80s! Running it through the Geocitiesizer is actually an improvement!!!

+

Cheers! :BEER:

+ +<%= erb :footer %> \ No newline at end of file diff --git a/views/high_scores.erb b/views/high_scores.erb new file mode 100644 index 0000000..e8faed1 --- /dev/null +++ b/views/high_scores.erb @@ -0,0 +1,24 @@ +<%= erb :header %> + +

<%= @user %> >> <%= @repo %> >> High Scores

+ + + + + + + + <% @high_scores.each do |high_score| %> + + + + + + <% end %> +
ScoreAvatarUser
<%= high_score[:contributions]*100 %><%= high_score[:login] %>
+

Permalink: https://github.com/<%= @user %>/<%= @repo %>

+ +

TWEET THIS!

+ +<%= erb :footer %> + diff --git a/views/index.erb b/views/index.erb new file mode 100644 index 0000000..bb71d5a --- /dev/null +++ b/views/index.erb @@ -0,0 +1,9 @@ +<%= erb :header %> +

<%= @title %>

+

<%= @text %>

+ +<%= erb :search_form %> + + +<%= erb :footer %> + diff --git a/views/not_found.erb b/views/not_found.erb new file mode 100644 index 0000000..6d02632 --- /dev/null +++ b/views/not_found.erb @@ -0,0 +1,11 @@ +<%= erb :header %> +
+

<%= @title %>

+

<%= @text %>

+ +
+
+<%= erb :search_form %> + +<%= erb :footer %> + diff --git a/views/random.erb b/views/random.erb new file mode 100644 index 0000000..e69de29 diff --git a/views/recent.erb b/views/recent.erb new file mode 100644 index 0000000..e7ce062 --- /dev/null +++ b/views/recent.erb @@ -0,0 +1,9 @@ +<%= erb :header %> + +

Recent searches

+ +<% @repos.each do |repo| %> +<%= "

#{repo.owner}/#{repo.name}

" %> +<% end %> + +<%= erb :footer %> \ No newline at end of file diff --git a/views/repo.erb b/views/repo.erb new file mode 100644 index 0000000..59303ab --- /dev/null +++ b/views/repo.erb @@ -0,0 +1,26 @@ +<%= erb :header %> + +

<%= @repo.owner %> >> <%= @repo.name %>

+ +
+
ID
+
<%= @repo.id %>
+ +
URL
+
<%= @repo.url %>
+ +
Homepage
+
<%= @repo.homepage %>
+ +
Name
+
<%= @repo.name %>
+ +
Description
+
<%= @repo.description %>
+ +
Created by
+
<%= @repo.owner %>
+ +
+ +<%= erb :footer %> diff --git a/views/search_form.erb b/views/search_form.erb new file mode 100644 index 0000000..0ff900a --- /dev/null +++ b/views/search_form.erb @@ -0,0 +1,6 @@ +
+
+ + +
+
\ No newline at end of file diff --git a/views/small_search.erb b/views/small_search.erb new file mode 100644 index 0000000..daa7c11 --- /dev/null +++ b/views/small_search.erb @@ -0,0 +1,5 @@ +
+
+ +
+
\ No newline at end of file diff --git a/views/user.erb b/views/user.erb new file mode 100644 index 0000000..fc17472 --- /dev/null +++ b/views/user.erb @@ -0,0 +1,43 @@ +<%= erb :header %> + +

<%= @user.login %>

+ +<%= @user.login %>< + +
+
ID
+
<%= @user.id %>
+ +
Login
+
<%= @user.login %>
+ +
Email
+
<%= @user.email %>
+ +
Blog
+
<%= @user.blog %>
+ +
Company
+
<%= @user.company %>
+ +
Location
+
<%= @user.location %>
+ +
Github'n since
+
<%= @user.created_at %>
+ +
Followers
+
<%= @user.followers_count %>
+ +
Following
+
<%= @user.following_count %>
+ +
Public repos
+
<%= @user.public_repo_count %>
+ +
Public gists
+
<%= @user.public_gist_count %>
+ +
+ +<%= erb :footer %>