<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[116798] branches/gsoc11-statistics/stats-server</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="https://trac.macports.org/changeset/116798">116798</a></dd>
<dt>Author</dt> <dd>cal@macports.org</dd>
<dt>Date</dt> <dd>2014-02-07 11:46:31 -0800 (Fri, 07 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>macports stats: move bin directory from level above, adjust for deployment</pre>

<h3>Added Paths</h3>
<ul>
<li>branches/gsoc11-statistics/stats-server/bin/</li>
<li><a href="#branchesgsoc11statisticsstatsserverbinadd_ports">branches/gsoc11-statistics/stats-server/bin/add_ports</a></li>
<li><a href="#branchesgsoc11statisticsstatsserverbingenerate_portspy">branches/gsoc11-statistics/stats-server/bin/generate_portspy</a></li>
<li><a href="#branchesgsoc11statisticsstatsserverbingenerate_seed">branches/gsoc11-statistics/stats-server/bin/generate_seed</a></li>
<li><a href="#branchesgsoc11statisticsstatsserverbinnew_ports">branches/gsoc11-statistics/stats-server/bin/new_ports</a></li>
<li><a href="#branchesgsoc11statisticsstatsserverbinpopulatepy">branches/gsoc11-statistics/stats-server/bin/populate.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesgsoc11statisticsstatsserverbin"></a>
<div class="propset"><h4>Property changes: branches/gsoc11-statistics/stats-server/bin</h4>
<pre class="diff"><span>
</span></pre></div>
<a id="svnignore"></a>
<div class="addfile"><h4>Added: svn:ignore</h4></div>
<span class="cx">erubis
</span><span class="cx">rackup
</span><span class="cx">rails
</span><span class="cx">rake
</span><span class="cx">rdoc
</span><span class="cx">ri
</span><span class="cx">sprockets
</span><span class="cx">thor
</span><span class="cx">tilt
</span><span class="cx">tt
</span><span class="cx">uuid
</span><a id="branchesgsoc11statisticsstatsserverbinadd_ports"></a>
<div class="addfile"><h4>Added: branches/gsoc11-statistics/stats-server/bin/add_ports (0 => 116798)</h4>
<pre class="diff"><span>
<span class="info">--- branches/gsoc11-statistics/stats-server/bin/add_ports                                (rev 0)
+++ branches/gsoc11-statistics/stats-server/bin/add_ports        2014-02-07 19:46:31 UTC (rev 116798)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+#!/usr/bin/env ruby
+require 'rubygems'
+require 'active_record'
+require 'fileutils'
+#require 'trac4r'
+
+ROOT = File.expand_path(File.dirname(__FILE__) + &quot;/../&quot;) 
+TIME_FILE = &quot;#{ROOT}/sync-timestamp&quot;
+NEW_PORTS = &quot;#{ROOT}/bin/new_ports&quot;
+PORT_INDEX = &quot;/opt/local/var/macports/sources/rsync.macports.org/release/tarballs/ports&quot;
+RAILS_ROOT = &quot;#{ROOT}&quot;
+MODE = 'production'
+
+require File.expand_path(RAILS_ROOT + '/app/models/category.rb',  __FILE__)
+require File.expand_path(RAILS_ROOT + '/app/models/port.rb',  __FILE__)
+
+
+if File.exists?(TIME_FILE)
+  $mtime = File.stat(TIME_FILE).mtime.to_i
+else
+  $mtime = 0
+end
+
+FileUtils.touch(TIME_FILE)
+
+$ports = Array.new
+$hashed_data = Hash.new
+
+db_info = YAML.load_file(File.expand_path(RAILS_ROOT + '/config/database.yml',  __FILE__))
+#db_info['development']['database'] = RAILS_ROOT + &quot;/&quot; + db_info['development']['database']
+#puts db_info[MODE].to_yaml
+ActiveRecord::Base.establish_connection(db_info[MODE])
+#trac = Trac.new(TRAC_URL, TRAC_USER, TRAC_PASS)
+
+fp = IO.popen(&quot;#{NEW_PORTS} -m #{$mtime} #{PORT_INDEX}&quot;)
+new_ports = fp.read.split(&quot;\n&quot;)
+
+if new_ports.count &gt; 0
+  new_ports &lt;&lt; &quot;&quot; #add last blank line
+end
+
+
+new_ports.each do |line|
+  unless (line == &quot;&quot;)
+    data = line.match(/(\S+):\s+\{?(.+)\}?$/)
+    unless data.nil? #field missing, should record this if it happens
+      $hashed_data[data[1].to_sym] = data[2]
+    end
+  else
+    category_name = $hashed_data[:categories].try(:split, &quot; &quot;).try(:[], 0)
+    $category = Category.find_by_name(category_name)
+    if $category.nil?
+      $category = Category.new({:name =&gt; category_name})
+      $category.save
+    end
+
+    port = Port.find_by_name($hashed_data[:name])
+    if port.nil?
+      port = Port.new
+    end
+
+    port[:name] = $hashed_data[:name]
+    port[:path] = $hashed_data[:portdir]
+    port[:version] = $hashed_data[:version]
+    port[:description] = $hashed_data[:description]
+    port[:licenses] = $hashed_data[:license]
+    port[:category_id] = $category.id
+    port[:variants] = $hashed_data[:variants]
+    port[:maintainers] = $hashed_data[:maintainers]
+    port[:platforms] = $hashed_data[:platforms]
+    port[:categories] = $hashed_data[:categories]
+
+    $ports &lt;&lt; [$hashed_data, port]
+    port.save
+        puts &quot;Saved #{port[:name]}, version #{port[:version]}&quot;
+    $hashed_data = {}
+  end
+end
</ins><span class="cx">Property changes on: branches/gsoc11-statistics/stats-server/bin/add_ports
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<a id="branchesgsoc11statisticsstatsserverbingenerate_portspy"></a>
<div class="addfile"><h4>Added: branches/gsoc11-statistics/stats-server/bin/generate_portspy (0 => 116798)</h4>
<pre class="diff"><span>
<span class="info">--- branches/gsoc11-statistics/stats-server/bin/generate_portspy                                (rev 0)
+++ branches/gsoc11-statistics/stats-server/bin/generate_portspy        2014-02-07 19:46:31 UTC (rev 116798)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+#!/usr/bin/env ruby
+
+### Generate a valid ports.py for use in populating the database with
+### sample submissions. ports.py will be used by populate.py
+
+# This file adapted from generate_seed which is adapted from add_ports from MPWA
+
+# Note - this file must be executed from inside RAILS_ROOT 
+# otherwise it won't be able to connect to the database
+
+require 'rubygems'
+require 'active_record'
+require 'fileutils'
+
+ROOT = File.expand_path(File.dirname(__FILE__) + &quot;/../&quot;) 
+BIN_ROOT = &quot;#{ROOT}/bin&quot;
+RAILS_ROOT = &quot;#{ROOT}/stats-server&quot;
+require File.expand_path(RAILS_ROOT + '/app/models/port.rb',  __FILE__)
+
+$ports = Array.new
+$hashed_data = Hash.new
+
+db_info = YAML.load_file(File.expand_path(RAILS_ROOT + '/config/database.yml',  __FILE__))
+ActiveRecord::Base.establish_connection(db_info['development'])

+
+class String
+  # Escape single quotes
+  def escape_single_quotes
+    self.gsub(/'/, &quot;\\\\'&quot;)
+  end
+end
+
+def esc(str)
+  if not str.nil?
+    str.escape_single_quotes
+  else
+    str
+  end
+end
+
+path = &quot;#{BIN_ROOT}/ports.py&quot;
+portfile = File.new(path, &quot;w&quot;)
+
+if not portfile
+  puts &quot;Unable to open #{path}&quot; 
+end
+
+portfile.syswrite('port_list = [ ')
+
+# Output an array of dictionaries. Each dictionary represents a port
+# The dicts have the keys name, version, variants.
+
+# Load all ports
+ports = Port.all
+ports.each do | port |
+  # Write the port
+  portfile.syswrite('{')
+  portfile.syswrite(&quot;\'name\': \'#{port.name}\', \'version\': \'#{port.version}\', \'variants\': \'#{port.variants}'&quot;)
+  portfile.syswrite('},')
+end
+
+portfile.syswrite(']')
+
+portfile.close
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: branches/gsoc11-statistics/stats-server/bin/generate_portspy
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<a id="branchesgsoc11statisticsstatsserverbingenerate_seed"></a>
<div class="addfile"><h4>Added: branches/gsoc11-statistics/stats-server/bin/generate_seed (0 => 116798)</h4>
<pre class="diff"><span>
<span class="info">--- branches/gsoc11-statistics/stats-server/bin/generate_seed                                (rev 0)
+++ branches/gsoc11-statistics/stats-server/bin/generate_seed        2014-02-07 19:46:31 UTC (rev 116798)
</span><span class="lines">@@ -0,0 +1,113 @@
</span><ins>+#!/usr/bin/env ruby
+
+### Generate a valid seeds.rb for use in seeding the database with 
+### valid ports and categories
+
+# Note - this file must be executed from inside RAILS_ROOT 
+# otherwise it won't be able to connect to the database
+
+require 'rubygems'
+require 'active_record'
+require 'fileutils'
+
+TIME_FILE = &quot;/var/tmp/gsoc11-mpwa-sync&quot;
+ROOT = File.expand_path(File.dirname(__FILE__) + &quot;/../&quot;) 
+NEW_PORTS = &quot;#{ROOT}/bin/new_ports&quot;
+PORT_INDEX = &quot;/opt/local/var/macports/sources/rsync.macports.org/release/tarballs/ports&quot;
+RAILS_ROOT = &quot;#{ROOT}&quot;
+MODE = &quot;production&quot;
+
+require File.expand_path(RAILS_ROOT + '/app/models/category.rb',  __FILE__)
+require File.expand_path(RAILS_ROOT + '/app/models/port.rb',  __FILE__)
+
+
+if File.exists?(TIME_FILE)
+  $mtime = File.stat(TIME_FILE).mtime.to_i
+else
+  $mtime = 0
+end
+
+FileUtils.touch(TIME_FILE)
+
+# Output encoding magic comment
+puts &quot;# coding: UTF-8&quot;
+
+$ports = Array.new
+$hashed_data = Hash.new
+
+db_info = YAML.load_file(File.expand_path(RAILS_ROOT + '/config/database.yml',  __FILE__))
+ActiveRecord::Base.establish_connection(db_info[MODE])
+
+fp = IO.popen(&quot;#{NEW_PORTS} -m #{$mtime} #{PORT_INDEX}&quot;)
+new_ports = fp.read.split(&quot;\n&quot;)
+
+if new_ports.count &gt; 0
+  new_ports &lt;&lt; &quot;&quot; #add last blank line
+end
+
+class String
+  # Escape single quotes
+  def escape_single_quotes
+    self.gsub(/'/, &quot;\\\\'&quot;)
+  end
+end
+
+def esc(str)
+  if not str.nil?
+    str.escape_single_quotes
+  else
+    str
+  end
+end
+
+new_ports.each do |line|
+  unless (line == &quot;&quot;)
+    data = line.match(/(\S+):\s+\{?(.+)\}?$/)
+    unless data.nil? #field missing, should record this if it happens
+      $hashed_data[data[1].to_sym] = data[2]
+    end
+  else
+    category_name = $hashed_data[:categories].try(:split, &quot; &quot;).try(:[], 0)
+    $category = Category.find_by_name(category_name)
+    if $category.nil?
+      $category = Category.new({:name =&gt; category_name})
+      puts &quot;category = Category.new({:name =&gt; \'#{category_name}\'})&quot;
+      puts &quot;category.save&quot;
+      $category.save
+    end
+
+    port = Port.find_by_name($hashed_data[:name])
+    if port.nil?
+      port = Port.new
+    end
+
+    port[:name] = $hashed_data[:name]
+    port[:path] = $hashed_data[:portdir]
+    port[:version] = $hashed_data[:version]
+    port[:description] = $hashed_data[:description]
+    port[:licenses] = $hashed_data[:license]
+    port[:category_id] = $category.id
+    port[:variants] = $hashed_data[:variants]
+    port[:maintainers] = $hashed_data[:maintainers]
+    port[:platforms] = $hashed_data[:platforms]
+    port[:categories] = $hashed_data[:categories]
+
+    $ports &lt;&lt; [$hashed_data, port]
+    
+    puts &quot;port = Port.new&quot;
+    puts &quot;port[:name] = \'#{esc($hashed_data[:name])}\'&quot;
+    puts &quot;port[:path] = \'#{esc($hashed_data[:portdir])}\'&quot;
+    puts &quot;port[:version] = \'#{esc($hashed_data[:version])}\'&quot;
+    puts &quot;port[:description] = \'#{esc($hashed_data[:description])}\'&quot;
+    puts &quot;port[:licenses] = \'#{esc($hashed_data[:license])}\'&quot;
+    puts &quot;port[:category_id] = #{$category.id}&quot;
+    puts &quot;port[:variants] = \'#{esc($hashed_data[:variants])}\'&quot;
+    puts &quot;port[:maintainers] = \'#{esc($hashed_data[:maintainers])}\'&quot;
+    puts &quot;port[:platforms] = \'#{esc($hashed_data[:platforms])}\'&quot;
+    puts &quot;port[:categories] = \'#{esc($hashed_data[:categories])}\'&quot;
+    puts &quot;port.save&quot;
+
+    port.save
+    $hashed_data = {}
+  end
+end
</ins><span class="cx">Property changes on: branches/gsoc11-statistics/stats-server/bin/generate_seed
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<a id="branchesgsoc11statisticsstatsserverbinnew_ports"></a>
<div class="addfile"><h4>Added: branches/gsoc11-statistics/stats-server/bin/new_ports (0 => 116798)</h4>
<pre class="diff"><span>
<span class="info">--- branches/gsoc11-statistics/stats-server/bin/new_ports                                (rev 0)
+++ branches/gsoc11-statistics/stats-server/bin/new_ports        2014-02-07 19:46:31 UTC (rev 116798)
</span><span class="lines">@@ -0,0 +1,140 @@
</span><ins>+#!/bin/sh
+# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=tcl:et:sw=4:ts=4:sts=4
+# Run the Tcl interpreter \
+exec /usr/bin/tclsh &quot;$0&quot; &quot;$@&quot;
+
+catch {source \
+    [file join &quot;/opt/local/share/macports/Tcl&quot; macports1.0 macports_fastload.tcl]}
+package require macports
+package require Pextlib
+
+# Globals
+array set ui_options        [list]
+array set global_options    [list]
+array set global_variations [list]
+set port_options            [list]
+
+# Pass global options into mportinit
+mportinit ui_options global_options global_variations
+
+# Standard procedures
+proc print_usage args {
+    global argv0
+    puts &quot;Usage: $argv0 \[-d\] -m &lt;time&gt; \&lt;directory\&gt;&quot;
+    puts &quot;-d:\tOutput debugging information&quot;
+    puts &quot;-m:\tOutput ports newer than the given mtime&quot;
+}
+
+proc pindex {portdir} {
+    global target oldfd oldmtime qindex fd directory outdir \
+           ui_options port_options
+
+    # try to reuse the existing entry if it's still valid
+    if {[info exists qindex([string tolower [file tail $portdir]])]} {
+        try {
+            set mtime [file mtime [file join $directory $portdir Portfile]]
+            if {$oldmtime &lt; $mtime} {
+                set offset $qindex([string tolower [file tail $portdir]])
+                seek $oldfd $offset
+                gets $oldfd line
+                set name [lindex $line 0]
+                set len [lindex $line 1]
+                set line [read $oldfd $len]
+                array set portinfo $line
+
+                if {[info exists ui_options(ports_debug)]} {
+                    puts &quot;Found entry for $portdir&quot;
+                }
+
+                foreach field [array names portinfo] {
+                    puts $fd &quot;${field}: $portinfo($field)&quot;
+                }
+                puts $fd &quot;&quot;
+
+                return
+            }
+        } catch {*} {
+            ui_warn &quot;failed to open entry for ${portdir}&quot;
+        }
+    }
+}
+
+if {[expr $argc &gt; 4]} {
+    print_usage
+    exit 1
+}
+
+for {set i 0} {$i &lt; $argc} {incr i} {
+    set arg [lindex $argv $i]
+    switch -regex -- $arg {
+        {^-.+} {
+            if {$arg == &quot;-d&quot;} { # Turn on debug output
+                set ui_options(ports_debug) yes
+            } elseif {$arg == &quot;-m&quot;} { # output ports newer than mtime
+                incr i
+                set oldmtime [lindex $argv $i]
+            } else {
+                puts stderr &quot;Unknown option: $arg&quot;
+                print_usage
+                exit 1
+            }
+        }
+        default {
+            set directory [file join [pwd] $arg]
+        }
+    }
+}
+
+if {![info exists directory]} {
+    set directory .
+}
+
+if {![info exists oldmtime]} {
+    set oldmtime 0
+}
+
+# cd to input directory
+if {[catch {cd $directory} result]} {
+    puts stderr &quot;$result&quot;
+    exit 1
+} else {
+    set directory [pwd]
+}
+
+# Set output directory to full path
+if {[info exists outdir]} {
+    if {[catch {file mkdir $outdir} result]} {
+        puts stderr &quot;$result&quot;
+        exit 1
+    }
+    if {[catch {cd $outdir} result]} {
+        puts stderr &quot;$result&quot;
+        exit 1
+    } else {
+        set outdir [pwd]
+    }
+} else {
+    set outdir $directory
+}
+
+set outpath [file join $outdir PortIndex]
+# open old index for comparison
+if {[file isfile $outpath] &amp;&amp; [file isfile ${outpath}.quick]} {
+    if {![catch {set oldfd [open $outpath r]}] &amp;&amp; ![catch {set quickfd [open ${outpath}.quick r]}]} {
+        if {![catch {set quicklist [read $quickfd]}]} {
+            foreach entry [split $quicklist &quot;\n&quot;] {
+                set qindex([lindex $entry 0]) [lindex $entry 1]
+            }
+        }
+        close $quickfd
+    }
+} else {
+    set newest 0
+}
+
+set fd stdout
+mporttraverse pindex $directory
+if {[info exists oldfd]} {
+    close $oldfd
+}
+close $fd
</ins><span class="cx">Property changes on: branches/gsoc11-statistics/stats-server/bin/new_ports
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
<a id="branchesgsoc11statisticsstatsserverbinpopulatepy"></a>
<div class="addfile"><h4>Added: branches/gsoc11-statistics/stats-server/bin/populate.py (0 => 116798)</h4>
<pre class="diff"><span>
<span class="info">--- branches/gsoc11-statistics/stats-server/bin/populate.py                                (rev 0)
+++ branches/gsoc11-statistics/stats-server/bin/populate.py        2014-02-07 19:46:31 UTC (rev 116798)
</span><span class="lines">@@ -0,0 +1,149 @@
</span><ins>+#!/usr/bin/env python
+
+# populate.py
+# Simulates multiple users submitting realistic data
+# Uses curl to submit sample data and test rails submission code
+
+import random
+import string
+import uuid
+import json
+import subprocess
+import time
+from ports import port_list
+
+max_users = 250
+max_ports_per_user = 500
+
+url_testdeploy = 'http://statsdeploy.heroku.com/submissions'
+url_dev    = 'http://127.0.0.1:3000/submissions' 
+
+macports_versions = ['1.9.2', '1.9.99', '2.0']
+osx_versions = ['10.4', '10.5', '10.6']
+os_archs = ['i386', 'ppc']
+os_platforms = ['darwin']
+build_archs = ['x86_32', 'x86_64']
+gcc_versions = ['4.2.1', '4.3.6', '4.4.6', '4.5.3', '4.6.1']
+xcode_versions = ['2.5', '3.0', '3.1', '3.2', '4.0']
+
+# Generated user ids
+users = []
+
+# The probability that a new user will be added starts at prob_new_user
+prob_new_user = 95 # 95 %
+
+# Randomly choose entries for each category
+def build_os():
+        os = {}
+        os['macports_version'] = random.choice(macports_versions)
+        os['osx_version'] = random.choice(osx_versions)
+        os['os_arch'] = random.choice(os_archs)
+        os['os_platform'] = random.choice(os_platforms)
+        os['build_arch'] = random.choice(build_archs)
+        os['gcc_version'] = random.choice(gcc_versions)
+        os['xcode_version'] = random.choice(xcode_versions)
+        return os
+
+# Build up a space separated list of variants
+# It selects a random number of variants to include from a list of valid variants
+# for a port
+def build_variants(variants):
+        varlist = variants.split()
+        
+        size = random.randint(0, len(varlist))
+        randomlist = random.sample(varlist, size)
+        
+        return &quot; &quot;.join(randomlist)
+
+# Generate a list of ports for this user.
+def build_ports():
+        ports = []
+        
+        # Choose a random number between 0 and max_ports_per_user
+        n_ports = random.randint(0, max_ports_per_user)
+        
+        # Generate n_port ports
+        for i in range(n_ports):
+                
+                # Choose a random port from the list of all ports
+                port = random.choice(port_list)
+                
+                # Generate random version strings by appending a digit to the existing version
+                # eg: 2.2 -&gt; 2.2_6
+                # Only append once, check if this port's version has already been modified
+                if not 'mod' in port:
+                        append = ''.join(random.choice(string.digits) for i in xrange(1))
+                        port['version'] = port['version'] + '_' + append
+                        port['mod'] = True # Flag that this port's version has been modified
+                
+                # Build up a list of variants from all valid variants for this port
+                port['variants'] = build_variants(port['variants'])
+                
+                # Append to the list of ports to submit for this user
+                ports.append(port)
+        return ports
+
+def decay_probability():
+        global prob_new_user
+        
+        # Over time the probability that a new user will be added decreases as more users participate
+        decay_factor = 0.0001
+        n_users = len(users)
+        prob_decay = n_users * decay_factor
+        prob = prob_new_user - prob_decay
+        
+        prob_new_user = prob
+        
+        # Always keep a minimum 5% chance of growth to simulate users new to 
+        # macports users coming in and participating
+        if prob &lt;= 5:
+                prob_new_user = 5
+
+def generate_uuid():
+        idstr = str(uuid.uuid4())
+        users.append(idstr)
+        
+        return idstr
+
+def get_uuid():
+        # Check if there are any available uuids
+        if len(users) == 0:
+                return generate_uuid()
+        
+        decay_probability()
+        
+        # Add a new user 'prob_new_user' percent of the time
+        # This simulates a new user deciding to participate
+        x = random.uniform(1,100)
+        print str(prob_new_user) + &quot; n_users = &quot; + str(len(users))
+        if x &lt;= prob_new_user:
+                return generate_uuid()
+        else:
+                # Get a random uuid from the list (simulate an existing user updating their info)
+                uuid = random.choice(users)
+                return uuid
+
+def submit():
+        #url = url_testdeploy
+        url = url_dev
+        idstr = get_uuid()
+        
+        data = {}
+        
+        data['id'] = idstr
+        data['os'] = build_os()
+        data['active_ports'] = build_ports()
+        
+        json_enc = json.dumps(data)
+        args = &quot;-d \'submission[data]=%s\'&quot; % json_enc
+        pid = subprocess.Popen('curl ' + args + ' ' + url, shell=True)
+        pid.wait()
+
+def main():
+        random.seed()
+        for x in range(max_users):
+                submit()
+                time.sleep(0.005)
+
+if __name__ == '__main__':
+        main()
</ins><span class="cx">Property changes on: branches/gsoc11-statistics/stats-server/bin/populate.py
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4>Added: svn:executable</h4></div>
</div>

</body>
</html>