Architecture: Titanium Desktop against the Twitter Streaming API - xmlhttprequest

I'm new to Titanium, and have started out by trying to build a (yet another) Twitter client. The problem I've encountered is that I would like to use Twitter's Streaming API, and I'm struggling to understand the best way to do that within Titanium Desktop.
Here's the options I see:
Don't use the Streaming API, it's not going to work.
Build a Python bridge that connects with a httpclient that supports streaming responses (required for the Streaming API, it never closes the connection). Let that client deliver the responses to a Javascript method that formats and outputs tweets as they come. (Problem here: How do I bundle the python libraries I need?)
Use the Javascript HttpClient shipped with Titanium SDK 1.1 in some clever way I'm not aware of.
Use the 1.2.0-RC2 release of Titanium SDK that ships with a HttpClient that has support for streaming responses. There's very little information in the Release notes to judge if the streaming support is enough to get things working with the Streaming API.
Use twstreamer, a javascript library for streaming support through a Flash intermediary. I've seen bug reports stating the Flash does not work well inside Titanium Desktop, but I'd love to be proven wrong.
Another way that I'm not yet thought of.
I'm hoping for all sorts of clever ideas of how I can get this working, and tips going forward. Thanks for reading!

I'm not at all familiar with Titanium, but looking through their docs your best bet is likely going to be to use Titanium.Process to fork something that can deal with streaming responses. There are plenty of lightweight options here, but note that if you want to use userstreams you'll need an option that supports OAuth and SSL

Here's how to do it (after LOTS of testing):
var xhr = Titanium.Network.createHTTPClient();
xhr.open("GET", "https://stream.twitter.com/1/statuses/filter.json?track=<Your-keyword-to-track>", true, '<Your-twitter-nickname>', '<Your-twitter-password>');
xhr.send();
var last_index = 0;
function parse() {
var curr_index = xhr.responseText.length;
if (last_index == curr_index) return; // No new data
var s = xhr.responseText.substring(last_index, curr_index);
last_index = curr_index;
console.log(s);
}
var interval = setInterval(parse, 5000);
setTimeout(function(){
clearInterval(interval);
parse();
xhr.abort();
}, 25000);

Related

Properly testing an SDK that calls an API

I have an API that I've written and now I'm in the middle of writing an SDK for 3rd parties to more easily interact with my API.
When writing tests for my SDK, it's my understanding that it's best not to simply call all of the API endpoints because:
The tests in the API will be responsible for making sure that the API works.
If the SDK tests did directly call the API, my tests would be really slow.
As an example, let's say my API has this endpoint:
/account
In my API test suite I actually call this endpoint to verify that it returns the proper data.
What approach do I take to test this in my SDK? Should I be mocking a request to /account? What else would I need to do to give my SDK good coverage?
I've looked to other SDKs to see how they're handling this (Stripe, Algolia, AWS), but in some cases it does look like they're calling a sandbox version of the actual API.
(I'm currently working with PHPUnit, but I'll be writing SDKs in other languages as well.)
I ended up taking this approach:
I have both unit tests AND integration tests.
My integration tests call the actual API. I usually run this much less frequently — like before I push code to a remote. (Anyone who consumes my code will have to supply their own API credentials)
My unit tests — which I run very frequently — just make sure that the responses from my code are what I expect them to look like. I trust the 3rd party API is going to give me good data (and I still have the integration tests to back that up).
I've accomplished this by mocking Guzzle, using Reflection to replace the client instance in my SDK code, and then using Mock Handlers to mock the actual response I expect.
Here's an example:
/** #test */
public function it_retrieves_an_account()
{
$account = $this->mockClient()->retrieve();
$this->assertEquals(json_decode('{"id": "9876543210"}'), $account);
}
protected function mockClient()
{
$stream = Psr7\stream_for('{"id": "9876543210"}');
$mock = new MockHandler([new Response(
200,
['Content-Type' => 'application/json'],
Psr7\stream_for($stream)
)]);
$handler = HandlerStack::create($mock);
$mockClient = new Client(['handler' => $handler]);
$account = new SparklyAppsAccount(new SparklyApps('0123456789'));
$reflection = new \ReflectionClass($account);
$reflection_property = $reflection->getProperty('client');
$reflection_property->setAccessible(true);
$reflection_property->setValue($account, $mockClient);
return $account;
}
When writing tests for the SDK you assume that your api DOES work exactly like it should (and you write tests for your api to assure that).
So using some kind of sandbox or even a complete mock of your api is sufficient.
I would recommend to mock your API using something like wiremock and then write your unit tests around that mock API to make sure everything works as desired.
This way when your production app with break, you can at-least make sure (by running unit tests) that nothing broken in your application side but there can be problem with actual API (i.e response format being changed).

Handling of Thumbnails in Google Drive Android API (GDAA)

I've run into the following problem when porting an app from REST API to GDAA.
The app needs to download some of (thousands of) JPEG images based on user selection. The way this is solved in the app is by downloading a thumbnail version first, using this construct of the REST API:
private static InputStream getCont(String rsid, boolean bBig){
InputStream is = null;
if (rsid != null) try {
File gFl = bBig ?
mGOOSvc.files().get(rsid).setFields("downloadUrl" ).execute():
mGOOSvc.files().get(rsid).setFields("thumbnailLink").execute();
if (gFl != null){
GenericUrl url = new GenericUrl(bBig ? gFl.getDownloadUrl() : gFl.getThumbnailLink());
is = mGOOSvc.getRequestFactory().buildGetRequest(url).execute().getContent();
}
} catch (UserRecoverableAuthIOException uraEx) {
authorize(uraEx.getIntent());
} catch (GoogleAuthIOException gauEx) {}
catch (Exception e) { }
return is;
}
It allows to get either a 'thumbnail' or 'full-blown' version of an image based on the bBig flag. User can select a thumbnail from a list and the full-blown image download follows (all of this supported by disk-base LRU cache, of course).
The problem is, that GDAA does not have an option to ask for reduced size / thumbnail version of an object (AFAIK), so I have to resort to combining both APIs, which makes the code more convoluted then I like (bottom of the page). Needles to state that the 'Resource ID' needed by the REST may not be immediately available.
So, the question is: Is there a way to ask GDAA for a 'thumbnail' version of a document?
Downloading thumbnails isn't currently available in the Drive Android API, and unfortunately I can't give a timeframe to when it will be available. Until that time, the Drive Java Client Library is the best way to get thumbnails on Android.
We'd appreciate if you go ahead and file a feature request against our issue tracker: https://code.google.com/a/google.com/p/apps-api-issues/
That gives requests more visibility to our teams internally, and issues will be marked resolved when we release updates.
Update: I had an error in the discussion of the request fields.
As Ofir says, you can't get thumbnails with the Drive Android API and you can get thumbnails with the Drive Java Client Library. This page has is a really good primer for getting started:
https://developers.google.com/drive/v3/web/quickstart/android
Oddly, I can't get the fields portion of the request to work as it is on that quick start. As I've experienced, you have to request the fields a little differently.
Since you're doing a custom field request you have to be sure to add the other fields you want as well. Here is how I've gotten it to work:
Drive.Files.List request = mService.files()
.list()
.setFields("files/thumbnailLink, files/name, files/mimeType, files/id")
.setQ("Your file param and/or mime query");
FileList files = request.execute();
files.getFiles(); //Each File in the collection will have a valid thumbnailLink
A sample query might be:
"mimeType = 'image/jpeg' or mimeType = 'video/mp4'"
Hope this helps!

Flash player API for browser extension

let's say we have a P2P multi-player Flash based game hosted on a website. Would it be possible to create a browser extension that would listen to what is going on within the Flash application? For example, I would like to know when a player connects to a room, gets kicked or banned, or simply leaves by himself. I'm sorry this is not really a specific question but I need a direction to start. Thanks in advance!
I can see a few ways to communicate between Flash and a browser plugin.
One is to open a socket to a server running on the local machine. Because of the security sandbox, this may not be the easiest approach, but if feasible, it is of course probably the one to go for because you've already got your socket-handling code written, and listening/writing to a additional socket isn't terribly complicated. For this approach, you just need your plugin to start listening on a socket, and get the flash applet to connect to it.
Another way might be to try something with passing messages in cookies. Pretty sure this would just cause much grief, though.
Another way, and I suspect this may turn out to be the easier path, is to communicate between Flash and JavaScript using the ExternalInterface class, then from JavaScript to the plugin. Adobe's IntrovertIM example should get you started if you can find a copy on the web.
In Flash, create two functions, a jsToSwf(command:String, args:Array<String>):Dynamic function, to handle incoming messages from JS that are sent to that callback, and a swfToJs(command:String, args:Array<String> = null):Dynamic function, which calls flash.external.ExternalInterface.call("swfToJs", command, args);.
To set it up, you need to do something like:
if (flash.external.ExternalInterface.available) {
flash.external.ExternalInterface.addCallback("jsToSwf", jsToSwf);
swfToJs("IS JS READY?");
}
(The two parameters to addCallback are what the function is called in JS, and what it's called in Flash. They don't have to be the same thing, but it sort of makes sense that they do)
In JS, you need the same functions: function swfToJs(command, params) accepts commands and parameter lists from Flash; and jsToSwf(command, params) calls getSwf("Furcadia").jsToSwf(command, params);.
getSwf("name") should probably be something like:
/** Get ref to specified SWF file.
// Unfortunately, document.getElementById() doesn't
// work well with Flash Player/ExternalInterface. */
function getSwf(movieName) {
result = '';
if (navigator.appName.indexOf("Microsoft") != -1) {
result = window[movieName];
} else {
result = document[movieName];
}
return result;
}
The only fiddly bit there is that you need to do a little handshake to make sure everyone's listening. So when you have Flash ready, it calls swfToJs("IS JS READY?"); then the JS side, on getting that command, replies with jsToSwf("JS IS READY!"); then on getting that, Flash confirms receipt with swfToJs("FLASH IS READY!"); and both sides set a flag saying they're now clear to send any commands they like.
So, you've now got Flash talking with JS. But how does JS talk with a browser extension? And, do you mean extension, or add-on, since there's a difference! Well, that becomes a whole 'nother can of worms, since you didn't specify which browser.
Every browser handles things differently. For example, Mozilla has port.emit()/port.on() and the older postMessage() as APIs for JS to communicate with add-ons.
Still, I think ExternalInterface lets us reduce a hard question (Flash-to-external-code comms) to a much simpler question (Js-to-external-code comms).

Instant Messenger API

I need just a simple Objective-C app or API that can send and receive IMs to a single user.
BARE BONES.
I've looked at Skype, but the Objective-C part looks really outdated. AIM is preferred, but anything that can send and receive IMs is perfect.
Is there an API for this? For AIM or Skype?
Examples would be appreciated, and remember, I'm totally new to Obj-C.
I don't know about simple or bare bones, but Adium is a good open-source IM client for OS X written in Cocoa.
UDPATE: You might want to check out this blog post ("Towards an Open Source XMPP Framework for Cocoa"). It looks like the author wanted his own Jabber/XMPP Cocoa framework, too, and has even created a project for it in Google Code.
I am currently working on an Objective-C implementation of the OSCAR (AIM) protocol. It is being updated on GitHub. If I understand what you want to do correctly, the library, although incomplete, will meet your needs. It can send and receive messages, and work with status messages. It can also read the buddy list if you are interested in that. The entire library should be finished by the end of the month, and you can check it out on GitHub:
https://github.com/unixpickle/LibOrange
Signing on is this simple:
login = [[AIMLogin alloc] initWithUsername:username password:password];
[login setDelegate:self];
if (![login beginAuthorization]) {
NSLog(#"Failed to start authenticating.");
abort();
}
Once signed on, sending messages works like this:
AIMMessage * reply = [AIMMessage messageWithBuddy:[message buddy] message:#"Test"];
[theSession.messageHandler sendMessage:reply];
Obviously, you can check out the sample on GitHub, but I thought I would put that sample code to wet your appetite. Enjoy!
I don't know exactly how hard it would be to use, but isn't there an open source library for accessing IMs called libPurple? maybe you should check that out and see what it can do in Xcode.
If it's for a small scale deployment, it would be pretty easy to roll your own using Distributed Objects. I've heard it can be problematic trying to use DO for a high traffic Internet service though.

Where does node.js fit in a Microsoft / Azure / WCF / MVC project?

I have been working on a real time data project using the Microsoft stack and it seems that node.js is made for this very purpose (of real time data) and is getting a lot of publicity.
Does it makes sense to integrate node.js into my MSFT solution? (what criteria should I be considering)
How does it "hook into" the project?
What components does it replace?
Steve Marx demo'd this for http://chat.smarx.com/
You can see the basic code at http://things.smarx.com/#Run Node.js -
var proc = new Process()
{
StartInfo = new ProcessStartInfo(
RoleEnvironment.GetLocalResource("Executables").RootPath + #"\node.exe",
string.Format("server.js {0}",
RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["HttpIn"].IPEndpoint.Port))
{
UseShellExecute = false,
WorkingDirectory = RoleEnvironment.GetLocalResource("Executables").RootPath
}
};
but I can't currently find a full blog post from him about this
If you like node, look at Nancy for .NET
http://elegantcode.com/2010/11/28/introducing-nancy-a-lightweight-web-framework-inspired-by-sinatra/
As per this episode of Cloud Cover and the Node.js blog it would appear that Node.js is officially coming to Azure (and probably Windows in general).
I wrote a series of blog posts about running node.js on Windows Azure a few months ago (http://bit.ly/gxHawS). However I would offer a similar caveat that while it's theoretically possible, I'm not sure I would recommend it (at this point)...