<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Seocracy.com &#187; Programming</title>
	<atom:link href="http://seocracy.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://seocracy.com</link>
	<description>A blog about technical SEO, Ruby, Web Apps, and more</description>
	<lastBuildDate>Wed, 28 Apr 2010 21:47:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Detecting anomalous spikes in a line graph via sub-sampling and standard deviation</title>
		<link>http://seocracy.com/2010/04/detecting-anomalous-spikes-in-a-line-graph-via-sub-sampling-and-standard-deviation/</link>
		<comments>http://seocracy.com/2010/04/detecting-anomalous-spikes-in-a-line-graph-via-sub-sampling-and-standard-deviation/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 21:47:09 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[ruby/rails]]></category>

		<guid isPermaLink="false">http://seocracy.com/?p=372</guid>
		<description><![CDATA[Woah, what a title&#8230;
What I want to talk about isn&#8217;t as complicated as it sounds. Basically, in collecting daily site specific metrics for the purposes of SEO, you sometimes get some bad data from your third-party sources.
These bad data points can skew your graphs and make it almost impossible to visually derive any useful information [...]]]></description>
			<content:encoded><![CDATA[<p>Woah, what a title&#8230;</p>
<p>What I want to talk about isn&#8217;t as complicated as it sounds. Basically, in collecting daily site specific metrics for the purposes of SEO, you sometimes get some bad data from your third-party sources.</p>
<p>These bad data points can skew your graphs and make it almost impossible to visually derive any useful information from them.</p>
<p>For example:</p>
<p style="text-align: center;"><a href="http://seocracy.com/wp-content/uploads/2010/04/indexed_before.png"><img class="size-full wp-image-373  aligncenter" style="margin-top: 0px; margin-bottom: 0px;" title="Indexed pages" src="http://seocracy.com/wp-content/uploads/2010/04/indexed_before.png" alt="Indexed Pages - before" width="491" height="169" /></a></p>
<p style="text-align: center;">
<p style="text-align: left; ">The graph above (click to expand) shows the number of pages for a 6 month date range. In early January the data spikes dramatically upwards. This is clearly an anomaly, as the day after, the data is back in its normal range. The trouble here is that this anomalous point skews the entire graph, making it impossible to derive any real insights from it. The above graph is rendered useless by that one piece of anomalous data.</p>
<p style="text-align: left; ">Here is the same graph WITHOUT that one bad piece of data (click to expand)</p>
<p style="text-align: center; "><a href="http://seocracy.com/wp-content/uploads/2010/04/indexed_after.png"><img class="size-full wp-image-380 aligncenter" title="indexed_after" src="http://seocracy.com/wp-content/uploads/2010/04/indexed_after.png" alt="indexed_after" width="529" height="167" /></a></p>
<p style="text-align: center; ">
<p style="text-align: left; ">It&#8217;s amazing how one bad data point can skew your entire graph, isn&#8217;t it? Now we have an image that is useful!</p>
<p style="text-align: left; ">
<p style="text-align: left; ">Here&#8217;s some (hackish &amp; sketchy) code to identify these statistical anomalies and replace them:</p>
<p style="text-align: left; ">
<p><script src="http://gist.github.com/382699.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://seocracy.com/2010/04/detecting-anomalous-spikes-in-a-line-graph-via-sub-sampling-and-standard-deviation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Quick and painless geo-location</title>
		<link>http://seocracy.com/2010/03/quick-and-painless-geo-location/</link>
		<comments>http://seocracy.com/2010/03/quick-and-painless-geo-location/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 19:30:13 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Random!]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Tips & Tricks]]></category>

		<guid isPermaLink="false">http://seocracy.com/?p=363</guid>
		<description><![CDATA[Hey all,
I wanted to post up a quick tip for you all, since I often hear people asking about how they can implement geo-location in their landing pages.
Alot of people recommend MaxMind or some other geoIP database, but really, thats a pain in the ass&#8230;there is a much easier way to do it.
On your landing [...]]]></description>
			<content:encoded><![CDATA[<p>Hey all,<br />
I wanted to post up a quick tip for you all, since I often hear people asking about how they can implement geo-location in their landing pages.</p>
<p>Alot of people recommend MaxMind or some other geoIP database, but really, thats a pain in the ass&#8230;there is a much easier way to do it.</p>
<p>On your landing page, just include the following in header.</p>
<p style="padding-left: 30px;">&lt;script type=&#8221;text/javascript&#8221; src=&#8221;http://www.google.com/jsapi&#8221;&gt;&lt;/script&gt;</p>
<p>This script will calculate your visitors location for you&#8230;.and all you have to do is pull the ClientLocation variable!<br />
For example, if I wanted to display a popup with the users city:</p>
<p style="padding-left: 30px;">alert(google.loader.ClientLocation['address']['city'])</p>
<p>Seriously, its THAT SIMPLE.</p>
<p>Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://seocracy.com/2010/03/quick-and-painless-geo-location/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>building a personal web dashboard</title>
		<link>http://seocracy.com/2010/02/building-a-personal-web-dashboard/</link>
		<comments>http://seocracy.com/2010/02/building-a-personal-web-dashboard/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 06:06:25 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Random!]]></category>

		<guid isPermaLink="false">http://seocracy.com/?p=358</guid>
		<description><![CDATA[Hey all,
I&#8217;ve recently undertaken a personal project that I hope will make my day-to-day activities on a the web a bit more efficient. I&#8217;ve always dreamed of having the perfect home page for myself; one that had all my most crucial data at a glance. Unfortunately, all the services I&#8217;ve tried have fallen short (*cough* [...]]]></description>
			<content:encoded><![CDATA[<p>Hey all,</p>
<p>I&#8217;ve recently undertaken a personal project that I hope will make my day-to-day activities on a the web a bit more efficient. I&#8217;ve always dreamed of having the perfect home page for myself; one that had all my most crucial data at a glance. Unfortunately, all the services I&#8217;ve tried have fallen short (*cough* netvibes *cough*). So, I&#8217;ve decided that enough is enough; I am going to build my own dashboard.</p>
<p>The dashboard will take quite a few cues from the interface of <a title="The Stat Codex" href="http://codex.getst.at" target="_blank">The STAT Codex</a>, in so far that it will be window/panel based and entirely modular, but it will be customized to my needs.</p>
<p>At the very least, I want the dashboard to pull the following data:</p>
<ul>
<li>email module (gmail and others, just reading, sending can open up  a new window in the email client.)</li>
<li>twitter module (multiple accounts&#8230;send and receive tweets)</li>
<li>a twitter favorites module that allows my to follow the favorited tweets of various twitter accounts</li>
<li>instapaper module for items to be read</li>
<li>remember the milk  module for to-do items</li>
<li>major site statistics module (only for my most active web properties)</li>
<li>new incoming backlinks module</li>
<li>paypal module for showing paypal balance and recent transactions</li>
<li>google calendar module</li>
<li>log monitor module (would tail the server logs for most active web properties)</li>
</ul>
<p>What else would you add to the list? What data would you love to have at a click on your home page?</p>
]]></content:encoded>
			<wfw:commentRss>http://seocracy.com/2010/02/building-a-personal-web-dashboard/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Amazon S3 bucket limit</title>
		<link>http://seocracy.com/2009/08/amazon-s3-bucket-limit/</link>
		<comments>http://seocracy.com/2009/08/amazon-s3-bucket-limit/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 09:33:53 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Theory]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ruby/rails]]></category>

		<guid isPermaLink="false">http://seocracy.com/?p=321</guid>
		<description><![CDATA[
So, today I learned that Amazon S3 limits the amount of buckets you are allowed to have at any one time. This was a HUGE pain in the ass for me, as I just rewrote my S3 caching libraries to separate my caching into daily buckets.

The idea I had was that I would keep 30 [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-320 alignnone" title="I CALL SHENANIGANS ON AMAZON S3!!!" src="http://seocracy.com/wp-content/uploads/2009/08/theybestealinmybucket.jpg" alt="theybestealinmybucket" width="640" height="340" /></p>
<p>So, today I learned that Amazon S3 limits the amount of buckets you are allowed to have at any one time. This was a HUGE pain in the ass for me, as I just rewrote my S3 caching libraries to separate my caching into daily buckets.</p>
<p><img class="alignnone size-full wp-image-328" title="headesk" src="http://seocracy.com/wp-content/uploads/2009/08/headesk1.png" alt="headesk" width="614" height="314" /></p>
<p>The idea I had was that I would keep 30 days worth of buckets before automatically shuffling all those buckets into long term archival at the end of each month.</p>
<p>You see, Amazon S3 doesn&#8217;t allow for folders within buckets (not technically, I&#8217;ll get to that later), and I think it&#8217;s bloody ridiculous for me to store the ~15 millions xml cache files I need daily access to in just one massive bucket. So, I thought my plan to create daily buckets was pretty damn good. Apparently Amazon disagrees, as hey have set a limit on the number of buckets I can have associated with my account (FYI, I have ~90 buckets right now and that&#8217;s where the limit is).</p>
<p>So, I&#8217;ve been looking into my options, and I have decided that I&#8217;m going to have to go back to my original set up of storing all 15 million (and growing) xml files in one bucket. As some of you may know, S3 GUIs like S3Fox are able to show sub-folders within buckets, so I figure I will go this route. My first step was to take a crack at the Ruby S3 library from Amazon (<strong>not</strong> the AWS gem, which is crap for multi threaded environments) to see how I can create folders within buckets. Turns out, you can&#8217;t. At least, not out of the box. You see, AmazonS3 doesn&#8217;t actually SUPPORT sub-folders within buckets.</p>
<p>Stupid, right? I know.</p>
<p>So, how does S3Fox do it? It turns out they create virtualized folders by creating a special object that acts as a folder, then you access your stored objects by appending that folder object name to the actual file key. For a directory named &#8220;/foo&#8221;, you would create an object with the key &#8220;foo_$folder$&#8221;. Then, to get a directory listing of all files stored under the foo path, you just query S3 for objects with keys that start with &#8220;/foo&#8221;, and you ignore any objects that end with &#8220;_$folder$&#8221;.</p>
<p>I&#8217;m about to waste my day setting this up, and I&#8217;m none to happy about it. It seems like a hackish and shitty work around for an obvious service flaw. I&#8217;m sure there is some technically-reasonable answer for why Amazon has set an arbitrary limit for buckets and also why they don&#8217;t allow you to create folders, but I don&#8217;t know what it is. Anyone have any answers?</p>
<p>Hat-Tip the <a href="http://deadprogrammersociety.blogspot.com/2008/01/making-s3-folders-in-ruby.html" target="_blank">Dead Programmer Society</a> for the code to create virtualized folders in S3.</p>
]]></content:encoded>
			<wfw:commentRss>http://seocracy.com/2009/08/amazon-s3-bucket-limit/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Updated Google Analytics Keyword Extractor</title>
		<link>http://seocracy.com/2009/04/updated-google-analytics-keyword-extractor/</link>
		<comments>http://seocracy.com/2009/04/updated-google-analytics-keyword-extractor/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 13:34:27 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Google Hacking]]></category>
		<category><![CDATA[Link-Love]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Tools & Applications]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[gattica gem]]></category>
		<category><![CDATA[keywords]]></category>
		<category><![CDATA[organic]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[statistics]]></category>

		<guid isPermaLink="false">http://seocracy.com/?p=298</guid>
		<description><![CDATA[OK,  I&#8217;ll admit, my last post was downright shameful&#8230;
The code was poorly presented, and poorly formatted. It wasn&#8217;t at ALL my normal caliber of work, so I went ahead and rewrote the concept into a tighter little wrapper.
I am using the Gattica gem to interact with the Google Analytics API.
This little script provides a wrapper [...]]]></description>
			<content:encoded><![CDATA[<p>OK,  I&#8217;ll admit, my last post was downright shameful&#8230;</p>
<p>The code was poorly presented, and poorly formatted. It wasn&#8217;t at ALL my normal caliber of work, so I went ahead and rewrote the concept into a tighter little wrapper.</p>
<p>I am using the <a href="http://github.com/cannikin/gattica/tree/master" target="_blank">Gattica gem</a> to interact with the Google Analytics API.</p>
<p>This little script provides a wrapper around the gem that easily allows you to extract your sites organic keywords and sort them based on the number of unique entrances to your site via each keyword.</p>
<p><script src="http://gist.github.com/104452.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://seocracy.com/2009/04/updated-google-analytics-keyword-extractor/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using the Google Analytics API with Ruby, Open-Uri &amp; Hpricot</title>
		<link>http://seocracy.com/2009/04/using-the-google-analytics-api-with-ruby-open-uri-hpricot/</link>
		<comments>http://seocracy.com/2009/04/using-the-google-analytics-api-with-ruby-open-uri-hpricot/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 19:51:38 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Google Hacking]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[hpricot]]></category>
		<category><![CDATA[keywords]]></category>
		<category><![CDATA[open-uri]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scraping]]></category>

		<guid isPermaLink="false">http://seocracy.com/?p=269</guid>
		<description><![CDATA[You may or may not have heard that Google has finally opened up their Analytics API to the public. You can read Googles official statement here.
I thought I&#8217;d show you all a quick crash introduction on how you can access the API using Ruby.
The following code uses Open-Uri to access the API and Hpricot to [...]]]></description>
			<content:encoded><![CDATA[<p>You may or may not have heard that Google has finally opened up their Analytics API to the public. You can read Googles official statement <a href="http://analytics.blogspot.com/2009/04/attention-developers-google-analytics.html">here</a>.</p>
<p>I thought I&#8217;d show you all a quick crash introduction on how you can access the API using Ruby.</p>
<p>The following code uses Open-Uri to access the API and Hpricot to parse the response. In this example, we&#8217;re going to authenticate with the API, and then we&#8217;re going to use it to extract all the keywords (organic and paid) which have brought visitors to our site within the past year (limited to 100 keywords max)</p>
<p>NB: sorry for the shitty formatting. I tried like hell to get this code to display well, but I gave up. Just copy and paste..you&#8217;ll be able to sort it out.</p>
<p>require &#8216;rubygems&#8217;<br />
require &#8216;open-uri&#8217;<br />
require &#8216;hpricot&#8217;</p>
<p>USER_EMAIL=&#8221;XXXXXX&#8221; #Insert your Google Account email address here<br />
USER_PASS=&#8221;XXXXXX&#8221; #Insert your password here<br />
PROFILE_ID=&#8221;XXXXXX&#8221; #Insert your profile ID here (Find this in your analytics profile under profile settings)<br />
results = {}<br />
keywords = []<br />
auth_url = &#8220;https://www.google.com/accounts/ClientLogin?Email=#{USER_EMAIL}&amp;amp;Passwd=#{USER_PASS}&amp;amp;accountType=GOOGLE&amp;amp;source=open-uri-limbo-v01&amp;amp;service=analytics&#8221;</p>
<p>auth_key = (open(auth_url).read).split(&#8221;\n&#8221;).last</p>
<p>#now query for keywords, you can change the date values as you see fit, as well as the max-results value<br />
response = Hpricot.XML(open(&#8221;https://www.google.com/analytics/feeds/data?start-date=2008-10-01&amp;amp;end-date=2009-04-21&amp;amp;dimensions=ga:keyword&amp;amp;max-results=100&amp;amp;ids=ga:#{PROFILE_ID}&amp;amp;prettyprint=true&#8221;,<br />
&#8220;Authorization&#8221; =&amp;gt; &#8220;GoogleLogin #{auth_key}&#8221;).read)<br />
## storing some of the extra information in a &#8220;results&#8221; hash in case we need it later<br />
results[:total_results] = (response/&#8217;openSearch:totalResults&#8217;).inner_text<br />
results[:start_index] = (response/&#8217;openSearch:startIndex&#8217;).inner_text<br />
results[:items_per_page] = (response/&#8217;openSearch:itemsPerPage&#8217;).inner_text<br />
results[:start_date] = (response/&#8217;dxp:startDate&#8217;).inner_text<br />
results[:end_date] = (response/&#8217;dxp:endDate&#8217;).inner_text<br />
results[:aggregates] = (response/&#8217;dxp:aggregates&#8217;).inner_text<br />
results[:data_source] = (response/&#8217;dxp:dataSource&#8217;)<br />
results[:entries] = (response/&#8217;entry&#8217;)<br />
## the entries contain each individual keyword</p>
<p>## for my purposes, I&#8217;m not interested in visitors coming from search operators like &#8220;site:&#8221;<br />
## so we&#8217;re scrubbing those out.<br />
for entry in results[:entries]<br />
keyword = (entry/&#8217;dxp:dimension&#8217;).first[:value]<br />
keywords &amp;lt;&amp;lt; keyword unless keyword.include? &#8220;site:&#8221; or keyword.match(/\(.*\)/)<br />
end</p>
<p>## Now print out our keywords<br />
keywords.each {|kw|<br />
puts kw<br />
}</p>
<p><strong>UPDATE</strong> just seconds ago, a new gem was released called <a href="http://github.com/cannikin/gattica/tree/master">Gattica</a> which you can use to access the Google Analytics API. How&#8217;s that for up to the minute blogging? Thanks Twitter!</p>
]]></content:encoded>
			<wfw:commentRss>http://seocracy.com/2009/04/using-the-google-analytics-api-with-ruby-open-uri-hpricot/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>So, you want to build a Web App&#8230;</title>
		<link>http://seocracy.com/2009/04/so-you-want-to-build-a-web-app/</link>
		<comments>http://seocracy.com/2009/04/so-you-want-to-build-a-web-app/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 02:57:16 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Announcements & News]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Random!]]></category>
		<category><![CDATA[SEO]]></category>

		<guid isPermaLink="false">http://seocracy.com/?p=259</guid>
		<description><![CDATA[Are you unemployed? Were you fired from your job as an accountant at a Fortune 500 company? Looking for a good way to make money, but don&#8217;t want to get back in the rat race? If you answered yes to any of those questions, you should consider building a WEB APP!
Web Applications are EASY to [...]]]></description>
			<content:encoded><![CDATA[<p>Are you unemployed? Were you fired from your job as an accountant at a Fortune 500 company? Looking for a good way to make money, but don&#8217;t want to get back in the rat race? If you answered yes to any of those questions, you should consider building a WEB APP!</p>
<p>Web Applications are EASY to build! Anyone can do it!</p>
<p>First, you need an idea. This can be the hardest part. Basically, you just want to think about something people do every day that you can do better.<br />
Here are some ideas to get you started:</p>
<ul>
<li>web-based makeup mirror (requires a webcam)</li>
<li>sea-monkeys&#8230;give them facebook pages, make them twitter&#8230;put them up for adoption.</li>
<li>a calculator, with lots and lots of ajax&#8230;.and really big buttons.</li>
</ul>
<p>These are just a few ideas, but you get the picture. Take some time coming up with your idea, and be patient! You have to refine the idea before you waste time building something no one will ever use. Take at least 30 minutes to decide.</p>
<p>Once you&#8217;ve decided on what your highly profitable Web App is going to do, you have to build it! This is the easiest part. You don&#8217;t even have to know how to write code. Really! There are new programming languages that don&#8217;t even require complicated things like squiggly brakets {} or dollar signs $.  Thanks to the magic of <a href="http://phails.com/" target="_blank">Ruby on Rails</a>, if you can write a grocery list, you can write a Web App. Seriously!</p>
<p>Do you know how to view the source code for an HTML page? Great! That means you know how to design a website! Now, I know, designing things is complicated, but don&#8217;t worry about it! NO ONE DESIGNS THEIR OWN WEBSITES ANYMORE! Seriously! All you need is a Template. There are even <a href="http://developer.yahoo.com/yui/grids/builder/" target="_blank">WEB APPS to build Templates for WEB APPS</a>! Totally meta! <a href="http://designinfluences.com/fluid960gs/" target="_blank">Gnarly</a>!</p>
<p>So, you&#8217;ve got your ruby, you&#8217;ve got your template&#8230;.you&#8217;re almost done! Now, you need a LOGO! Most people say you should hire a designer to get a Logo done professionally, but you don&#8217;t want to spend any money out of pocket, do you? I mean, what are you, Mother Teresa?!? Hell no! I recommend you just <a href="http://logopond.com/" target="_blank">rip one off</a> for now, and once you make some revenue, you can buy some cheap stock Logo from istockphoto.com.</p>
<p>Remember, in order to maximize Web App profits, you need to always be vigilant so that no corners escape uncut. When building your Web App, you should be sure to try and burden yourself with as many of the details as possible. You need to be prepared to be the programmer, the tester, the designer, the marketer and the support staff, ALL IN ONE! But don&#8217;t get stressed out about handling a big workload, because it&#8217;s not like you have to do ANY of those things at 100% efficiency, as long as you&#8217;re the only one doing them. The people who will use your Web App are just nameless, faceless drones anyways; it&#8217;s not like you owe them timely responses to their emails. Always remember that your users are eternally indentured to you in exchange for access to your Web App.</p>
<p>OK, so you&#8217;ve got your Template, you&#8217;ve got your Logo&#8230;&#8230;..it&#8217;s time to do some programming! First, you want to download as many plugins and gems as possible. The more the better, because the more gems you have, the less code you have to write. Remember when your teacher crushed your dreams and told you that there are no unique ideas left, that everything has already been done? Well, when it comes to Gems, its true! There is a Gem or Plugin for every possible thing you could ever conceive of wanting to do &#8211; now, or in the future. So basically, just get as many Gems and Plugins as possible, and just start plugging them in wherever you need content.</p>
<p>Look at you! You go-getter! You&#8217;ve just programmed your first Web App! It&#8217;s going to be the <span style="text-decoration: underline;">BEST CALCULATOR EVER</span>! Don&#8217;t worry about scaling it up. If your users ever start calculating pi, you can just use the Cloud, man! The Cloud is where it&#8217;s at! In case you haven&#8217;t heard of the Cloud yet, I&#8217;ll tell you a bit about it. The Cloud is this place in the Amazon Basin, a humid, godless, no-mans-land inhabited by under paid savages (Amazonians). Anyways, the Cloud is like this giant parking garage, but instead of cars, they&#8217;ve parked hundreds and hundreds of servers which they&#8217;ve woven together with millions of long, tangled fibreoptic wires (hence the name &#8216;the Cloud&#8217;). Anyways, you just email your program to the Amazonians, and they&#8217;ll put your program on a piece of the cloud, giving you the ability to add as many mongrel instances to your server cluster as your heart desires. Scaling?!?! What Scaling?!?!</p>
<p>Now that you&#8217;ve got your Template, and your Logo and your Program on the Cloud, you&#8217;re ready to start marketing!!! This part is really really easy. You just need to stir the pot a little bit, &amp; kick up a little media interest. For example, let&#8217;s say one of your Virtual Sea-Monkeys ends up having to see a Substance Abuse Counselor&#8230;..that&#8217;s marketing gold! Big-mouthed bloggers love stories like that! The more sensational the better, especially because people will put your media story on sites like Digg, or StumbleUpon. These sites will send you visitors who will really take the time to read your story, visit your site, interact with your product, and develop long-lasting, meaningful connections with your brand. You just have to keep your eyes open for marketing opportunities!</p>
<p>By now, thanks to your Web App, you&#8217;re probably well on your way to dealing with your delinquent mortgage payments and are no longer dodging your relatives. Congratulations! <a href="http://www.someecards.com/upload/workplace/im_glad_you_can_vent_your_white_collar_frustration.html" target="_blank">Feel free to send your former boss a cruel and insensitive e-card from someecards.com</a>, because You&#8217;ve Arrived!!! You&#8217;re a big web success story! Expect to hear from Inc. Magazine within minutes.</p>
<p>But! But! But! Don&#8217;t stop there! This is just the beginning! Now that you&#8217;ve seen how easy it is to create one Web App, create more! Don&#8217;t worry about the Web Apps that you&#8217;re already managing, it&#8217;s OK to let them slide. If you want, you can start an affiliate program and get affiliates to keep marketing your old, stale Web Apps while you&#8217;re busy building new ones! You&#8217;ll want to get an Email Autoresonder so that you&#8217;re not burdened by time consuming support requests to have subscriptions canceled, you&#8217;ve got better things to do! You&#8217;re an entrepreneur!</p>
]]></content:encoded>
			<wfw:commentRss>http://seocracy.com/2009/04/so-you-want-to-build-a-web-app/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Will Google stop SERP scrapers by going Ajax?</title>
		<link>http://seocracy.com/2009/01/will-google-stop-serp-scrapers-by-going-ajax/</link>
		<comments>http://seocracy.com/2009/01/will-google-stop-serp-scrapers-by-going-ajax/#comments</comments>
		<pubDate>Sat, 31 Jan 2009 17:29:26 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Theory]]></category>

		<guid isPermaLink="false">http://seocracy.com/?p=243</guid>
		<description><![CDATA[Some of you might have noticed the buzz going around the net today about Google&#8217;s SERPs going ajax. There is a great post about it here:
Google Web Search Ajax
I&#8217;ve heard more than a few people asking if this will stop automation software from crawling Googles SERPs to retrieve rankings or Adwords data. In short, the [...]]]></description>
			<content:encoded><![CDATA[<p>Some of you might have noticed the buzz going around the net today about Google&#8217;s SERPs going ajax. There is a great post about it here:</p>
<p><a href="http://smackdown.blogsblogsblogs.com/2009/01/30/google-web-search-goes-completely-ajax/" target="_blank">Google Web Search Ajax</a></p>
<p>I&#8217;ve heard more than a few people asking if this will stop automation software from crawling Googles SERPs to retrieve rankings or Adwords data. In short, the answer is no.</p>
<p>I doubt this development would be solely intended to stop people from using automated rank checkers or content scrapers, but Google has to know that whatever they change, people will simply adapt and evolve their software to keep pace. My personal opinion is that a move to ajax SERPs would provide google with a tighter control of how they serve data, as well as providing them with a whole slew of new metrics they could leverage. On the flip-side, this move could hamper the accessibility of Googles service from outdated/underpowered computers and browsers.</p>
<p>Regardless, the possibility of Google going ajax does indeed raise some questions in so far as how people should proceed with developing automation software. Not only is ajax delivered content more difficult to automate, but ajax also could be used to track mouse movement. This would be one of the metrics that ajax would make available to Google, and also it could be a possible means by which Google could begin to distinguish bots from humans. (although, on the Google-scale, that would be an incredibly large amount of data to process.)  While AJAX content is not as trivial to scrape as traditional content, it is still quite possible. I think that as Google evolves to develop ways to clean up their SERPs, programmers and marketers will evolve as well. I believe that software will inevitably evolve to mimic human browsing behavior. This includes filling out form data, mouse movement, sending Google Toolbar data, using back buttons, clicking links, storing cookes, etc. And don&#8217;t forget, all that will have to be done at human speeds, not computer speeds. The requirement to mimic human behavior also means that it will become more and more difficult to multi-thread and do simultaneous requests from one IP range. Rather than managing massive proxy farms, in the future, it will be more cost-effective and productive to off-load automation requests to client computers which, when required, send data back to a master server for processing (no, I&#8217;m not talking about malware here&#8230;.more like browser plugins).</p>
<p>There are already a slew of different libraries which mimic browsing behavior and also handle ajax. Off the cuff, <a href="http://www.rubyrailways.com/ajax-scraping-with-scrubyt-linkedin-google-analytics-yahoo-suggestions/" target="_blank">ScrubyT </a>handles ajax quite well. <a href="http://wtr.rubyforge.org/" target="_blank">Watir</a> can actually open an instance of IE, FF, Safari, or even Chrome, and thus fully mimic a browser. Marketers and programmers can use these libraries, and other libraries to both mimic human browsing behavior and make ajax calls to automate SERPs. In the future, you can expect these kinds of libraries to evolve and become more advanced and customized towards mimicking human behavior. Even still, if ajax calls are not encoded, you can simply extract the appropriate call out of the page and make it yourself. An example of this can be seen <a href="http://stackoverflow.com/questions/260540/how-do-you-screen-scrape-ajax-pages" target="_blank">here</a>.</p>
<p>At the end of the day, a move on Google&#8217;s part to ajax SERPs may throw a wrench into some peoples software, but it will certainly not herald an end to automation tools like Aaron Wall&#8217;s excellent <a href="http://tools.seobook.com/seo-toolbar/" target="_blank">SEOToolbar</a>, or others.</p>
]]></content:encoded>
			<wfw:commentRss>http://seocracy.com/2009/01/will-google-stop-serp-scrapers-by-going-ajax/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Dynamic Alt-Tags</title>
		<link>http://seocracy.com/2009/01/dynamic-alt-tags/</link>
		<comments>http://seocracy.com/2009/01/dynamic-alt-tags/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 21:58:23 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Tips & Tricks]]></category>

		<guid isPermaLink="false">http://seocracy.com/?p=222</guid>
		<description><![CDATA[Note: This post builds off of ideas presented in past blog posts, like String Permutation.
&#8212;&#8212;&#8212;

I was recently doing a little friendly consulting for a friend of mine who runs a membership based adult-site.
Basically he was converting well but not getting alot of traffic, so we took some time to look over his sites layout and [...]]]></description>
			<content:encoded><![CDATA[<address>Note: This post builds off of ideas presented in past blog posts, like <a title="string permutations" href="http://seocracy.com/2008/06/fun-with-string-permutations/" target="_blank">String Permutation.</a></address>
<address>&#8212;&#8212;&#8212;<br />
</address>
<p>I was recently doing a little friendly consulting for a friend of mine who runs a membership based adult-site.</p>
<p>Basically he was converting well but not getting alot of traffic, so we took some time to look over his sites layout and went over some basic SEO best-practices.</p>
<p>One of the things that he really needed to improve on was the layouts of his images. I mean, with a site like this, images are way more prevalent than content&#8230;his design is hugely image intensive, and there are literally hundreds of individual preview galleries that could potentially act as great landing pages for each individual sub-niche&#8230;</p>
<p>I was advising him that he should be working on keyword rich, unique captions and alt-tags for his images, and his complaint was that there are so many images that it would be a huge pain in the ass to go through and create captions/ALTs for each one. So, we decided that the best thing to do in this case would be to create a simple function that dynamically builds unique captions and ALT text for him.</p>
<p>Basically, what we did was build 10 different sets of four-to-five <a title="definition of array" href="http://en.wikipedia.org/wiki/Array" target="_blank">arrays</a> containing various keywords that we could randomly choose from in building a complete string. We then set the function to dynamically choose one of the array sets, so that each caption/ALT didn&#8217;t have the exact same format.</p>
<p>In building each array set, we started with a sentence structure he wanted to use, and then expanded each word out into it&#8217;s own array.</p>
<p>Example: (I normally keep this blog PG13, so please excuse the dirty words, but I&#8217;m using an example relevant to the adult industry)</p>
<p><strong>ARRAY1. Sentence structure:<br />
&#8220;Download &lt;model_name&gt;&#8217;s private sex video&#8221;</strong></p>
<p>array1a = [download,check out,view,see,get,look at]<br />
array2b = [private,personal,intimate]<br />
array3c = [sex,solo,masturbation,jerk-off,porn]<br />
array4d = [video,film,clip,download,stream,flick,vid,picture]</p>
<p><strong>ARRAY2. Sentence structure:<br />
&#8220;&lt;model_name&gt; has tons of hot videos&#8221;</strong></p>
<p>array2a = [has,uploads,provides,creates,films,makes]<br />
array2b = [tons of, lots of, many of, hundreds of, a lot of, loads of]<br />
array2c = [hot, sexy, steamy, erotic, raunchy, amazing, mind-blowing]<br />
array4d = [videos,films,clips,downloads,streams,flicks,vids,pictures]</p>
<p>ARRAY3&#8230;etc..ARRAY4&#8230;.etc&#8230;..all the way to TEN different sets of arrays.</p>
<p>The above is just an example&#8230;.in a real production usage, I would recommend no less than 10-15 words PER array.</p>
<p>Then, for each caption and each alt, the webpage calls the function which randomly chooses one of the 10 array sets and uses it to build a dynamic string.</p>
<p>Once you&#8217;ve randomly selected one of the 10 array sets to use, you&#8217;d build the dynamic string like this:</p>
<pre><strong><span style="color: #000000;">dynamic_string = array1a[rand(array1a.length)]." ".model_name."'s ".array1b[rand(array1b.length)]." ".array1c[rand(array1c.length)]." ".array1d[rand(array1d.length)];</span></strong></pre>
<p>So, this function might return the following: &#8220;download Jenny&#8217;s intimate sex video&#8221; OR &#8220;checkout Suzie&#8217;s private porn clip&#8221; OR etc, etc etc</p>
<p>Using this simple and well-documented technique, the site owner was able to create keyword rich, dynamic captions/ALTs for every single picture in his hundreds of preview galleries. He was able to keep his image-rich site design and still put lots of great content into it without making it look like keyword spam, and all without going through the back-breaking effort of manually writing content.</p>
<p>Two closing notes fore you all to think about:</p>
<p>1)You can use your favorite keyword/synonym tools and even search query logs to build massive lists of your relevant keywords. Then you just need to take some time to scan through them and group and sort them into relevant sets.</p>
<p>2)This technique is very useful for anchor text as well <img src='http://seocracy.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://seocracy.com/2009/01/dynamic-alt-tags/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Effective and Efficient ways to Mass Install Wordpress</title>
		<link>http://seocracy.com/2008/08/effective-and-efficient-ways-to-mass-install-wordpress/</link>
		<comments>http://seocracy.com/2008/08/effective-and-efficient-ways-to-mass-install-wordpress/#comments</comments>
		<pubDate>Tue, 26 Aug 2008 00:00:00 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Link-Love]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Theory]]></category>
		<category><![CDATA[Tools & Applications]]></category>

		<guid isPermaLink="false">http://127.0.0.1/seocracy/?p=80</guid>
		<description><![CDATA[blah blah...slug line....blah blah.....catch phrase...]]></description>
			<content:encoded><![CDATA[<p>Blah&#8230;commencement of pleasantries&#8230;..blah blah&#8230;.witty charming banter&#8230;.blaah&#8230;.introduction to mass install wordpress..blaaah&#8230;&#8230;more witty commentary&#8230;.blah blah&#8230;..install this&#8230;ftp that&#8230;blah&#8230;incredibly complicated&#8230;.blah..self aggrandizement&#8230;.blah&#8230;&#8230;<br />
</span></p>
<p id="s2-23">Situation:<br />
Shared Host<br />
CPanel<br />
No SSH Access</span></p>
<p> Solution 1: FTP Transfer Folder  to server, Mechanize/CURL Install<br />
Process:<br />
</span></p>
<p id="s2-211">1) Collect variables: database, username, cpanel login, cpanel password, keywords<br />
</span></p>
<p id="s2-213">2) If necessary, create databases and users on CPanel host (using CURL, or Mechanize)</span></p>
<blockquote><p>
<em>Here is a function I use to create CPanel DBs:<br />
</em><span style="background-color: #ffff00">def self.create_db(base_url, cpanel_loc, cpanel_user, cpanel_pass, db, dbuser, dbpass)</span><br />
<span style="background-color: #ffff00"> agent = WWW::Mechanize.new </span><br />
<span style="background-color: #ffff00"> agent.user_agent_alias = $USER_AGENTS[rand($USER_AGENTS.length)]</span><br />
<span style="background-color: #ffff00"> agent.basic_auth(cpanel_user,cpanel_pass)</span><br />
<span style="background-color: #ffff00"> url = &#8220;http://#{base_url}#{cpanel_loc}/frontend/x/sql/&#8221;</span><br />
<span style="background-color: #ffff00"> agent.get(url)</span><br />
<span style="background-color: #ffff00"> agent.get(&#8221;#{url}adddb.html?db=#{db}&#8221;)</span><br />
<span style="background-color: #ffff00"> agent.get(&#8221;#{url}adduser.html?user=#{dbuser}&amp;pass=#{dbpass}&#8221;)</span><br />
<span style="background-color: #ffff00"> agent.get(&#8221;#{url}addusertodb.html?user=#{cpanel_user}_#{dbuser}&amp;db=#{cpanel_user}_#{db}&amp;ALL=ALL&#8221;)</span><br />
<span style="background-color: #ffff00"> end</span></p></blockquote>
<p id="cal50">3) For each keyword in the keyword list, create a different blog<br />
</span></p>
<p id="hquz0"> 3a) Write local wordpress-config file with user entered data</span></p>
<p id="hquz1"> 3b) Pull a random theme from local theme library</span></p>
<p id="kkiw"> 3c) Pull required plugins from local plugin library</span></p>
<p id="l8m2"> 3d) Create local folder for blog, copy base wordpress install files, plus files from 3a,3b,3c</span></p>
<p id="l8m20">4) Begin FTP Transfer of files from master server to destination on install server (Thread this process to speed up)</span></p>
<p id="l8m21">5) Mechanize/CURL to appropriate Install URL, then Mechanize/CURL through management panel to activate theme selected in 3b and plugins selected in 3c</span></p>
<p id="vn4b">*Repeat step 3 for each keyword supplied to the function<br />
</span></p>
<p id="s2-215">
</span></p>
<p>NOTES: This method, when optimized and threaded, can install about one blog / 90 seconds. The major speed limiting factor is the FTP transferring. A base wordpress install already has a TON of files, and depending on how many plugins and how many themes you are including, the number of files really slows down the FTP transfer. I recommend creating a personal WP base install with ALL of the junk and cruft removed (ie: the management panel niceities like password strength checking etc..). Removing all non-essential files from a wordpress base install can really speed up FTP transfers. This is a good practice anyways, since we want to be as resource efficient as possible, since we&#8217;re going to cram this shared server with nothing but blogs.</span></p>
<p>Solution 2: FTP package file to server, extract through file manager, Mechanize/CURL Install<br />
Process:<br />
</span></p>
<p id="c7-j0">1) Collect variables: database, username, cpanel login, cpanel password, keywords<br />
</span></p>
<p id="c7-j2">2) If necessary, create databases and users on CPanel host (using CURL, or Mechanize)<br />
</span></p>
<p id="c7-j4">3) For each keyword in the keyword list, create a different blog</span></p>
<p id="dbe5"> 3a) Write local wordpress-config file with user entered data</span></p>
<p id="c_bl"> 3b) Pull a random theme from local theme library</span></p>
<p id="c_bl0"> 3c) Pull required plugins from local plugin library</span></p>
<p id="c_bl1"> 3d) Create local folder for blog, copy base wordpress install files, plus files from 3a,3b,3c</span></p>
<p id="qp2u"> 3e) Package folder<br />
</span></p>
<p id="c_bl2">4) FTP Transfer Package from master server to destination on install server</span></p>
<p id="qp2u1">5) Mechanize or CURL CPanel Filemanager to unzip file on server</span></p>
<p id="fm6_">6) Mechanize/CURL to appropriate Install URL, then Mechanize/CURL through management panel to activate theme selected in 3b and plugins selected in 3c</span></p>
<p>*Repeat step 3 for each keyword supplied to the function</span></p>
<p>NOTES: This method, when optimized and threaded, can install one in about 25 seconds. Once again, the major impediment to speed here is the FTP transfer. This is still a lot faster than Solution 1, and is perhaps the best solution for a situation where you can&#8217;t use SSH. I should note that you could also just create one central tarball and then mechanize/CURL the CPanel File Manager to copy and unzip it for each new install, but&#8230;I really hate to use that amount of screen automation. It just tends to break down so often. </span></p>
<p>Situation:<br />
Shared / VPN Server<br />
CPanel<br />
SSH Access</span></p>
<p> Solution 1: Master Server Central Wordpress Install / Mechanize CURL Install<br />
Process:<br />
1) Upload base Wordpress install files, Theme Library, Plugin Library from master server to central location on install server<br />
2) Create a deployment file that does the following:<br />
2a) Copy base Wordpress install to destination folder using SSH<br />
2b) Set up symbolic links between destination install themes &amp; plugins, with the central libraries uploaded in step 1.<br />
2c) If necessary, create databases and users<br />
2d) Create Wordpress Config file based on information supplied by master server<br />
3) Mechanize/CURL to appropriate Install URL, then Mechanize/CURL through management panel to activate desired theme &amp; plugins.<br />
* For each blog you wish to install, just upload a new deployment file</span></p>
<p> NOTES: Once you have installed the central libraries, this method is extremely fast.</span></p>
<p> CONCLUSIONS: At the end of the day, it is definitely faster and more space efficient if you have SSH access through which you can automate the install process. Unfortunately, many shared hosts don&#8217;t offer SSH access (some offer it only if you provide some form of government identification). Many people go for shared hosting situations because they are very cheap, low-risk and you can afford to buy many different hosting packages with different IP addresses. For people who are running more sophisticated networks and have greater resources, VPS situations (without CPanel) are preferable, since they are more stable with more available resources, and of course, SSH, which really makes automation a breeze.</span></p>
<p> Automating the deployment and install of Wordpress blogs can be a really frustrating process to wade through. That said, ..blah&#8230;.blah&#8230;and&#8230;gratifying&#8230;.blah&#8230;1000 blogs&#8230;.blah blah&#8230;button click&#8230;.bla<br />
h&#8230;elite spammer&#8230;blah blah</span></p>
]]></content:encoded>
			<wfw:commentRss>http://seocracy.com/2008/08/effective-and-efficient-ways-to-mass-install-wordpress/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
