If you’re using Bitbucket together with Jira, you can easily resolve a ticket in Jira by adding a #resolve in your commit comment in Bitbucket. You can resolve multiple tickets, too; just add each ticket number per line with a #resolve right next to it, for example:

JCSW-561 #resolve
JCSW-560 #resolve
JCSW-559 #resolve
JCSW-558 #resolve
JCSW-557 #resolve
JCSW-549 #resolve

You’re welcome.

Scott Guthrie:

As part of this commitment I am pleased to announce today that Microsoft has signed an agreement to acquire Xamarin, a leading platform provider for mobile app development.

I expected this the moment Microsoft open-sourced .NET back in November 2014. I am actually surprised that it took them more than a year to do this. I think it’s a great move to expedite the adoption of .NET outside Windows. I suspect that Xamarin will be merged into the Visual Studio brand to avoid confusion amongst developers.

GMA Network will be covering the first leg of PiliPinas 2016 Debates today in Cagayan De Oro:

PiliPinas Debates 2016 is a debate show developed by the Commission on Elections (COMELEC). This will be the first COMELEC organized debate show in preparation for the May 9, 2016 general elections.

You can live stream the debate from Youtube. If you have a Chromecast, you can stream it directly to your television using the Google Cast plugin in Google Chrome. If you have an Apple TV, you can use Safari to Airplay the live stream to your television.

Alternatively, you can use the Youtube app which supports both Airplay and Google Cast.

If you’re a technology news junkie like me, you probably keep a list of tech news sources. Here’s my personal list of local technology news sources (independent blogs, local news outlet) that I have been collecting through the years.

ABS-CBN News | Gadgets and tech Site
GMA News Online / SciTech / Technology, Gadgets and Gaming RSS Site
Inquirer Technology^ RSS Site
mb.com.ph | Philippine News >> Technology RSS Site
MobileTechPinoy RSS Site
Newsbytes Philippines RSS Site
Rappler: Technology RSS Site
TechInAsia RSS Site
Techolo – Philippine Technology Outlook Blog RSS Site
Webgeek Philippines RSS Site
YugaTech | Philippines, Technology & Reviews RSS Site

I have included the RSS links for the old fogeys like me. I still enjoy my news in my favorite feed reader and coffee. Happy reading.

Inc. Southeast Asia:

2. Do not hire your best friends as employees
“Building a company with your good friends is a very good idea if everybody is equal,” Trikalitis says.
This does not apply to co-founders, but to hiring close friends as your employees. The moment best friends enter into a boss-employee setup, the working relationship becomes complicated. In friendship, you’re equal, but now, your friend has to report to you. And because the two of you had an existing bond, it becomes difficult to draw the lines between friendship and work.

“And that is how friendships fall apart, and can never be mended again,” she says.

In Out There Media, this has happened about three times already, Trikalitis shares. And in those instances, people who used to be good friends have now stopped talking to each other.

Trikalitis adds, “So it is better to keep your good friend, and hire a professional or a person that might be some friend and a professional, but not one of your best friends.”

Two of my very close friends are working for me and are doing a fantastic job. We have great relationship that is mutually beneficial both personally and professionally. It’s not a walk in the park, of course. It’s a combination of setting the correct expectations and having a mature mindset to make it work.

Have the “talk” with them. First things first. Before getting them on board, make sure to be upfront about working professionally would mean acting differently with each other. Make them accept that uncomfortable situation is part of the relationship.

Always wear the right “hat” when interacting with them. Around work environment, your main objective is to get things done, nothing personal. If you stick with this philosophy, working with them will be smoother: you do not have to worry on accidentally hurting their feelings. When socializing with them outside work, be mindful of your actions. Never boss around.

Show them why they should respect you as a colleague. Friends can act comfortably around each other because they usually don’t care what each other does–which is great. However, inside the office, show them that you mean business. Show them how good you are with what you do. They’ll respect you for that and further improve your relationship.

Angela Lee Duckworth’s “The Key to Success? Grit” Ted talk is one of my all time favorites:

Huffington Post wrote an article referencing Duckworth’s work:

Developing grit is all about habitually doing the things that no one else is willing to do. There are quite a few signs that you have grit, and if you aren’t doing the following on a regular basis, you should be.

Good read.

Here’s a good litmus test to determine how seasoned a developer is: ask him to design a method that is conditional clause heavy. Most developers will instinctively resort to arrow code: the excessive nesting of conditional clauses which pushes the code out into an arrow formation. Coding Horror has a good rundown of the problem and some tips to minimize it.

And you know you’re definitely in trouble when the code you’re reading is regularly exceeding the right margin on a typical 1280×1024 display

Guard clause is the most important concept to mitigate arrow code. Most developers are unaware how important it is. First, as explained in the article, it minimize convoluted conditional clauses (cyclomatic complexity). Since they act as sentry points, you can make sure that parameters are satisfied first before moving to the next line of code. Succeeding code can execute with a privilege that variables will always be present, no checks needed (thus reducing additional conditional clauses). Second, it creates a clean and elegant method anatomy: guard clauses, purpose of the method, and return. This makes the method self-documenting and predictable. This also allows you to plan usage of resources, which brings me to my third and last point: efficiency. Resources will only be spent when they are actually needed.

 

 

Coding Horror:

Don’t feel inadequate if you aren’t lining your nest with the shiniest, newest things possible. Who cares what technology you use, as long as it works, and both you and your users are happy with it?

That’s the beauty of new things: there’s always a new one coming along. Don’t let the pursuit of new, shiny things accidentally become your goal. Avoid becoming a magpie developer. Be selective in your pursuit of the shiny and new, and you may find yourself a better developer for it.

There’s a shittier variation of the magpie developer: the one who keeps moving on to the next shiny object without even learning the fundamentals. They’re just in it to tickle their fancy, not to get things done. Stay the hell away from them.

Outside local news (and occasional live sport event), I get most of my video content from the Internet. Through the years there has been a steady uptick of video content from the Internet . Most of the contents are foreign, however, so when a Netflix clone became available, it was a no-brainer for me. iflix is a video on-demand service mainly targeted to Southeast Asia (currently only in Malaysia, Philippines and Thailand).

I’ve been trying iflix for more than a month now. If you are experimenting on the idea cord-cutting or just looking for an alternative way to get more video content, read on.

Things they got right

Streaming. I was pleasantly surprised with iflix’ streaming stability. The Philippine broadband situation is shitshow right now; however, iflix’ adaptive bit-rate streaming—video quality changes depending on the quality of bandwidth of connection—actually makes a difference. I can watch any movie in any device with almost zero hiccup. I have a 2MBps connection in my house, and it holds up pretty good. Streaming over cellular data is decent. The videos stream almost flawlessly as long as you’re on 3G or higher.

Price. iflix has an aggressive pricing of P129 per month. This is a third of the average cost of a cable monthly subscription. This is dirt cheap: a single movie rental in Apple App Store or Google Play Movies ranges between P200-P600. To put it in another perspective, if you watch re-runs of a TV show like Friends or How I Met Your Mother, you could purchase a USB hard drive to store videos. Assuming that obtaining the videos does not cost you anything, you’re out at least P 3,000 for the hard drive alone. The same amount of money can be for a 2-year iflix subscription. Again, dirt cheap.

Things they need to improve

Technology. This is where things go south. iflix has mobile and web apps; the mobile apps are, I believe, web apps wrapped with a native shell. Like most non-native mobile apps, they are buggy and kludgy.

  • General navigation. The mobile app’s navigation is plagued by slow performance. For example, tapping a movie does not instantly bring you to the next screen. Additionally, pressing the back button shows the previous screen and a progress indicator at the top bar until target screen is loaded. The scrolling is not buttery smooth and doesn’t have inertial scrolling. The search experience is also something to be desired. Tapping the search icon exposes a slow, sometimes unresponsive, webpage-like experience. These are all symptoms of a web app dressed as a native app.
  • Screen projection. I’ll be honest, this is the main reason why I purchased the service. Sitting back on your couch, picking up any movie and watching it on a big screen anytime of the day is very appealing to me. iflix almost got it right. It supports both Chromecast 1 & 2. I can project to any of these devices with zero issues. However, it does not support Google Cast enabled devices such us Google Nexus Player. Unlike Google Cast implementation like Spotify where it hides unsupported devices, iflix embarrassingly brings up unsupported devices in its app only to flake out when you stream the video. It does not support AirPlay. No, projecting your desktop to Apple TV doesn’t count.

Content Selection. If you are looking for fresh content, iflix is not for you. Do not expect the latest episode of Arrow or The Big Bang Theory here. However, if you enjoy watching reruns (like I do), that’s where the real value comes in. iflix is geared toward this: catching up shows you missed or binge watching an entire season of a show. The movies are also slim pickings. According to this FAQs they update their movie catalog in a weekly or monthly basis; however, I would imagine that their movie catalog, at best, is a few thousand.

Should you get it?

If you have a decent internet connection without aggressive capping you should get it. Despite my disappointments, it’s hard to say no to because of its price.

I’ve a side project that has been put on hold for a while and I decided to pick it up last week. It’s a small, two-part web app. One part pulls data from Twitter.

In order to make authorized calls to Twitter API, an application must first obtain access tokens from Twitter. There are two ways to do this: OAuth access tokens in behalf of the user or Application-only Authentication. I pondered on writing my own full-pledge OAuth client library but it’s an overkill for my requirements. I settled on Application-only Authentication.

Writing a client library for Twitter sounds fun and cool until you actually do it. It’s meticulous and finicky. In fact, scouring the Internet for a working code was a fruitless endeavor.  Half of my Internet searches yielded half-baked answers. The other half suggested that I should just use third-party libraries which I was adamant about—I don’t want to miss the opportunity to learn in this project. Desperation led me to Twitter’s documentation: I have to do everything from scratch without any help from StackOverflow.

I use HttpClient for everything that’s HTTP—API call, file upload, etc.—it provides better granularity when sending and receiving HTTP requests and response, respectively. Despite using HttpClient for a while now, using it for OAuth tested my patience. Letting an API specification dictate my code is not fun at all and mostly trial-and-error. To make things worst, the errors are often cryptic or vague.

Several hours later, I was able to pull together a working build. Application-only Authorization is comprise of three parts: preparing your keys, retrieving the bearer token and sending actual API call.

Preparing Your Keys
Application-only Authentication has a limitation: it does not have user context so it has a few limitations. However, contrary to what most developers believe, it’s often suffice to most situation. Here’s how to prepare consumer key and consumer secret key when sending an HTTP request (excerpt from Twitter):

  1. URL encode the consumer key and the consumer secret according to RFC 1738. Note that at the time of writing, this will not actually change the consumer key and secret, but this step should still be performed in case the format of those values changes in the future.
  2. Concatenate the encoded consumer key, a colon character “:”, and the encoded consumer secret into a single string.
  3. Base64 encode the string from the previous step.
    var encodedConsumerKey       = HttpUtility.UrlEncode(_ConsumerKey);
    var encodedConsumerKeySecret = HttpUtility.UrlEncode(_ConsumerKeySecret);
    var encodedPair              = Base64Encode(String.Format("{0}:{1}", encodedConsumerKey, encodedConsumerKeySecret));

Retrieving Bearer Token
This is where I did a lot of trial-and-error. Preparing and sending the request requires a good understanding of how HTTP requests work. Converting that knowledge to .NET/C# is challenging if you’re inexperienced.

  • The request must be a HTTP POST request.
  • The request must include an Authorization header with the value of Basic <base64 encoded value from step 1>.
  • The request must include a Content-Type header with the value of application/x-www-form-urlencoded;charset=UTF-8.
  • The body of the request must be grant_type=client_credentials.
    var requestToken = new HttpRequestMessage {
        Method      = HttpMethod.Post,
        RequestUri  = new Uri("oauth2/token", UriKind.Relative),
        Content     = new StringContent("grant_type=client_credentials")
    };
 
    requestToken.Content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded") { CharSet = "UTF-8" };
    requestToken.Headers.TryAddWithoutValidation("Authorization", String.Format("Basic {0}", encodedPair));

Making the Actual API Call
This is the easy part. Once you have the bearer token, just add an `Authorization` header to the request with the bearer token as its value and do a `Post` call.

    requestData.Headers.TryAddWithoutValidation("Authorization", String.Format("Bearer {0}", bearerToken));
 
    var results = await HttpClient.SendAsync(requestData);
    return await results.Content.ReadAsStringAsync();

Here’s the full working method:

        public override async Task Post(string path, HttpContent content) {
 
            var bearerToken = await GetToken();
 
            if (bearerToken == null || bearerToken == string.Empty)
                throw new Exception("Bearer token cannot  be empty");
 
            var requestData = new HttpRequestMessage{
                                    Method      = HttpMethod.Post,
                                    Content     = content,
                                    RequestUri  = new Uri(path, UriKind.Relative),
                                };
 
            requestData.Headers.TryAddWithoutValidation("Authorization", String.Format("Bearer {0}", bearerToken));
 
            var results = await HttpClient.SendAsync(requestData);
            return await results.Content.ReadAsStringAsync();
        }
 
 
        private async Task GetToken() {
 
            if (_ConsumerKey == null || _ConsumerKey == string.Empty)
                throw new Exception("No Consumer Key found.");
 
            if (_ConsumerKeySecret == null || _ConsumerKeySecret == string.Empty)
                throw new Exception("No Consumer Secret Key found.");
 
            var encodedConsumerKey       = HttpUtility.UrlEncode(_ConsumerKey);
            var encodedConsumerKeySecret = HttpUtility.UrlEncode(_ConsumerKeySecret);
            var encodedPair              = Base64Encode(String.Format("{0}:{1}", encodedConsumerKey, encodedConsumerKeySecret));
 
            var requestToken = new HttpRequestMessage {
                Method      = HttpMethod.Post,
                RequestUri  = new Uri("oauth2/token", UriKind.Relative),
                Content     = new StringContent("grant_type=client_credentials")
            };
 
            requestToken.Content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded") { CharSet = "UTF-8" };
            requestToken.Headers.TryAddWithoutValidation("Authorization", String.Format("Basic {0}", encodedPair));
 
            var bearerResult    = await HttpClient.SendAsync(requestToken);
            return JObject.Parse(await bearerResult.Content.ReadAsStringAsync())["access_token"].ToString();
        }
 
        private static string Base64Encode(string plainText) {
            var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
            return System.Convert.ToBase64String(plainTextBytes);
        }