Commit 9fea730da3f142c6cd00ed669efab9988d4338be

count how many times a repository has been cloned from ip/country

Signed-off-by: David A. Cuadrado <krawek@gmail.com>

Commit diff

app/models/cloner.rb

 
1class Cloner < ActiveRecord::Base
2 belongs_to :repository
3end
toggle raw diff

app/models/repository.rb

 
99 :order => "status, id desc", :dependent => :destroy
1010 has_many :proposed_merge_requests, :foreign_key => 'source_repository_id',
1111 :class_name => 'MergeRequest', :order => "id desc", :dependent => :destroy
12 has_many :cloners, :dependent => :destroy
1213
1314 validates_presence_of :user_id, :project_id, :name
1415 validates_format_of :name, :with => /^[a-z0-9_\-]+$/i,
3131
3232 def self.find_by_path(path)
3333 repo_name, project_name = (path.split('/') - GitoriousConfig['repository_base_path'].split('/')).reverse
34
3435 project = Project.find_by_slug!(project_name)
3536 project.repositories.find_by_name(repo_name.sub(/\.git/, ""))
3637 end
229229 users_by_email = users.inject({}){|hash, user| hash[user.email] = user; hash }
230230 users_by_email
231231 end
232
233 def cloned_from(ip, country_code = "--", country_name = nil)
234 cloners.create(:ip => ip, :date => Time.now.utc, :country_code => country_code, :country => country_name)
235 end
232236
233237 protected
234238 def set_as_mainline_if_first
toggle raw diff

app/views/repositories/_infobox.html.erb

 
4141 </div>
4242 </li>
4343 <% end -%>
44 <li>The repository has been cloned <%= @repository.cloners.size %> times.</li>
4445</ul>
toggle raw diff

data/GeoIP.dat

 
toggle raw diff

db/migrate/600_create_cloners.rb

 
1class CreateCloners < ActiveRecord::Migration
2 def self.up
3 create_table :cloners do |t|
4 t.string :ip
5 t.string :country_code, :length => 2
6 t.string :country
7 t.datetime :date
8 t.integer :repository_id
9 end
10 end
11
12 def self.down
13 drop_table :cloners
14 end
15end
16
toggle raw diff

script/git-daemon

 
22
33require 'rubygems'
44require 'daemons'
5require 'geoip'
56require 'socket'
67
8ENV["RAILS_ENV"] ||= "production"
79require File.dirname(__FILE__)+'/../config/environment'
810
11Rails.configuration.log_level = :info # Disable debug
12
913BASE_PATH = File.expand_path(GitoriousConfig['repository_base_path'])
1014
1115module Git
2424 def initialize
2525 daemonize(File.join(RAILS_ROOT, "log", "git-daemon.log"))
2626
27 @geoip = GeoIP.new(File.join(RAILS_ROOT, "data", "GeoIP.dat"))
2728 trap "CLD" do
2829 pid = Process.wait
2930 log(pid, "Disconnected. (status=#{$?.exitstatus})")
3232
3333 port = 9418
3434 server = TCPServer.new('localhost', port)
35
36 service_regexp = /(\d{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze
35 service_regexp = /(\w{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze
3736 while session = server.accept
3837 line = session.recv(1000)
3938 timeout = 30
4343 host = $4
4444
4545 path = "#{BASE_PATH}/#{path}"
46
4746 if !File.directory?(path)
4847 log(Process.pid, "Invalid path: #{path}")
4948 session.close
5049 next
5150 end
5251
52 if !File.exist?(File.join(path, "git-daemon-export-ok"))
53 session.close
54 next
55 end
56
5357 Dir.chdir(path) do
5458 cmd = "git-upload-pack --strict --timeout=#{timeout} ."
5559
5660 fork do
61 repository = nil
62 begin
63 ActiveRecord::Base.allow_concurrency = true
64 repository = ::Repository.find_by_path(path)
65 rescue Exception
66 end
5767 pid = Process.pid
5868 domain, port, name, ip = session.addr
5969 log(pid, "Connection from #{ip}")
7272 $stdin.reopen(session)
7373 session.close
7474
75 if repository
76 localization = @geoip.country(ip)
77 repository.cloned_from(ip, localization[3], localization[5])
78 else
79 log(pid, "Cannot find repository: #{path}")
80 end
81
7582 exec(cmd)
76 exit
83
84 exit!
7785 end
7886 end
87 else
88 $stderr.puts "Invalid request: #{line}"
89 session.close
7990 end
8091 end
8192 end
toggle raw diff

spec/fixtures/cloners.yml

 
1# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
3argentina:
4 ip: 200.45.34.21
5 country: Argentina
6 country_code: AR
7 date: 2008-04-13 23:40:30
8
9mexico:
10 ip: 200.53.12.21
11 country: Mexico
12 country_code: MX
13 date: 2008-04-13 23:40:30
toggle raw diff

spec/models/cloner_spec.rb

 
1require File.dirname(__FILE__) + '/../spec_helper'
2require 'geoip'
3
4describe Cloner do
5 before(:all) do
6 @geoip = GeoIP.new(File.join(RAILS_ROOT, "data", "GeoIP.dat"))
7 end
8
9 before(:each) do
10 @cloner = Cloner.new
11 end
12
13 it "should has a valid country" do
14 localization = @geoip.country(cloners(:argentina).ip)
15 localization[3].should == cloners(:argentina).country_code
16 localization[5].should == cloners(:argentina).country
17 end
18end
toggle raw diff