Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

Tuesday, June 19, 2012

The @FindMyPlane bot

A few days ago I wrote about the Genexus Challenge developer edition and my first Smart Devices app, Find my Plane. Once I get, what I think is, a good idea in my head I get around it a lot to improve it in every possible way. But this is not the case, sort of.

Right after I deployed the app to the Apple’s app store, I thought “how can I advertise it, without paying for advertising of course”, I needed people to find out about the app and download it, and a good word about it would be awesome too. So I thought about social networks… Facebook is for friends and I already told them to download it (did I mentioned it’s free?!) so twitter came to mind… but what can I do to promote my app from twitter, other than twitting about it of course.

So I thought of the @FindmyPlane bot and this post will tell you how I did it, not that it’s rocket science, but I found an interesting use of Windows Azure’s Worker Roles*. Wait, what?! you’re gonna tell people how to build a twitter spammer bot? No, let me get into that.

The @FindMyPlane twitter account works like this. You send a twit to @FindMyPlane with your flight number and find my plane will answer that tweet with useful info about it, the same kind of info you’d get in the Find My Plane app, but of course, only the info that fits in 140 characters.

So this is how it works. There’s a worker role (called Receiver) that every ten seconds access the twitter api looking for mentions for the @FindMyPlane account. Once it gets the list of tweets (if any of course) it saves them to a Table from Azure Storage and saves the latest tweet id in a Queue (also from Azure Storage) so the next time it just asks from that tweet on.

This is pretty much the code:

string lastTweet = "";
string previousMessageId = "";
foreach (CloudQueueMessage message in Queue.GetAllMessages(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_QUEUE))
{
previousMessageId = message.Id;
lastTweet = message.AsString;
}

bool first = true;
foreach (Status status in Mentions.GetMentions(fmp, lastTweet))
{
try
{
Table.Insert(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_TABLE, TweetEntity.FromStatus(status).ToString());
}
catch { }

if (first)
{
lastTweet = status.Id;
first = false;
}
}

if (!first)
{
Queue.DeleteMessage(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_QUEUE, previousMessageId);
Queue.CreateMessage(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_QUEUE, lastTweet);
}




And there’s a second Worker Role (called Replier) that every ten seconds queries the table where the tweets were saved for those that have not been replied yet and don’t have errors. For every tweet I try to get info of the flight number sent, if I do find info, I reply the tweet with that info and update the record on the table as replied. If I can’t find info, let’s say you tweeted “@FindMyPlane is awesome!” I update the record as ‘with errors’. This is just a way for me to know when I couldn’t reply because of an error on the system or because what I got was not a valid flight number.



Code here:



string query = "Replied eq 'False' and Error eq 'False'";
foreach (TableEntity entity in Table.Query(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_TABLE, query))
{
string flightNumber = entity["Text"].ToUpper().Replace("@FINDMYPLANE ", "");
try
{
FlightInfo info = FlightStatus.GetFlightStatus(flightNumber);
string tweet = string.Format("@{0} {1}", entity["UserScreenname"], info);
Update.UpdateStatus(tweet, fmp, entity["Id"]);
entity["Replied"] = "True";

Table.UpdateEntity(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_TABLE, entity);
}
catch
{
try
{
entity["Error"] = "True";
Table.UpdateEntity(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_TABLE, entity);
}
catch
{
Table.DeleteEntity(Constants.AZURE_STORAGE_ACCOUNT, Constants.AZURE_STORAGE_KEY, Constants.AZURE_TABLE, entity.PartitionKey, entity.RowKey);
}
}
}



Cool uh?!



Here’s how all this works together



image



(*) for a good read on the Azure platform, Worker Roles and Storage (Table, Queues & Blobs) go to: http://bit.ly/SGAzure



You can download the ‘Find my Plane’ for Android and for iPhone.

Read Full Post

Monday, October 24, 2011

Featuring GXpowerCommands

apgetwikiimageAfter @gmilano’s Cool Commands for Visual Studio I thought I should write my own “cool commands” for Genexus. There a few tasks the I need to do quite often and I thought I’d be great if I could have right there on a contextual menu, like completely deleting a folder and it’s content or “Rebuild and run” an object… or even run (execute) an object as is, no further specification of analysis needed.

So I created this package with the extensions I found useful to myself. Here’s a little description of every command:

Empty and delete folder: I tries to delete every object in a folder and the folder itself. The success will depend on the references the contained objects have to. I any object A outside the selected folder) is referencing an object B from the folder, B won’t be able to be deleted, thus, the folder either. This command is not transactional.
Build/Rebuild folder objects: Ever wanted to build every object in a folder? It’s kind of painful to select every single object, right? Now you can step on a folder and choose to build or rebuild every single object in it.
Rebuild and run: Only valid for main objects, this command will execute a forced build (rebuild) and then execute (run) the generated program.
Run as is: What was that message again? I know the state of the generated program, I just want to execute it, no validation needed. This is the command that will fire the browser and show you the program “as is”. 
Command prompt here: This is a command that’s now built-in in Visual Studio. Applied to Genexus you can open a command prompt at the Knowledge Base directory or at your different environments directories. Just click on the desired node from the Preferences tree and voilá.
Windows Explorer here: Same as command prompt but for Windows Explorer. Enough said.

This package can be freely downloaded from the Genexus Marketplace, so go ahead and give it a try.

In this post I’ll like to answer the question I know some people must be wondering: “dude! you work at the Genexus Development Team, why aren’t these commands available in Genexus out of the box?”. Well, I’m no traditional Genexus developer so I’m not sure if these commands will actually be useful to the entire community so I don’t want to add “noise” to the already pretty big menus we have in Genexus. So depending on the adoption of these commands you might see some of them in Genexus in the near future.

Spanish instructions here, download here.

Like every other set of bits from this blog, this extension is “Works on my machine” certified, but this one has actually been tested by the guys at the Genexus marketplace Smile
works-on-my-machine-starburst_3_thumb[1]

EDIT 25-Oct-2011: Genexus X Evolution 2 support is now available.

Read Full Post

Thursday, March 31, 2011

WCF RIA Services Compositions with Entity Framework

I haven't been working on anything outside Genexus, Deklarit and Genexus Server for a while, so when my friend Mateo asked to help him on a new project for a client of his, based on brand new Microsoft technologies, I was saying yes before the end of the sentence.

This blog post and probably some more to come will be related to our experience with Entity Framework 4, RIA Services 1 and Silverlight 4.

But in this particular case I wanted to blog about a problem we had with Compositions. Compositions are very useful when you have an Association where a Parent entity needs to have its children all the time.

The Update method of parent entities is a bit different than regular entities. I took the patter from this article (Compositional Hierarchies) but things didn’t work as expected. I have to add that “m generating POCO entities and using the Unit Of Work pattern so it wasn’t easy just copy and paste the code for the article. I posted a few questions to the RIA services forum and found out that that pattern exposed a bug :(

Fortunately I was redirected this post from Brett Samblament which described the new pattern to follow to write a fully functional UpdateParent method. But again, I can’t just copy and paste, so here’s the code I wrote for it. Also, by using generic, I’m able to call the exact pattern for every composition in my model, cool uh?!

public void UpdateParent(Parent parent)
{
EntityHelper.UpdateParentEntity(parent, ObjectContext.Parents, ChangeSet, ObjectContext);

foreach (Child child in ChangeSet.GetAssociatedChanges(parent, o => o.Children))
EntityHelper.UpdateChildEntity(child, ObjectContext.Children, ChangeSet, ObjectContext);

}


And my EntityHelper class has the following methods:



public static void UpdateParentEntity<T>(T entity, IRepository<T> repository, ChangeSet chgSet, IUnitOfWork oc)
where T : class
{
try
{
ObjectContext ctx = oc as ObjectContext;
repository.ObjectSet.AddObject(entity);

T originalEntity = chgSet.GetOriginal<T>(entity);

if (originalEntity == null)
ctx.ObjectStateManager.ChangeObjectState(entity, EntityState.Unchanged);
else
repository.ObjectSet.AttachAsModified(entity, originalEntity);
}
catch (Exception ex)
{
TraceManager.Error(string.Format("An error occurred updating a {0}", typeof(T)), ex);
throw;
}
}


public static void UpdateChildEntity<T>(T entity, IRepository<T> repository, ChangeSet chgSet, IUnitOfWork oc)
where T : class
{
try
{
ObjectContext ctx = oc as ObjectContext;
ChangeOperation change = chgSet.GetChangeOperation(entity);

switch (change)
{
case ChangeOperation.Delete:
if (GetEntityState(entity, ctx) == EntityState.Detached)
repository.ObjectSet.Attach(entity);
ctx.DeleteObject(entity);
break;
case ChangeOperation.Insert:
// do nothing
break;
case ChangeOperation.None:
ctx.ObjectStateManager.ChangeObjectState(entity, EntityState.Unchanged);
break;
case ChangeOperation.Update:
T original = chgSet.GetOriginal<T>(entity);
if (original == null) { throw new Exception("Update with no original value found"); }
if (GetEntityState(entity, ctx) == EntityState.Detached)
repository.ObjectSet.Attach(entity);
repository.ObjectSet.AttachAsModified(entity, original);
break;
default:
break;
}
}
catch (Exception ex)
{
TraceManager.Error(string.Format("An error occurred updating a {0}", typeof(T)), ex);
throw;
}
}


public static EntityState GetEntityState(object entity, ObjectContext ctx)
{
System.Data.Objects.ObjectStateEntry ose;
if (ctx.ObjectStateManager.TryGetObjectStateEntry(entity, out ose))
return ose.State;
else
return
EntityState.Detached;
}


I hope this helps someone clear the way… and I promise I’ll post more (and more often) about this.



As usual, this code is ‘works on my machine’ certified.



works on my machine



I never get tired of this Smile

Read Full Post

Wednesday, June 30, 2010

Introducing shelltwit



Some time ago I talked about a command line twitter client I was developing. Today I can proudly say it is finished… for now Smile
And I decided to upload the code to Codeplex GitHub for a few reasons. First of all it uses xAuth with .net with no extra library. Some may be asking “why would you want to do that if there are hundreds of libraries out there?”… well yeah but… no I don’t have an answer for that… I guess I just wanted to give it a try.
Also, while developing this tool I encountered some problems that some people does not ever find, specially people from English speaking countries. The problem appears when you want to twit say… “Peñarol Campeón!”. It took me a little while to discover the right encoding and as I said before, there’s not much written about it. (For more info take a look here)
And finally I wanted to share the code in case some soul out there wanted to give me a hand with the rest of the API. So far this tool only updates the status, but I’m also building a library (cleverly called shelltwitlib) where I’m intending to add every twitter API method.
As a bonus, if you use the shelltwitlib (since it works with xAuth) you’ll be able to have your tool displayed on your status like in the picture shown below.
ViaShelltwit
Want more? Bit.ly integration is also available Smile

works-on-my-machine-starburst_3_thumb[1]

Read Full Post

Monday, May 17, 2010

Encoding strings for the twitter API

gentleface.com free icon set Some time ago, I started to work on shelltwit a command line twitter updater (it only updates your status), but I didn’t want to use any existing library because I wanted to learn how to work directly to twitter API.

I looked around for some examples, the Twitter API doc is not well updated or complete, so it is not easy to start coding right away, you need to read a lot first (I hate when that happens). I found a good sample from Shannon Whitley called Twitter xAuth with .net. I started up with that code but I found an issue with international characters, like á, é or ñ, which kept me from posting about #Peñarol. So I started to hunt the bug, looked around online, went to the Twitter API user group and found out that there are a lot of issues with international characters. I found people form Brazil, Russia and Japan complaining about it. Apparently most libraries were written by english speaking developers so very few encounter the issue.

Now I can happily say that found the issue so I thought about posting the solution here.

Encoded strings (your twitter status) must be made to UTF8 according to RFC3986 and there’s no native .net function that does that, so after some researching I came up with an algorithm that does exactly that. So I hope it helps some one else.

static string UNRESERVED_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";

//http://en.wikipedia.org/wiki/Percent-encoding
//http://www.w3schools.com/tags/ref_urlencode.asp see 'Try It Yourself' to see if this function is encoding well
//This should be encoded according to RFC3986 http://tools.ietf.org/html/rfc3986
//I could not find any native .net function to achieve this
/// <summary>
///
Encodes a string according to RFC 3986
/// </summary>
/// <param name="value">
string to encode</param>
/// <returns></returns>
public static string EncodeString(string value)
{
StringBuilder sb = new StringBuilder();
foreach (char c in value)
{
if (UNRESERVED_CHARS.IndexOf(c) != -1)
sb.Append(c);
else
{
byte[] encoded = Encoding.UTF8.GetBytes(new char[] { c });
for (int i = 0; i < encoded.Length; i++)
{
sb.Append('%');
sb.Append(encoded[i].ToString("X2"));
}
}
}
return sb.ToString();
}

Read Full Post

Monday, April 19, 2010

My Run 2.0 samples

annoysgomez Last week Run 2.0 took place in Montevideo and I had the privilege of working with Guadalupe Casuso (from Microsoft) and Luis Pandolfi (from Infocorp) on part of the Keynote, we talked about Windows Azure and if you ask me it was too short.

After the keynote I talked to some people who told me the session was great, but most of them already knew about Azure, so I guess I never know how good/clear was for someone new to the Windows Azure Platform (if you’re in this category please send me a line). One thing Guadalupe told us, and I guess she was right, is that there’s no point of showing something you can’t use yet… it’s like showing a kid a candy. I don’t know, but one thing I do know is that we could have use the entire conference to talk about Azure :)

On my part of the session I had to show something on ServiceBus so I showed Steve Marx’s AnnoySmarx sample. I changed a few thing from the listener, one thread would never end unless you close the cmd window, and added a few messages for demoing purposes. The sample is pretty cool cause it let you change the wallpaper of my computer by clicking the images from an online web page (in this case hosted on Windows Azure). For my sample I deployed the web app at http://gomezwallpaper.cloudapp.net/ and people from the audience would get online and click on the images while on the main screen you could see the wallpaper of my notebook changing. I was pretty cool and showed how you can get servicebus up & running with a little extra work from what you do to host regular WCF services.

Another tool I used is Windows Azure Storage Explorer which I built myself to browse and manage items from a Storage Account. I recently uploaded the source code to codeplex, the project is here.

Read Full Post