Saturday, July 21, 2012

Autoretweet from Twitter list

It's finally there!
We've just released new feature for RoundTeam which allows you to automatically retweet from any public Twitter list.

Using this feature you can autoretweet all feed generated by particular list on Twitter. You still can filter it by #hashtags, @mentions, or keywords.

Of course, retweeting from followers, following (those who are followed) and all Twitter is there as always.

More about how to use and configure auto retweet from Twitter list here: http://roundteam.co/faq#faq14

You are welcome to give it a try, it's a big fun :)

Like us on Facebook: http://facebook.com/RoundTeam
Follow us on Twitter: @RoundTeam
Visit our web-site: http://roundteam.co

Sunday, July 8, 2012

Design and implementation pattern

One of my favorite approaches to design and implement new application components is the following:

I start with the public interface of the component, defining how it will communicate with the other app components and external world.

This provides a vision of how future component will be integrated into the application.
Then I continue with writing a skeleton for "business" methods. These methods are usually very high-level, they don't have complicated parsing, validation, operations with DB etc. Usually all such methods are quite declarative and can easily be read. For example:


public function add(Team $team, $allListItemStr) {
$listItemsToAdd = $this->parseAll($allListItemStr);
$listItemsExisting = $this->allByTeam($team);
$newItems = $this->findNew($listItemsExisting, $listItemsToAdd);
foreach ($newItems as $newItem) {
$newItem->setTeam($team);
$newItem->save();
}
}


This is simplified example of one of the components of RoundTeam web-app responsible for adding new list items.

So, I start with writing such skeletons for each public interface method. It helps to identify the workflow of these methods, extract future common helper methods etc. Nothing more is done at this point. Such methods like "parseAll" and "findNew" are not yet implemented.

This process can take several recursive steps in depth when one of the methods used in public interface methods requires invocation of several other methods to work etc.

Once this work is done, full component architecture is visible. How it will communicate with outer world, what is the workflow of the business logic methods etc.

After that I start writing actual low-level code like parsing, DB operations from the very bottom. From the most low-level methods. Those methods can usually be easily unit-tested since they are "atomic" meaning they don't rely on other complex methods etc. Those methods are implemented and covered with unit-tests one by one, level by level, until the most high level business logic methods actually start to work. At that point usually it's also easy to cover them with unit-tests, since all methods they rely on are already implemented and unit-tested.

This approach of course has it's own boundaries, but in general it's quite commonly used in my development.

One of the pitfalls here, is to think in advance about the error handling. How errors are going to be propagated from the low-level methods and influence the behavior of the high-level methods. If one missed this step in the beginning of design phase, there is a risk whole architecture should be re-done in the middle of the implementation stage.

Monday, April 30, 2012

RoundTeam: Objective


Have you ever faced a situation that you'd like to share tweet with particular group of people, but don't want to follow each of them directly on Twitter?

What if you'd like to target your tweets to different Teams, not individual team members? Team is every group of people which has common interest(s), such as classmates, football team, neighbors, ornithologists of New York area, or any other.

Team members may come and leave, however Team stays the same. This is another reason to keep connection to the Team in general, not to each individual team member.

RoundTeam is free autoretweet service, a Twitter application, which invents a concept of a Twitter Team. Team is just an account from Twitter perspective, but it represents an interest or group of interests, not an individual person.

So, there are four simple steps to leverage Twitter in a new way:
  1. Choose existing or create new Twitter account to represent your team.
  2. Add this account to RoundTeam -- free online retweet service
  3. Specify what and from whom to retweet. It can be #hashtag, @mention, or just a keyword.
  4. Invite people to follow your Team on Twitter
Now every time there is new tweet on Twitter which matches the criteria of the Team, this tweet will be automatically retweeted. Thus all Team followers will see this tweet in their Twitter timeline (or even get an SMS on their cell phone).

Some of the benefits of this approach:
  • No need to follow each team member directly. Individuals may join and leave, commmunity tweets are still delivered to those who are interested.
  • This is better than Twitter "saved search" because saved search cannot send SMS to your mobile device once new tweet is available. Also saved search is something that each team member have to configure on their accounts.
RoundTeam mission is to create communities on Twitter. Such an islands of precisely targeted tweets in the world ocean of Twitter data.

Visit RoundTeam at http://roundteam.co

Sunday, November 20, 2011

Twitter @Anywhere and PHP Symfony. Implementing login action

While playing with the Twitter @Anywhere and PHP Symfony I have implemented "Sign in with Twitter" method for RoundTeam app (http://roundteam.co).

How it was done:

Creating a placeholder to represent "Sign in with Twitter" button.
mainpageSuccess.php:
<span id="login" class="twit_login">Sign in with Twitter</span>
I am not going to describe CSS part here.

Enabling Twitter connection using @Anywhere
javascript (rt.js):
$(document).ready(function() {
    twttr.anywhere(function(T) {
        $("#login").bind('click', function () {
            T.signIn();
        });
    }
Now when user clicks on "Sign in with Twitter" button he will be prompted to login using Twitter credentials. On this step "twitter_anywhere_identity" cookie is created (more details about this cookie and how to interpret it on server side see here: https://dev.twitter.com/docs/anywhere/welcome).

Okay, now we need to notify server that login has happened.
Here is one of the ways to implement this using PHP Symfony:

routing.yml
rt_get_user:
  url: /rt/user
  param: {module: connect, action: user}

action.class.php (for module "connect"):
public function executeUser(sfWebRequest $request) {
$cookie = $request->getCookie('twitter_anywhere_identity');
$this->logMessage('got auth request');
if ($cookie) {
$twitter_data = explode(':', $cookie);
$userId = $twitter_data[0];
$secret = $twitter_data[1];
$calculatedSecret = sha1($userId.RoundTeam_auth::SECRET);

if ($secret === $calculatedSecret) {
$this->logMessage('secret verified');
$userJson = $request->getParameter('user');
if ($userJson) {
$this->logMessage('user found!');
$user = json_decode($userJson);

$this->data = $user;

$this->logMessage($userJson);

$screenName = $this->data->screenName;
if (TeamTable::getInstance()->exists($screenName) == false) {
$this->logMessage('authenticated: '.$screenName);
$this->getUser()->signIn($this->data);
} else {
$this->logMessage('Failed to login using team: '.$this->$screenName, 'err');
}
} else {
$this->logMessage('user not found');
}
}
}
$this->redirect('@rt');
}

The last step is to post user data to server and reload page:

T.bind("authComplete", function (e, user) {
        post('rt/user', {user: JSON.stringify(user)}, function(response) {
        location.reload();
    });
});

That's it. Now user may login using his twitter credentials without leaving the round-team.com page. User data is passed to server and server authenticates user to enter.

It means that user stays logged in on both client side and server side. That said when you implement logout don't forget to log out user from server side:
$this->getUser()->setAuthenticated(false);
and client side:
twttr.anywhere.signOut();

Complete js code listing may be found on http://round-team.com

Saturday, April 2, 2011

Mozilla Firefox -- getting Social

Let me share my experience of how to make Mozilla Firefox more "social" browser. So it will keep you up-to-date with your communication channels, like social networks, mail accounts, news feeders etc.

Twitter, Facebook, LinkedIn

Yonoo plug-in for Firefox keeps me connected. Some features:
  • All updates in one line -- no more different tabs of several lines of updates. Twitter, Facebook, YouTube, LinkedIn and many other instant messengers/social networks feeds are listed in one place (being still distinguishable)
  • Minimum extra space -- when collapsed it costs me one small column to the left of the browser window. I use 11'inch laptop for my daily work, so, being concerned about every pixel, I am totally fine with this size
  • Simple yet flexible user interface
  • Amount of new items is shown even if main view is collapsed
  • Pop-up notifications in bottom-right corner of browser (may be turned off)

Google reader

I use Google Reader Watcher to stay updated with the latest news. Be careful not to install this plug-in instead.

What I don't like about this plug-in is that it is located in status bar thus not visible in full-screen mode. Well, it's still better than open a new tab.

Gmail

Have a look at Gmail Watcher. The only Gmail Firefox add-on which is installed into navigation bar (not status bar). Also, it doesn't require to enter login/password.

These add-ons all together provide me constant connectivity to the community.

If you have other cool socializing Firefox add-on to share -- please comment on this post!

Thursday, March 31, 2011

Yet another "Like" button

Google has introduced own Facebook-"Like" button named "+1".
Yet another "+1" button...

Have a look at the article on CNN.com announcing it:
http://money.cnn.com/2011/03/30/technology/google_button/index.htm

It has 9(!) links with partially duplicated functionality to share this article.
With Google's it will be 10. Too many, as for me. How do you think?

Also considering various integrations supported by many social applications like
Facebook <-to-> Twitter <-to-> LiveJournal <-to-> LinkedIn <-to-> Facebook -- for more and more people that becomes irrelevant to make this choice. Because any choice will produce the same result. I do not see any reason for this number of "like and share it" links. That amount produces minimum value for end-user (read contributors) and noises web-pages.

However that's a political move, that's clear. That's pity that companies like Google always being thinking about the end-user first start to produce things which are good for Google, less for googlers.

Tuesday, March 29, 2011

Java 7 support in IDE's

Eclipse versions up to 3.6 (Helios) do not support Java SE 7 features completely.
I have installed JDK 7 on Ubuntu laptop, however this is not possible now programming using it within Eclipse.

Java 7 support is expected in the next Eclipse release which 3.7 aka Indigo planned for June 2011.

IDEA update 10.5 planned for Spring 2011 will include Java 7 support.

And of course, Java 7 is already supported in NetBeans. Are you surprised?..