Ignore svn directories while you grep

I have seen a lot of posts that show you how to ignore svn files when you grep. However, there seems to be more demand for a script that ignores svn directories. Here is one option:

tgrep(){
     grep -r $1 * | grep -v .svn | while read line;
     do
          echo $line
     done
}

Just add the function to one of your bash config files (~/.bashrc, ~/.bash_profile, ~/.bash_login), restart your terminal, and you are good to go. Here is a great article about how bash configs work. I put tgrep() in my .bashrc file, but also added the following to .bash_profile to force my .bashrc to load.

. ~/.bashrc
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , | Leave a comment

Talk politics with famous artists!

For the past few weeks, I have been building a widget to help artists/musicians talk politics to their fan base. The project is called “Be The Change” and is being run by myself and fellow members of the PAC, Music For Democracy. The Political Action Committee is a partisan group whose aim is to help artists speak out to their fans about politics.

Music For Democracy’s more immediate goal is to ensure Obama gets elected. People who sign up for the widget will get a call from an artist of their choice on election day reminding them to vote. They will also be entered in a competition to receive a live call from their favorite artist.

Our widget creates a political communication channel between artists and fans. This is not only great for getting Obama elected, but also a great way for fans to hear about artists’ opinions on political issues year-round. Engaging people in politics is very beneficial to our nation.

To get politically connected with your favorite artists, sign up on my widget below by clicking “Do It” and filling out the information. You can really make a difference and help Obama get elected by using our awesome SHARE feature. This feature helps you embed this widget on most social networks and easily email your friends to get them involved. Get involved and Be The Change!

Update (12/04/08): Now that the election is over, I am removing the actual widget from my blog and posting a screen shot. Feel free to shoot me any questions you have about the actual widget.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Music, Software | Tagged , , , , | 1 Comment

Effective customer conversion scheme from Fetch?

It has been a while since I blogged but sometime in the next month I will start again. Here is something in the mean time.

Over a week ago my 30 day trial of Fetch file transfer for Mac OS X ended. When I tried to open the program, I received a pop-up message asking me to purchase the program. But I also saw “Trial period extension available in 14…13…12…” Fetch was telling me that every time I try to use their program, I will have to wait for this counter to hit zero until I purchase the software.

It seems that the counter increments each day with a base delay of 5 seconds. My trial period ended on 9/14 and today is 9/23. (23-14) + base_delay = 14 seconds. Although I am not sure if this progression will continue to be linear.

So what is the big deal here? Why is this worth a blog post?

I think this customer conversion method is very effective for this type of product. With the extended trial period, they are giving users the chance to become comfortable with the FTP client; and it is very important to be comfortable with your file transfer software (unless you are going command line). When the delay gets too long, I will probably purchase the software because it is not worth my time to go on a search for a new program if I am comfortable with Fetch.

Furthermore, there have been times when I have needed to do an emergency upload to a server. If the Fetch delay was on the order of minutes, all it would take is one scare and I am sure I would make the purchase. It is only $25, so it is not something I have to really think about.

One thing I might do differently is actually bake the delays into the software. I would delay a user every time he opened up a new connection because as of now, I can just keep Fetch open for days without being delayed.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Random, marketing | Tagged , , , | Leave a comment

Any good syntax highlighting plugins out there?

UPDATE (05/14/2009)
I spent a few hours checking out some new syntax highlighter plugins. The best I found was Syntax Highlighter and Code Prettifier Plugin for WordPress. I tried it for a few days, but it loads extremely slow and the styling is not inline (therefore your RSS feeds will not look pretty). After being frustrated again with the options out there, I updated wp-syntax and removed my hacks. It looks a lot better now, but there is still an issue with understanding quotes in regular expressions as you can see here. For now I will just submit a bug and not worry about it. I just wanted to mention that I believe wp-syntax is the best option available.

Original Post:
When I first started this blog just a few months ago, my code snippets were ugly. After evaluating a few syntax highlighting plugins, I chose wp-syntax because it is pretty well documented for a Wordpress plugin and has over 10,000 downloads. It was also nice to see screen shots before installing.

The wp-syntax plugin is based on GeSHi, a syntax highlighter written in PHP. GeSHi is cool because it supports a wide variety of languages. However, I did not like the default styling provided by GeSHi for any languages and it has bad syntax support for Ruby.

Any suggestions for a good syntax highlighting plugin would be GREATLY APPRECIATED! For now, I went into the source code and fixed most of the issues with Ruby syntax support, as well as altered styles and added more keyword support for PHP, Ruby, and CSS. It’s an ugly fix but I wanted to get it done quickly.

If you like the way my code looks here, do the following:

  1. Install wp-syntax (follow link for installation directions)
  2. Download my versions of geshi.php, ruby.php, php.php, and wp-syntax.css from this link
  3. Replace “wp-content/plugins/wp-syntax/geshi/geshi.php” with my version of geshi.php
  4. Replace wp-content/plugins/wp-syntax/geshi/geshi/(php.php, ruby.php, and css.php) with my versions of php.php, ruby.php, and css.php
  5. Put my wp-syntax.css in wp-content/themes/your_theme_name/ (wp-syntax knows to look here to override their default stylesheet)
  6. Add this to your Wordpress theme’s style sheet (probably styles.css):
    1
    2
    3
    4
    5
    6
    
    pre
    {
        font-size: 11px;
        background-color: #090909;
        font-family:  Monaco, Verdana, Arial, Lucida Grande;
    }
  7. To format your code blocks, just wrap your code as described in the documentation (using the pre tag).

I would probably do a more comprehensive improvement if GeSHi was not currently being rewritten; or if I didn’t have faith that I will stumble across something better soon ;)

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , , | Leave a comment

Engineering remotely

A recent change in my company gave me the ability to work from home. When people think of working from home, the first benefits that pop into their mind are probably saving gas money and commuting time. Thinking a bit further, they may realize that using less gas is better for the environment and staying off the road means less traffic which means other people waste less gas.

After just a few weeks of developing software from home, I realized my situation greatly benefited my company. The most obvious benefits are that my company requires less office space and saves money on utility bills. Besides those, I work more efficiently from home and therefore produce more. I attribute my better productivity to the following:

(1) Greater Sense Of Responsibility
If I get distracted, I feel like it is on my own time. When I was in the office, if I did not produce a lot one day, it was a “bad day”. While working remotely, my boss knows I am actually working when he sees results. To me, this means I better not have “bad days”. If I have a “bad day”, I will probably be doing work at night.

(2) Work “In The Zone”
I would venture to guess that most people do not work at their peak productivity level 40-60 hours a week; yet many are forced to spend that amount of time behind a desk. While working remotely, any time I do not feel in the zone I can take a break and do something much more interesting than walking to the kitchen to fill up a cup of water. This means that while I am working, I am usually “in the zone”: working at very high productivity levels. When David Heinemeier Hansson was developing Ruby on Rails, he only had 10 hours/week to devote to the project. 10 hours/week can go a long way of you are working at a high productivity level.

(3) Healthiness = Happiness
Since I have started working from home, I have more time to get good sleep. Now I can exercise in a well-rested state every day, and after working out I can cook myself a well-balanced and generally healthier meal because I have access to a full kitchen. If you think eating healthy is mainly a physical health concern, watch Super Size Me, because you are incorrect. That movie reminded me (of course I already knew) how much eating can affect your mental health.

If you are thinking about negotiating a remote work agreement with your boss, I hope you find the above points useful. If you feel uncomfortable about the proposition, take Timothy Ferriss’s advice and ask for a trial period!

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Random | Tagged , , , , | 1 Comment

MySpace Band Statistics

Lately I’ve been doing a lot of research on social networks centered, at least partially, on music. In doing this, I began gathering some statistics on bands that use MySpace. I wanted to get a ballpark figure of how active bands are in the MySpace network. My friend Dan collaborated with me on writing some scripts to gather data. We wrote 3 scripts to get our stats.

Script #1 is a PHP script that looked at MySpace profiles and saved only band profiles to my hard drive. After I chose my range of MySpace profiles to analyze, it was faster to split up the range between a few scripts and run multiple threads. I also tried to make my requests through a proxy but found it to be too slow.

$start_time = time();
$total_music_profile_count = 0;
$friendID_start = 100000000;     //Start at 100 million
$friendID_end =   101000000;    //101 million
$PATH = ""; //insert path here
$ch = curl_init();           
 
/* You can use Tor to surf anonymously... I found this too slow */
//$tor_address = '127.0.0.1:8118';           
 
for($friendID=$friendID_start; $friendID<$friendID_end; ++$friendID){
     //Uncomment these to surf anonymously
     /*
     curl_setopt ($ch, CURLOPT_PROXY, $tor_address);
     curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
     curl_setopt ($ch, CURLOPT_HTTPPROXYTUNNEL, true);
     curl_setopt ($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
     */           
 
     curl_setopt ($ch, CURLOPT_URL,
"http://profile.myspace.com/index.cfm?fuseaction=user.viewprofile&friendID=$friendID");
     curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
     $result = curl_exec($ch);
     $pattern = '/MySpace music profile/i';           
 
     if(preg_match ($pattern, $result ,$matches)){
          ++$total_music_profile_count;
          $filename = "$PATH/mp_$friendID.html";
          $file_HANDLE = fopen($filename, "wb");
          $bytes_written = fwrite($file_HANDLE, $result);
          fclose($file_HANDLE);
     }
     print "Processed MySpace profile with friend ID: $friendID\n";
}           
 
$end_time = time();
$time_elapsed = $end_time - $start_time;

Script #2 is a ruby script that parsed the saved profiles and wrote the band id, band/artist name, profile view count, friends count, last login date, and member since date to a MySQL database. You will notice that the band_member_text regex is commented out. We wanted to know the number of band members in each band, but the content was too variable to evaluate. *I apologize about the syntax highlighting issue you see below. WP-Syntax (powered by Geshi) seems to have a problem understanding quotes in regular expressions.

#!/usr/bin/rubyrequire 'rubygems'           
 
require 'mysql'
require 'date'         
 
def main           
 
     db = Mysql.new(hostname, user, password, database) #insert db info here
     path = ""    #insert path here           
 
     entries = Dir.entries(path).reject { |e| e == "." || e == ".." }
     total_profile_views=0
     total_friends=0
     today = Date.today
     max_avg_friends_per_day = 0
     max_avg_profile_views_per_day = 0
     n = 0           
 
     entries.each do |e|
          text = IO.read(path + "/" + e)
          band_id_regex = /^mp_([0-9]+).html/i
          band_name_regex = /<title>\s*MySpace\.com\s*\-\s*([^\-]+)/
          profile_views_regex = /Profile Views: (\s*)([0-9]+)/i
          num_friends_regex = /has <span class="redbtext">(\d+)<\/span> friends/
          last_login_regex = /last login: ( )?(\s*)([0-1]?[0-9]\/[0-3]?[0-9]\/[1-2][0-9]
{3})/i
          member_since_regex = /Member Since<\/span><\/td><td id="ProfileMember Since"
width="175" bgcolor="#d5e8fb" style="WORD-WRAP: break-word"<((\d|\/){8,10})>\/td</           
 
          if e =~ band_id_regex
               band_id = $1.to_i
          else
               band_id = 0
          end           
 
          if text =~ band_name_regex
               band_name = $1
               band_name.gsub!(/'+/, " ")
          else
               band_name = ""
          end           
 
          if text =~ profile_views_regex
               profile_views = $2.to_i
               total_profile_views += profile_views
          else
               profile_views = 0
          end           
 
          if text =~ num_friends_regex
               num_friends = $1.to_i
               total_friends += num_friends
          else
               num_friends = 0
          end           
 
          if text =~ last_login_regex
               last_login = $3
               ll_date = Date.parse(last_login)
          else
               last_login = "1900-01-01"
    	       puts "last login parsing error for file: " + e
          end           
 
          member_since_found = true
          if text =~ member_since_regex
              member_since = $1
    	      ms_date = Date.parse(member_since)
         else
    	      member_since = "1900-01-01" #dummy date
    	      member_since_found = false
    	      ms_date = Date.parse(member_since)
              puts "member_since parsing error for file: " + e
         end           
 
         if(member_since_found)
              avg_profile_views_per_day = (profile_views)/(today - 3 - ms_date);
              avg_profile_views_per_day = avg_profile_views_per_day.to_f
              avg_friends_per_day = (num_friends)/(today - 3 - ms_date);
      	      avg_friends_per_day = avg_friends_per_day.to_f
         else
      	      avg_friends_per_day = 0.0
              avg_profile_views_per_day = 0.0
         end           
 
          if max_avg_friends_per_day < avg_friends_per_day
               max_avg_friends_per_day = avg_friends_per_day
          end           
 
          if max_avg_profile_views_per_day < avg_profile_views_per_day
               max_avg_profile_views_per_day = avg_profile_views_per_day
          end           
 
          mysql_query = "INSERT INTO music_profile_stats (band_id, band_name,
profile_views, num_friends, last_login) VALUES (#{band_id}, '#{band_name}',
#{profile_views}, #{num_friends}, '#{last_login}')"
          db.query(mysql_query)
     end
end
main

Results thus far:

  • Total MySpace profiles analyzed: 2,132,917
  • Total band profiles found: 87,710 (out of the 13.5 million on MySpace - count taken in March of 2008)
  • Average number of profile views per band: 3,403
  • Average number of friends per band = 201

For each band, I recorded the average amount of profiles views they received per day, as well as the average number of friends they acquired per day. Script #3 is a php script that compiled results about band activity by looking at this data.

require_once('./mysql_connect.php');         
 
bucketize("music_profile_stats", "avg_friends_per_day", 0.01, 4, 1500);
bucketize("music_profile_stats", "avg_prof_views_per_day", 0.03, 5, 12500);           
 
function bucketize($table, $column, $bucket_start, $bucket_multiplier, $max_val){           
 
     $query = "SELECT * FROM $table WHERE 1=1 ORDER BY $column";
     $result = mysql_query($query);
     $bucket = array();
     $num = 0;
     array_push($bucket, $num);
     $num = $bucket_start;           
 
     while($num < $max_val){
 	array_push($bucket, $num);
 	$num *= $bucket_multiplier;
     }           
 
     $bucket_step = 0;
     while($row = mysql_fetch_array($result)){
 	if(($bucket_step < (count($bucket) -1))&&($row[$column] >=
 $bucket[$bucket_step+1])) $bucket_step += 1;           
 
 	$temp = $bucket[$bucket_step];
 	$stats["$temp"] += 1;
     }
     print "**********************************************\n";           
 
     foreach($stats as $k=>$v){
 	//normalize data
 	$temp = $k*365;
 	print "$temp per year => $v\n";
     }
     print "**********************************************\n";
}

The results from this script are graphed below.
Average Friends Acquired Per Year

Average Profile Views Per Year

Conclusion:

  • 54% of the bands in my sample have, on average, less than 1 profile view per day and acquire no more than 4 friends per year (very inactive)
  • 8% of the bands in my sample have, on average, between 1 and 10 profile views per day and acquire between 4 and 15 friends per year (somewhat inactive)

I would consider the remaining 38% of my sample to be at least active members. Extrapolating these results, of the 13.5 million bands on MySpace, I estimate that approximately 5 million of these bands are active in the MySpace network.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Software | Tagged , , , , , , , , | 18 Comments

First Post!

This is my first post on TonyAmoyal.com!

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • MySpace
  • Slashdot
  • StumbleUpon
  • Technorati
  • TwitThis

If you enjoyed this post, make sure you subscribe to my RSS feed!

Posted in Random | 1 Comment