<?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>GeekLad &#187; Programming</title>
	<atom:link href="http://geeklad.com/category/programming/feed" rel="self" type="application/rss+xml" />
	<link>http://geeklad.com</link>
	<description></description>
	<lastBuildDate>Wed, 01 Feb 2012 14:25:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Playing the Empire Avenue Social Media Exchange</title>
		<link>http://geeklad.com/playing-empire-avenue</link>
		<comments>http://geeklad.com/playing-empire-avenue#comments</comments>
		<pubDate>Tue, 10 May 2011 02:00:56 +0000</pubDate>
		<dc:creator>GeekLad</dc:creator>
				<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://geeklad.com/?p=2442</guid>
		<description><![CDATA[Update: e(RINGLE) has incorporated my algorithm into his P3 for Empire Avenue Chrome extension. Use his extension instead of mine, because it includes what I built and much more! If you already installed mine, be sure to uninstall it before installing P3, or some weird things can happen. Recently, I … <a href="http://geeklad.com/playing-empire-avenue"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://empireavenue.com/?t=zb6nzta0"><img src="http://geeklad.com/wp-content/uploads/2011/05/empire-avenue-logo.png" alt="" title="empire-avenue-logo" width="300" height="43" class="alignleft size-full wp-image-2443" style="border: 0 none;" /></a> <em><strong>Update</strong>: <a href="http://www.empireavenue.com/RINGLE?t=zb6nzta0">e(RINGLE)</a> has incorporated my algorithm into his <a href="https://chrome.google.com/webstore/detail/nicoicbaoinjgpcclfjdkfimngkgogdl">P<sup>3</sup> for Empire Avenue</a> Chrome extension.  Use his extension instead of mine, because it includes what I built and much more!  If you already installed mine, be sure to uninstall it before installing P<sup>3</sup>, or some weird things can happen.</em></p>
<p>Recently, I started playing in a fantasy social media stock exchange, called <a href="http://empireavenue.com/?t=zb6nzta0">Empire Avenue</a>. It took me a while to get a handle on what moves the prices, and I&#8217;m still learning.  With some help from <a href="http://chris.pirillo.com/">Chris Pirillo</a>, I think I&#8217;ve finally got a good handle on it and he&#8217;s helped me start a tool that can help you build a sound Empire Avenue portfolio too.</p>
<p><span id="more-2442"></span>I first came to learn about Empire Avenue when Jesse Stay made a few blog posts about it where he writes about Empire Avenue as <a href="http://www.staynalive.com/2011/04/empire-avenue-is-catalyst-for-new.html">a catalyst for the new economy</a> and <a href="http://www.staynalive.com/2011/05/new-frontier-of-capitalism.html">the new frontier of capitalism</a>.  Both articles were excellent, but my interest hadn&#8217;t quite piqued until my good friend Bwana posted his <a href="http://www.bwana.org/2011/05/07/empire-avenue-just-plain-fun/">thoughts on Empire Avenue</a> and he referred me to <a href="http://chris.pirillo.com/my-empire-avenue-strategy-and-tips/">Chris Pirillo&#8217;s tips on Empire Avenue</a>.</p>
<h3>Two Ways to Make Eaves</h3>
<p>Eaves are the Empire Avenue (virtual) currency.  Being a numbers guy and with data analysis being my day job, I wanted to learn how to play the Empire Avenue exchange.  I figured I could probably put together some tools to earn some virtual money, just as I did in <a href="http://geeklad.com/urban-rivals-market-bot">Urban Rivals</a>.</p>
<p>When it comes down to it, there are two ways to make Eaves in Empire Avenue with your investments:</p>
<ul>
<li>By earning dividends from what I will henceforth refer to as stocks (which are actually people or companies &#8211; i.e. entities with social networking accounts)</li>
<li>By buying stocks for a low price and selling at a higher price</li>
</ul>
<p>Fundamentally speaking it&#8217;s pretty simple, but in order to determine what constitutes a good investment, you need to learn what drives both dividends and stock prices.  It became very clear to me when Chris Pirillo told me:</p>
<blockquote>
<ul>
<li>Stock price = buying interest from others</li>
<li>Dividends = your (social networking) activity (both on and off-site)</li>
</ul>
</blockquote>
<h3>Dividend Yield</h3>
<p>Chris Pirillo&#8217;s strategy is to identify stocks that provide a high dividend, relative to the stock price.  I like this strategy very much, because it is quite conservative.  If you find a good dividend producer, the stock price could remain stagnant or even drop, and you still make money.  While you own the stock, you will continue to earn daily dividends, which come from the daily social networking activities of the person/company.</p>
<p>This strategy also applies to real stock exchanges, where investors might purchase a stock that has an attractive <strong>dividend yield</strong>.  Dividend yield is calculated by dividing the dividends paid per share by the stock price.  It&#8217;s a good measure to use to decide whether or not a stock might be a good investment, in terms of the dividends it will provide relative to the purchase price of the stock.</p>
<p>Because I was attracted to Chris&#8217; strategy of focusing on high dividend yielding stocks, I started developing my own Chrome Extension to provide some investment analysis on Empire Avenue stocks.  Chris provided a great deal of help in developing the tool, with suggestions on what to add.  In addition to providing dividend yields, it also provides break even information (which I will explain in a bit) as well as current profitability info for the stocks you currently own.</p>
<h3>Capital Appreciation</h3>
<p>Just as one might buy real life stocks low and sell high, that same concept applies to Empire Avenue.  In real life stock markets, this is referred to as <b>capital appreciation</b>.  You can certainly use dividend yield to decide whether or not a stock is still relatively inexpensive compared to the dividends it provides.  Chris also uses this as an indicator for whether or not a stock has room to grow in price.</p>
<p>I think this is a decent strategy as well, however, I would not rely on it alone.  The price of a stock is driven by the demand to buy it.  If a lot of people want to buy it, the stock price will move up.  By the same token, if the stock has appeared to plateau, it may drive individuals to sell it which in turn would drive the stock price down.  The speculative nature of these ups and downs can make investing based on price alone somewhat risky.</p>
<p>Until more tools such as mine and <a href="https://chrome.google.com/webstore/detail/nicoicbaoinjgpcclfjdkfimngkgogdl">Eddie Ringle&#8217;s</a> (I will likely incorporate my calculations into his extension eventually, as he has his open sourced and <a href="https://github.com/eddieringle/p3_eav">posted to Git</a>) come out and provide additional valuation metrics and analysis, there is also the human nature of thinking because the share price is high the stock is expensive, which is mistake many would-be investors make.  One cannot value a stock as inexpensive or expensive based on share price alone.  It must be placed into context with valuation metrics such as dividend yield.</p>
<p>For example, my stock <a href="http://www.empireavenue.com/GEEKLAD?t=zb6nzta0">e(GEEKLAD)</a> is currently trading for 13.620 and Chris&#8217; stock <a href="http://www.empireavenue.com/PIRILLO?t=zb6nzta0">e(PIRILLO)</a> is trading for 156.32.  If you were to value our stocks on share price alone, you would say mine is cheap and Chris&#8217; is expensive.  However, if you used dividend yield to valuate our stocks, Chris&#8217; could be considered much cheaper.  His provides more than a 1% dividend yield, whereas mine does not even provide 0.50% dividend yield.</p>
<p>On the other hand, there is still that human factor where most individuals would have the tendency to say Chris&#8217; stock is more expensive than mine, and I would suspect that at his current price his stock probably won&#8217;t appreciate as fast as mine.  Also, because he has many more outstanding shares, it would take much more volume for his stock to move rapidly than it would take for my stock to move.  As the outstanding shares increase, the relative volume will probably decrease, so you&#8217;ll see slower acceleration in the stock price.</p>
<h3>My Chrome Extension</h3>
<p>My plugin provides you with the following information when you either view a stock&#8217;s profile page (when you are logged into Empire Avenue):</p>
<ul>
<li><b><u>Daily Dividend Yield</u></b>: This the calculation of the daily dividend per share divided by the share price.  In Chris&#8217; experience, 1% is a good yield, 2% is extremely good, and 3% is nearly unheard of.</li>
<li><b><u>Approximate Dividend Pay Back (Days)</u></b>This is how long it would take you to earn back the money you paid to buy the stock, and cover (an assumed) 5% commission as well as the 5% commission you would need to pay when you sell it.</li>
<li><b><u>Current Break Even</u></b>: This is the share price the stock would have to increase to, in order to cover the 5% purchase commission and 5% sale commission if the stock were purchased at the current price.</li>
</ul>
<p>In addition, for stocks you already own you will also see:</p>
<ul>
<li><b><u>Your Average Purchase Price</u></b>: This is your average purchase price, excluding commissions.</li>
<li><b><u>Your Breakeven Price</u></b>: This is where the stock price has to be for you to recoup your purchase price, purchase commission (assumed at 5%) and sale commission as well.</li>
<li><b><u>Your Real Gain per Share</u></b>: This is how much you&#8217;ve actually made per share, taking account your purchase commission and your sale commission if you were to sell at the current share price.</li>
<li><b><u>Your Real Total Gain</u></b>: This is how much you&#8217;ve actually made in total, taking into account commissions for the purchase and sale and your average purchase price, were you to sell the price at the current share price.</li>
</ul>
<p>Here&#8217;s a screenshot of my investment in <a href="http://www.empireavenue.com/BWANA?t=zb6nzta0">e(BWANA)</a>:</p>
<p><img src="http://geeklad.com/wp-content/uploads/2011/05/empire-avenue-investment-analyzer-screenshot.png" alt="" title="empire-avenue-investment-analyzer-screenshot" class="aligncenter size-full" /></p>
<p>To see this in action, visit your portfolio/lists at <a href="http://www.empireavenue.com/influencer/portfolio">http://www.empireavenue.com/influencer/portfolio</a>, then click on any stock to view the stats as you see them in the screenshot above.  You can also see those stats if you visit a stock profile page.  For profile pages of stocks you own, you&#8217;ll see your profitability stats.</p>
<p>It is very important to make sure you cover your purchase/sale commissions when you trade, otherwise you could very well sell a stock you think you&#8217;ve made money on, but you won&#8217;t be able to cover the 10.5% or so you&#8217;ll pay in commissions.  Say what?  Why 10.5%???  To calculate the gain, you can take 105% and divide it by 95%, which gives you a little over 110.5%.  That 10.5% represents the gain from your purchase price that you need to cover your purchase and sale commissions.</p>
<p>If you make a hot buy that has a higher purchase commission, your break even is even higher.  Unfortunately, neither the website or API (from what I can tell) provide any info on commissions you&#8217;ve paid in your transactions, so I have to assume you paid 5%.  If you paid 30% commission and pay 5% on the sale, your pay back would be 36.8% above your purchase price (130% divided by 95%).</p>
<p>So do not be alarmed when you view a stock in your portfolio and my plugin says you currently have a loss.  It&#8217;s because the stock hasn&#8217;t moved high enough to cover your commissions.  However, if you have a stock that yields 1% dividends, your dividends will have covered your commissions in 11 days or so.  In a future version of the extension, I want to account for accumulated dividends to get a true ROI calculation, which would be:</p>
<p><i>Sale Price &#8211; Sale Commissions &#8211; Purchase Price &#8211; Purchase Commissions <b> + Accumulated Dividends</b></i></p>
<p>What Chris previously referred to as ROI (previous to the discussions I had with him), is actually dividend yield.  ROI would be calculated as I have stated in my formula above, for investments currently being held.  If I can get to a true ROI calculation that includes accumulated dividends, my extension will be that much better.</p>
<p>So, give it a shot and <strike><a href="#">download the Empire Avenue Investment Analyzer Chrome extension</a></strike> <a href="https://chrome.google.com/webstore/detail/nicoicbaoinjgpcclfjdkfimngkgogdl">download the P<sup>3</sup> for Empire Avenue Chrome extension</a>.  Let me know what suggestions you may have by leaving comments here, or if you run into any bugs.  Feel free to ask me any questions about investing on Empire Avenue as well, and I&#8217;ll be glad to try to answer them.  Good luck and happy investing!</p>
<p>If you like my extension, feel free to show your appreciation and pick up a few shares of <a href="http://www.empireavenue.com/GEEKLAD?t=zb6nzta0">e(GEEKLAD)</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://geeklad.com/playing-empire-avenue/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Urban Rivals Market Bot</title>
		<link>http://geeklad.com/urban-rivals-market-bot</link>
		<comments>http://geeklad.com/urban-rivals-market-bot#comments</comments>
		<pubDate>Wed, 23 Mar 2011 02:43:25 +0000</pubDate>
		<dc:creator>GeekLad</dc:creator>
				<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Google Chrome]]></category>

		<guid isPermaLink="false">http://geeklad.com/?p=2260</guid>
		<description><![CDATA[Update: Shortly after I posted this, the good folks of Urban Rivals politely asked me to remove the post and I politely declined. About a week later, someone informed me changes were made to the market, and the first few sales for each card are now displayed as images rather … <a href="http://geeklad.com/urban-rivals-market-bot"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p><img src="http://geeklad.com/wp-content/uploads/2011/03/urban-rivals-logo.png" alt="urban-rivals-logo" title="urban-rivals-logo" width="204" height="103" class="alignleft size-full wp-image-2261" style="border: 0 none;" /><i><b><u>Update</u></b>: Shortly after I posted this, the good folks of Urban Rivals politely asked me to remove the post and I politely declined.  About a week later, someone informed me changes were made to the market, and the first few sales for each card are now displayed as images rather than HTML.  He said up until then, the bot was working great for him, but the changes to the market have caused the bot to stop working.  Unless someone is able to fix it with some sort of image to text JavaScript library (I think there are some libraries that do this w/ captchas), the script is effectively dead.  I will leave the source posted, in case someone is able to repair it.</i></p>
<p>Some time ago, a friend got me into an online card game called <a href="http://www.urban-rivals.com/">Urban Rivals</a>.  It is similar to other card games such as Magic the Gathering, but played online either via iPhone/iPad app or in your browser.  One aspect of the game that quickly got my attention (other than the game itself), was the card marketplace where you can buy and sell playing cards.</p>
<p>It didn&#8217;t take long for me to realize that it was an inefficient market.  Profitable trades presented themselves quite regularly, and with a bit of automation it would be easy to take advantage of the market.  I proceeded with developing a Google Chrome extension that would allow me to do so, and it worked quite well.</p>
<p><span id="more-2260"></span><!-- more -->Over the course of a few days, I had it up and running, automating both buying and selling of cards.  Essentially, it continually scans the marketplace until a profitable buy appears, buys the card (or cards), and immediately posts them for sale at one clintz (the in-game currency) below the lowest price.  I told a friend of mine about it, and with some trepidation at first, he decided to try it out and helped me test and tweak it.  Eventually, he realized it worked great and used it extensively as I did.</p>
<p>When it was all said and done, I had accumulated probably over 6 million worth of clintz and cards, having started with just a few thousand.  My friend had probably accumulated on the order of about 5 million.  Ultimately, my friend and I were both banned.  I told him if ever I did get banned, I would likely release the extension into the wild to see what sort of havoc it might wreak on the marketplace.  Well, I did get banned, so here we are.  Even before I was banned, I had a morbid curiosity to learn what might happen if I were to give it to more than just one or two other players.  Having been banned was just the excuse I was looking for, as I (and my friends) no longer have a vested interest in keeping it a secret.</p>
<h3>Words of Wisdom in Using the Urban Rivals Market Bot</h3>
<p>First and foremost, <strong><em>Use at Your Own Risk.</em></strong><br />
If the good folks of Urban Rivals find out you&#8217;re using a bot, they will ban you.  If you use it in moderation, you may not get caught.  Of course, I can make no guarantees.  If you get banned for using this, don&#8217;t blame me as you&#8217;ve been warned!</p>
<p><strong><em>Be very careful if you set up a separate account.</em></strong><br />
My friend set up an account for using the bot, in case if he got banned, so he would still have the original account.  Unfortunately this plan backfired on him, as he was banned not for the bot but both accounts were banned for having duplicate accounts.</p>
<p>If you do use decide to set up an additional account, do not ever connect to them from the same internet connection.  You could try using <a href="https://www.torproject.org/">Tor</a> to connect from an anonymous internet connection for the bot account, and use your regular internet connection for your regular account.  I haven&#8217;t tried this, but this method of using multiple accounts would probably work without a problem.  You just have to be very careful you never connect via the same method/connection.</p>
<p><strong><em>It may not work for long, or at all at this point.</em></strong><br />
 Since I no longer have a valid Urban Rivals account, I have no mechanism to see if it even still works.  The last time I used it, it worked without issue so it&#8217;s likely it still works, but I make no guarantees.  So that my &#8220;legacy&#8221; may still live on, I&#8217;ll include the source code as well.</p>
<p>If you&#8217;re good with JavaScript, you can probably figure out my mess of code and fix things if they&#8217;ve broken.  If you do fix any bugs you see, feel free to send me the new code and I&#8217;ll post it here.</p>
<p><strong><em>Be prepared for personal attacks.</em></strong><br />
Because the bot works by looking for good deals, occasionally it picks up deals that were posted in error.  Sometimes people forget a 0, and end up posting a card worth thousands for hundreds, or even hundreds of thousands for tens of thousands.  The bot will pick these up for a song and repost them for sale and make 10x profit.  Of course, when this happens it sometimes solicits inflammatory language from those that posted the price in error.</p>
<p>I would gladly exchange the card back to players that asked politely and patiently.  Either I would tell them to sell me a cheap card for slightly less than the value of the card so I could still make a profit, or sell the card back to them (if I still had it) for a profit.  I would recommend you do the same, if you do not wish to draw the attention of the UR gods.  If you want to remain even more transparent, you may even wish to throw the impolite requestors a bone as well.</p>
<p>I would also recommend disabling your online presence for your UR login.  I think in many cases, the players I pissed off thought I was online, when in fact it was simply that my browser window was open conducting market transactions on my behalf.  In some cases, I was receiving many messages from incensed players within minutes of each other, but I did not see the messages for many hours later and sometimes even days.</p>
<p>When I finally realized my online presence was the reason I was receiving so many messages so quickly from the same angry players, I disabled my online presence.  This helped quite a bit to quell the angry messages coming in rapid succession, but they did still happen.  Be nice to those who make mistakes in their market transactions and ask you to sell their card back to them.</p>
<h3>Instructions</h3>
<ol>
<li>If you don&#8217;t have it, <a href="http://www.google.com/chrome">download Google Chrome</a>, the best web browser known to man</p>
<li>Download and install the <a href="http://geeklad.com/tools/Urban%20Rivals%20Market%20Bot.crx">Urban Rivals Market Bot</a> Extension for Google Chrome</li>
<li>Configure the bot however you like:
<ul>
<li><strong>Enable Profitability Filter</strong>: This enables/disables the filtering of the market to only show profitable trades, according to the profitability settings.</p>
<li><strong>Enable Stars Filter</strong>: You can filter the market to only show cards with a certain number of stars
<li><strong>Min and Max Price</strong>: The minimum and max price to filter on.  Cards less than the minimum or more than the maximum will be removed from the market list.
<li><strong>Min Profit</strong>: The minimum amount of profit to make on the purchase and sale of a card, if sold for 1 clintz less than the lowest listed card.  Any cards that do not meet this criteria will not be displayed in the market.
<li><strong>Min Percent Profit</strong>: The minimum percent profit to make on the purchase/sale.  Cards must meet both the min profit and min percent profit criteria to be displayed.
<li><strong>Autobuy</strong>: Buy cards that meet the profit filter criteria.  Without the profitability filter enabled, this does nothing.
<li><strong>Autosell</strong>: Sell cards that are autobought.  Without autobuy enabled, this won&#8217;t do anything.  If disabled while autobuy runs, cards will be accumulated in a profitable manner, but not sold.
<li><strong>Refresh Delay</strong>: How many seconds to wait before refreshing the market page to try autobuying again.  You can set it to 0.  If you set it too fast, you&#8217;ll probably get a captcha, at which point the bot will stop working until you manually clear the captcha.
<li><strong>Max # of Cards to Buy</strong>: Sometimes there are profitable trades where there is a big breakpoint in the price of cards.  You can buy perhaps the two or three cheapest cards, and sell at the price of the remaining cheapest card.  If you want to be conservative, just leave it at 1.
<li><strong>Max Premium on Sale</strong>: Sometimes players buy up a lot of cards to raise the lowest price so they can sell the cards they buy at a higher price.  This is a safeguard to avoid buying/selling a card when this has happened, otherwise you could fall victim to this market manipulation tactic.  This is how far you are willing to resell a card marked up above the lowest price of the day, week, and month.  If you set it too high, you could end up paying too much for a card and you won&#8217;t be able to sell it profitably.  I typically ran it at 10 percent, which served me well.</ul>
<li>Visit the first page of the UR market.  Be sure to sort the market by date, with the most recent listings first (this is the default, so you really shouldn&#8217;t have to change anything).  The page will continually refresh according to the refresh delay setting, and as profitable listings are found it will attempt to buy them and resell them 1 clintz lower than the cheapest.  Please note, that it will only deal with cards with maxed experience.
</ol>
<p><strong>The Autosale of Doubles Feature</strong><br />
One last note on using the plugin.  If your sales expire, you may end up with many doubles in your collection.  I eventually grew tired of manually selling all of my doubles, so I also added functionality to autosell doubles when visiting my collection page.  When you visit your collection page, if you have doubles you&#8217;ll be prompted if you want to sell them.  </p>
<p>If you use this feature to sell a lot of doubles at once (perhaps 50 or more), it could result in a temporary ban from using the market.  This is a bit more severe than being captchad, as you can&#8217;t do anything but wait on the order of about 7-8 hours to access the marketplace again.  Don&#8217;t panic if it does happen, but you won&#8217;t be able to access ANY market pages (even your pending sales, sold cards, etc.) until enough time has passed.  I ultimately wanted to make this a feature that could be enabled/disabled in the settings popup, but I never got around to implementing that.</p>
<h3>A Small Request</h3>
<p>If someone could do me a favor, please contact <a href="http://www.urban-rivals.com/player/?id_player=13219177">mrdisco</a> and tell him about my bot.  He went on a rant in the forums to tell everyone what an asshole I am (scroll to the bottom of <a href="http://www.urban-rivals.com/community/forum/?mode=viewsubject&#038;id_subject=1488133&#038;language=2#37389312">this post</a> to read it).  Someone please send him the link to this post.  At least he can recoup his clintz using my bot, and even make a good bit more.</p>
<p>I attempted to contact him via UR messaging to tell him I would have gladly refunded him, if he had given me a chance to respond.  He sent me a barrage of messages in a span of maybe an hour, probably while I was sleeping or at work, so I never got to respond.  By the time I was able to respond, he added me to is ignore list so I couldn&#8217;t message him on UR although I wanted to.</p>
<p>At the time, I decided it best I not even try to explain myself in the forum.  He obviously had no interest in hearing what I had to say since he never even gave me the chance to explain.  At this point, I think this post is sufficient explanation and perhaps he may even no longer feel ill will.</p>
<h3>Final Thoughts</h3>
<p>Unfortunately, I was banned from UR (I&#8217;m sure mrdisco will be happy about that) so I am not able to post this in the UR forums, so here it is on my blog.  If any discussion does take place in the UR forums about it, please feel free to repost it here.  I&#8217;m very curious to know what people might say about it, if anything at all.</p>
<p>Oh, I almost forgot the source code!</p>
<p><a href="http://geeklad.com/tools/Urban%20Rivals%20Market%20Bot.zip">Download the Urban Rivals Market Bot Source Code</a></p>
<p>The code is ugly but it works (at least it did, when I last used it).  It&#8217;s all screen scraping with regular expressions in JavaScript.  If you know JavaScript, you can probably figure it out for the most part.  If you know regular expressions as well, then you can easily bend it to your will.  If you do, feel free to reach out to me if you keep the code working and up-to-date.</p>
<p>Enjoy!  Let me know if you have any questions about the plugin.  Unfortunately, without a UR account I really can&#8217;t do anything about fixing bugs if there are any, but perhaps there&#8217;s a JavaScript/regular expression guru out there that can take hold of the Urban Rivals Market Bot torch.</p>
]]></content:encoded>
			<wfw:commentRss>http://geeklad.com/urban-rivals-market-bot/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>goo.gl URL Shortener Bookmarklet via YQL</title>
		<link>http://geeklad.com/goo-gl-url-shortener-bookmarklet-via-yql</link>
		<comments>http://geeklad.com/goo-gl-url-shortener-bookmarklet-via-yql#comments</comments>
		<pubDate>Sat, 16 Jan 2010 15:40:54 +0000</pubDate>
		<dc:creator>GeekLad</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[goo.gl]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[YQL]]></category>

		<guid isPermaLink="false">http://geeklad.com/?p=2087</guid>
		<description><![CDATA[Last month we saw a new Google URL shortening service that will be used for Feedburner and the Google Toolbar. It wasn&#8217;t long before the URL shortening code in the toolbar was dissected, and subsequent APIs developed. I managed to put together my own by using YQL. YQL is a … <a href="http://geeklad.com/goo-gl-url-shortener-bookmarklet-via-yql"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-2088" title="goo.gl_yql" src="http://geeklad.com/wp-content/uploads/2010/01/goo.gl_yql.png" alt="goo.gl_yql" width="247" height="243" style="border: 0 none;" />Last month we saw a new <a href="http://googleblog.blogspot.com/2009/12/making-urls-shorter-for-google-toolbar.html">Google URL shortening service</a> that will be used for Feedburner and the Google Toolbar.  It wasn&#8217;t long before the <a href="http://www.kix.in/blog/2009/12/goo-gl/">URL shortening code in the toolbar was dissected</a>, and subsequent APIs developed.  I managed to put together my own by using <a href="http://developer.yahoo.com/yql/">YQL</a>.</p>
<p><span id="more-2087"></span>YQL is a truly amazing web API.  With its <a href="http://developer.yahoo.com/yql/guide/yql-execute-chapter.html">server-side JavaScript</a> and the ability to quickly scour the web for information, there is very little it cannot do.  I decided it was the perfect platform for putting together a simple API for goo.gl.</p>
<p>Because the Google Toolbar was already written in JavaScript, implementing it in YQL was quite easy with the server-side JavaScript.  It wasn&#8217;t long, before I put together my own <a href="http://www.datatables.org/">open data table</a> for <a href="http://goo.gl">goo.gl</a>.</p>
<p>I submitted my open table to the <a href="http://github.com/yql/yql-tables">git repository for open data tables</a>, and shortly after my <a href="http://github.com/yql/yql-tables/blob/master/google/google.goo.gl.xml">goo.gl open data table</a> was included.  It&#8217;s really pretty simple.  The YQL you would use to get the short URL for my blog would be:</p>
<p><code>SELECT * FROM google.goo.gl WHERE url="http://geeklad.com"</code></p>
<p>The great thing about YQL is that you can obtain the data as XML or JSON, and specify a JSON callback function.  So that means it&#8217;s very easy to use in JavaScript and develop <a href="http://geeklad.com/make-cross-domain-ajax-requests-with-xdrequest">cross-domain JavaScript</a>.  I put together a simple bookmarklet that uses my public YQL table and provides a goo.gl URL for the current page.  To try it out, just drag and drop the link below to your browser&#8217;s shortcut bar:</p>
<p><p style="text-align: center;"><a style="border: 1px solid #888888; padding: 4px 8px; font-weight: bold;" href="javascript:var YQL_url='https://query.yahooapis.com/v1/public/yql?format=json&env=store://datatables.org/alltableswithkeys&q=';var YQL_statement='SELECT * FROM google.goo.gl WHERE url=\''+document.location.href+'\'';var YQL_script_url=YQL_url+encodeURIComponent(YQL_statement)+'&callback=yql_cb';function yql_cb(response){short_url=response.query.results.result;prompt('Here is your short URL:  (be sure to copy to your clipboard)', short_url);}var yql_script=document.createElement('script');yql_script.src=YQL_script_url;document.getElementsByTagName('head')[0].appendChild(yql_script);void(0);">goo.gl page</a></p></p>
<p>Here&#8217;s the JavaScript code from the bookmarklet:<br />

<pre><code>var YQL_url='https://query.yahooapis.com/v1/public/yql?format=json&env=store://datatables.org/alltableswithkeys&q=';
var YQL_statement='SELECT * FROM google.goo.gl WHERE url=\''+document.location.href+'\'';
var YQL_script_url=YQL_url+encodeURIComponent(YQL_statement)+'&callback=yql_cb';
function yql_cb(response){
	short_url=response.query.results.result;
	prompt('Here is your short URL (be sure to copy to your clipboard): ', short_url);
}
var yql_script=document.createElement('script');
yql_script.src=YQL_script_url;
document.getElementsByTagName('head')[0].appendChild(yql_script);</code></pre>
</p>
<p>Pretty simple.  Basically it works by putting together the YQL statement w/ the URL of the current page, builds the proper YQL API URL for it, and finally inserts a JavaScript script with the call to the callback function that displays the URL of the current page in a prompt.  You&#8217;ll have to manually copy it to your clipboard.  Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://geeklad.com/goo-gl-url-shortener-bookmarklet-via-yql/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Google Fusion Tables Could be a Game Changer</title>
		<link>http://geeklad.com/google-fusion-tables-could-be-a-game-changer</link>
		<comments>http://geeklad.com/google-fusion-tables-could-be-a-game-changer#comments</comments>
		<pubDate>Tue, 15 Dec 2009 23:56:16 +0000</pubDate>
		<dc:creator>GeekLad</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Chrome]]></category>
		<category><![CDATA[Google Fusion Tables]]></category>

		<guid isPermaLink="false">http://geeklad.com/?p=2028</guid>
		<description><![CDATA[Google has been very busy lately with many new products recently. Many of them, such as Google Public DNS, Google Chrome OS, and real-time search have received the lion&#8217;s share of publicity. I&#8217;d like to talk about a little jewel sitting in Google Labs you may not heard of. It&#8217;s … <a href="http://geeklad.com/google-fusion-tables-could-be-a-game-changer"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p><img src="http://geeklad.com/wp-content/uploads/2009/12/fusiontables_logo.png" alt="fusiontables_logo" title="fusiontables_logo" width="251" height="43" class="alignleft size-full wp-image-2029" style="border: 0 none;" /> Google has been very busy lately with many new products recently.  Many of them, such as <a href="http://googleblog.blogspot.com/2009/12/introducing-google-public-dns.html">Google Public DNS</a>, <a href="http://googleblog.blogspot.com/2009/11/releasing-chromium-os-open-source.html">Google Chrome OS</a>, and <a href="http://googleblog.blogspot.com/2009/12/relevance-meets-real-time-web.html">real-time search</a> have received the lion&#8217;s share of publicity.  I&#8217;d like to talk about a little jewel sitting in <a href="http://www.googlelabs.com">Google Labs</a> you may not heard of.   It&#8217;s a shiny little jewel that could become a real game changer and not many people are talking about it yet: <a href="http://tables.googlelabs.com">Google Fusion Tables</a>.</p>
<p><span id="more-2028"></span>Google Fusion Tables is a web application that allows you to import, manipulate, and generate reports from large data sets.  It is designed to handle much more data than you can put into <a href="http://docs.google.com/support/bin/topic.py?hl=en&#038;topic=15115">Google Spreadsheets</a> or versions of Excel earlier than Excel 2007.  Some time ago, I started fooling around with it and I managed to import a relatively large data set with nearly 150,000 records without any issues whatsoever.  The interface also provides some nice ways to visualize the data.</p>
<p><img src="http://geeklad.com/wp-content/uploads/2009/12/fusiontables_visualizations.png" alt="fusiontables_visualizations" title="fusiontables_visualizations" width="240" height="275" class="alignnone size-full wp-image-2034" style="border: 0 none;"/></p>
<p>In addition to providing some nifty visualizations, there are also many data tables that have been published for public use.  For example, the 2010 Quality of Life Index:</p>
<p><img src="http://geeklad.com/wp-content/uploads/2009/12/fusiontables_screenshot.png" alt="fusiontables_screenshot" title="fusiontables_screenshot" width="500" height="240" class="alignnone size-full wp-image-2033" style="border: 0 none;" /></p>
<p>So why do I think this could be a game changer?  Yesterday, the Google Code Blog <a href="http://googlecode.blogspot.com/2009/12/google-fusion-tables-api.html">announced the Fusion Tables API</a>.  With the API it is no longer necessary to use the Fusion Tables web interface to upload, manipulate, and visualize data.  Now it can be done programatically, and Fusion Tables can be used to store large data sets in the cloud.  The data can be extracted using <a href="http://en.wikipedia.org/wiki/SQL">SQL</a>, which is the gold standard for handling the data stored within databases.</p>
<p>Not long ago, <a href="http://staynalive.com/">Jesse Stay</a> wrote about <a href="http://staynalive.com/articles/2009/10/15/web-3-0-the-building-block-web/">the building block web</a>.  The Fusion Tables API is a perfect example of a new set of blocks that will integrate very well (and easily) with the building block web.  Persistent data storage is an essential component for the building block web, and that is just what Fusion Tables provides.</p>
<p>Of course, it doesn&#8217;t come without its limitations.  According to the <a href="http://code.google.com/apis/fusiontables/docs/developers_guide.html">Google Fusion Tables API developer&#8217;s guide</a>, the API can send a maximum of 5 requests per second to the Fusion Tables server.  Hopefully Google will lift that constraint or increase it at some point.  5 requests per second won&#8217;t be enough for the enterprise applications that could potentially be built on top of Fusion Tables.</p>
<p>If you&#8217;re a PHP programmer, here&#8217;s some PHP code I&#8217;ve put together to help get you started:</p>
<link href="http://geeklad.com/syntax-highlighter/style.css" rel="stylesheet" type="text/css"/>
<script src="http://geeklad.com/syntax-highlighter/script.js" type="text/javascript"></script></p>
<p>
<script  type="syntaxhighlighter" class="brush: php"><![CDATA[
function GoogleClientLogin($username, $password, $service) {
	// Check that we have all the parameters
	if(!$username || !$password || !$service) {
		throw new Exception("You must provide a username, password, and service when creating a new GoogleClientLogin.");
	}
	
	// Set up the post body
	$body = "accountType=GOOGLE &Email=$username&Passwd=$password&service=$service";
	
	// Set up the cURL
	$c = curl_init ("https://www.google.com/accounts/ClientLogin");
	curl_setopt($c, CURLOPT_POST, true);
	curl_setopt($c, CURLOPT_POSTFIELDS, $body);
	curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($c);
	
	// Parse the response to obtain just the Auth token
	// Basically, we remove everything before the "Auth="
	return preg_replace("/[\s\S]*Auth=/", "", $response);
}

class FusionTable {
	var $token;
	
	function FusionTable($token) {
		if (!$token) {
			throw new Exception("You must provide a token when creating a new FusionTable.");		
		}
		$this->token = $token;
	}
	
	function query($query) {
		if(!$query) {
			throw new Exception("query method requires a query.");
		}
		// Check to see if we have a query that will retrieve data
		if(preg_match("/^select|^show tables|^describe/i", $query)) {
			$request_url = "http://tables.googlelabs.com/api/query?sql=" . urlencode($query);
			$c = curl_init ($request_url);
			curl_setopt($c, CURLOPT_HTTPHEADER, array("Authorization: GoogleLogin auth=" . $this->token));
			curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
			
			// Place the lines of the output into an array
			$results = preg_split("/\n/", curl_exec ($c));
			
			// If we got an error, raise it
			if(curl_getinfo($c, CURLINFO_HTTP_CODE) != 200) {
				return $this->output_error($results);
			}

			// Drop the last (empty) array value
			array_pop($results);
			
			// Parse the output
			return $this->parse_output($results);
		}
		// Otherwise we are going to be updating the table, so we need to the POST method
		else if(preg_match("/^update|^delete|^insert/i", $query)) {
			// Set up the cURL
			$body = "sql=" . urlencode($query);
			$c = curl_init ("http://tables.googlelabs.com/api/query");
			curl_setopt($c, CURLOPT_POST, true);
			curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($c, CURLOPT_HTTPHEADER, array(
				"Content-length: " . strlen($body),
				"Content-type: application/x-www-form-urlencoded",
				"Authorization: GoogleLogin auth=" . $this->token . " "		// I don't know why, but unless I add extra characters after the token, I get this error: Syntax error near line 1:1: unexpected token: null
			));
			curl_setopt($c, CURLOPT_POSTFIELDS, $body);
			
			// Place the lines of the output into an array
			$results = preg_split("/\n/", curl_exec ($c));
			
			// If we got an error, raise it
			if(curl_getinfo($c, CURLINFO_HTTP_CODE) != 200) {
				return $this->output_error($results);
			}

			// Drop the last (empty) array value
			array_pop($results);
			
			return $this->parse_output($results);
		}
		else {
			throw new Exception("Unknown SQL query submitted.");
		}
	}
	
	private function parse_output($results) {
		$headers = false;
		$output = array();
		foreach($results as $row) {
			// Get the headers
			if(!$headers) {
				$headers = $this->parse_row($row);
			}
			else {
				// Create a new row for the array
				$newrow = array();
				$values = $this->parse_row($row);
				
				// Build an associative array, using the headers for the association
				foreach($headers as $index => $header) {
					$newrow[$header] = $values[$index];
				}
				
				// Add the new array to the output array
				array_push($output, $newrow);
			}
		}
		
		// Return the output
		return $output;
	}
	
	private function parse_row($row) {
		// Split the comma delimted row
		$cells = preg_split("/,/", $row);
		
		// Go through each cell and see if we encounter a double quote
		foreach($cells as $index => $value) {
			// When we encounter a double quote at the start of a cell, we've got a quoted string
			if(preg_match("/^\"/", $value)) {
				// Concatenate the value with the next cell and remove the double quotes
				$cells[$index] = preg_replace("/^\"|\"$/", "", $cells[$index] . $cells[$index+1]);
				
				// Drop the next cell from the array
				array_splice($cells, $index+1, 1);
			}
		}
		return $cells;
	}
	
	private function output_error($err) {
		$err = implode("", $err);
		
		// Remove everything outside of the H1 tag
		$err = preg_replace("/[\s\S]*<H1>|<\/H1>[\s\S]*/i", "", $err);
		
		// Return the error
		return $err;
		
		// Eventually we'll just throw the error rather than return the error output
		throw new Exception($err);
	}
}


// USAGE EXAMPLE

// First, get the token.
// The GoogleClientLogin function will provide the token, given a Google Account email address, password, and service
// (in this case, fusiontables)
$token = GoogleClientLogin("mygm...@gmail.com", "mygoogleaccountpassword", "fusiontables"); 

// Create a new instance of FusionTable, passing in the token generated by GoogleClientLogin
$ft = new FusionTable($token); 

// Have fun!  Use the FusionTable->query method to run queries.
// It will automatically take care of using the GET or POST method, depending on the type of query
// The output is an array of associative arrays.
// The associative arrays use the csv headers for the keys, and the values are the values in the csv columns
$output = $ft->query("SELECT * FROM FOOTABLE WHERE FOO=1");
$ft->query("INSERT INTO FOOTABLE (FOO,BAR) VALUES (1,2)");
]]&gt;
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://geeklad.com/google-fusion-tables-could-be-a-game-changer/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Make Cross-Domain AJAX Requests with xdRequest</title>
		<link>http://geeklad.com/make-cross-domain-ajax-requests-with-xdrequest</link>
		<comments>http://geeklad.com/make-cross-domain-ajax-requests-with-xdrequest#comments</comments>
		<pubDate>Thu, 15 Oct 2009 19:03:25 +0000</pubDate>
		<dc:creator>GeekLad</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[YQL]]></category>

		<guid isPermaLink="false">http://geeklad.com/?p=1843</guid>
		<description><![CDATA[xdRequest is an open-source JavaScript library that I&#8217;ve developed for making cross-domain AJAX requests. In this day and age, with web browsers becoming very fast and powerful, it has become quite possible to build web applications with much of the work performed by the client. xdRequest makes it possible to … <a href="http://geeklad.com/make-cross-domain-ajax-requests-with-xdrequest"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/xdrequest/">xdRequest</a> is an open-source JavaScript library that I&#8217;ve developed for making cross-domain <a href="http://en.wikipedia.org/wiki/Ajax_(programming)">AJAX</a> requests. In this day and age, with web browsers becoming very fast and powerful, it has become quite possible to build web applications with much of the work performed by the client. xdRequest makes it possible to easily pull data from other sources and manipulate it all on the client-side. With xdRequest, you will no longer need to perform data extractions/manipulations from other sources on a server. It can all happen right in the browser.</p>
<p><span id="more-1843"></span></p>
<p><a href="http://geeklad.com/wp-content/uploads/2009/10/YQL-html-data-table.png" rel="lightbox"><img src="http://geeklad.com/wp-content/uploads/2009/10/YQL-html-data-table_thumb.png" alt="Screenshot of the YQL html data table" width="160" height="240" align="right" style="border: 0 none;" /></a> I had recently been fooling around quite a bit with <a href="http://developer.yahoo.com/yql/">YQL</a>, which does provide some built-in features to make cross-domain http requests. It can be done with the html <a href="http://www.datatables.org/">open data table</a>. You can try it out from the <a href="http://developer.yahoo.com/yql/console/">YQL Console</a>.  Just go to the data tables section on the right side and select <strong>Data &gt; html</strong>. Unfortunately, the built-in html table is somewhat limited.  You can only make requests using the GET method, and it does not provide any mechanism for sending/receiving HTTP headers.</p>
<p>Someone in the <a href="http://developer.yahoo.net/forum/index.php?showforum=41">YQL forums</a> posted a <a href="http://developer.yahoo.net/forum/index.php?showtopic=1930">YQL feature request to add POST</a> and other HTTP request methods to the html table. Someone responded with the suggestion of building an open data table to do just that. I then started reading the <a href="http://developer.yahoo.com/yql/guide/yql-opentables-chapter.html">open data table documentation</a>, and came to realize that what you can do with YQL and open data tables is nothing short of astounding.  You can use <a href="http://developer.yahoo.com/yql/guide/yql-execute-chapter.html">server-side JavaScript</a> to request data from multiple sources and manipulate it in any way you see fit.</p>
<p>I started developing my own custom open data table for the particular project I was working on at the time, and eventually the project morphed into xdRequest. Because I needed to track cookies and redirects in my little project, I realized that it would be great to develop a generic library that could handle such requests.  Eventually, I more or less abandoned the previous project to develop xdRequest.  Here are some of the features, as highlighted on the project page:</p>
<ul>
<li>Make cross-domain requests using the GET and POST methods</li>
<li>Add request headers along with the requests</li>
<li>Automatically collect cookies sent by the remote web server</li>
<li>Automatically follow redirects and collect cookies along the way</li>
<li>Properly store/transmit cookies, much like the popular server-side library, <a href="http://curl.haxx.se">cURL</a></li>
<li>Automatically submits hidden fields detected within forms on webpages</li>
</ul>
<p>I also put together a relatively simple <a href="http://geeklad.com/tools/xdRequest/xdRequest-example.html">xdRequest demo</a>. It brings in data from espn.go.com. When the page loads, it makes an xdRequest to ESPN for the <a href="http://www.gatorzone.com/football/">University of Florida Football</a> schedule. I&#8217;m a die-hard Gator and UF alumnus, so that&#8217;s why I decided to start the demo with the UF football schedule. When you can click the hyperlinks in the demo, xdRequests are made to ESPN to load schedules for other teams, as well as the box scores for games. It&#8217;s a simple example, but the sky is the limit as to what you can do with xdRequest.</p>
<p>If you&#8217;re interested in learning more about the project, be sure to check out the <a href="http://code.google.com/p/xdrequest/">xdRequest project</a> page. If you&#8217;re a JavaScript geek and would like to join, just drop me a line and I&#8217;ll gladly add you to the project. I&#8217;m kind of a n00b when it comes to object-oriented programming with JavaScript, so I could definitely use some help to clean up the code, make enhancements, find bugs, and fix bugs. This is the first &#8220;official&#8221; Open Source project I&#8217;ve ever worked on, so I&#8217;m a n00b when it comes to working on OSS as well.</p>
<p>If you like xdRequest and build any cool web applications with it, let me know and I&#8217;ll link to it from the project page. If you have any feature suggestions or encounter any bugs, please report them in the <a href="http://code.google.com/p/xdrequest/issues/list">xdRequest issue tracker</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://geeklad.com/make-cross-domain-ajax-requests-with-xdrequest/feed</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Display Your iGoogle Gadget User Count</title>
		<link>http://geeklad.com/display-your-igoogle-gadget-user-count</link>
		<comments>http://geeklad.com/display-your-igoogle-gadget-user-count#comments</comments>
		<pubDate>Tue, 07 Oct 2008 01:38:56 +0000</pubDate>
		<dc:creator>GeekLad</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[iGoogle gadgets]]></category>

		<guid isPermaLink="false">http://geeklad.com/?p=456</guid>
		<description><![CDATA[Most of you probably won&#8217;t use this ever, but if you are an iGoogle gadget developer then this is definitely for you! I put together a simple little tool that will display how many users my gadgets currently have, and I&#8217;ve set it up so that anyone can use it. … <a href="http://geeklad.com/display-your-igoogle-gadget-user-count"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>Most of you probably won&#8217;t use this ever, but if you are an iGoogle gadget developer then this is definitely for you!  I put together a simple little tool that will display how many users <a href="http://geeklad.com/projects/gadgets">my gadgets</a> currently have, and I&#8217;ve set it up so that anyone can use it.  <span id="more-456"></span>If you&#8217;d like to display the number of users your iGoogle gadget has, simply add this HTML code snippet to any webpage or even within your gadget:</p>
<p><code>&lt;script type="text/javascript" src="http://geeklad.com/tools/gadgetusers.js?url=www.somewebsite.com/somepath/yourgadgetfile.xml"&gt;&lt;/script&gt;</code></p>
<p>Just be sure to replace the <code>www.somewebsite.com</code> and <code>/somepath/yourgadgetfile.xml</code> accordingly.  My gadget user counter works by performing a <code>document.write</code> to output the number of users that are currently using your gadget, according to the <a href="http://www.google.com/ig/directory">iGoogle gadget directory</a>.  I have a feeling that these figures are understated or not updated very often, because according to <a href="http://www.google.com/analytics/">Google Analytics</a> I have many more users than the iGoogle gadget directory states.  At least the directory figures are conservative and they do get updated with some frequency.  Now you can easily inform people as to how many users are using your gadgets too!  Check out <a href="http://geeklad.com/projects/gadgets/web-definitions">my web definitions gadget</a> page to see it in action.</p>
<p>
]]></content:encoded>
			<wfw:commentRss>http://geeklad.com/display-your-igoogle-gadget-user-count/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced

Served from: geeklad.com @ 2012-02-04 00:04:57 -->
