jump to navigation

Discontinuing TripTao April 4, 2014

Posted by CK in Internet, Personal.
Tags: ,
1 comment so far

It’s almost funny that in between the post where I announced the availability of triptao, and this one where I announce shutting it down 11 months later, there have been only two more posts. I guess this reflects, with fair accuracy, the crazy ride of these 11 months.

So I “dreamt laughably big and took an absurdly huge risk or two” as the advice went — and it didn’t pay off as I expected. It wasn’t bad, but I didn’t have enough excuse to keep pushing it.

To be exact: it didn’t pay off as I expected materially; I feel I’m coming out of this being a much better person, in many respects.

  • I now have a better grasp of my limits — and it appears I can do much more than I thought myself capable of doing. The same, I’m perfectly certain, applies to everyone else. We should be less scared and more receptive to the possibility that we can do anything we think of.
  • I got back in touch with the technical side of things and remembered how much I enjoyed it. These have been very creative days.
  • I’ve learned a great deal of things on multiple levels. Somehow I feel I’m much better equipped for the next tasks, both technical and managerial/business.

I also got some lessons that concern specifically the area of online startups.

  • Unless you are Superman, you can’t do something like this alone. Make sure you have a co-founder.
  • Whatever you do, don’t rely on others for your data. Make sure you have full control on it (even if you don’t explicitly own it).
  • If you’re doing B2C, the added value should be instantly and fully evident to anyone who visits your site. With TripTao, I had to explain. You should not have to explain.
  • Marketing is king. You can’t underestimate its importance, no matter how great a product you have.

Now, coming back to that advice mentioned earlier, it says “take an absurdly huge risk or two“. Who am I to discard such interesting advice?

The journey continues with a new trip. More to follow in the next months.

promees.es — a weekend’s experiment October 15, 2013

Posted by CK in Networking, Research, Software.
Tags: , ,
add a comment

There is this concept I have been thinking about for quite some time now, and this weekend I got around to kicking off its development. There are additional things I want to implement for it, but in its current form it is probably ok to publicize. So here’s the idea: People make promises constantly. “I’ll fix this for you”; “Sure, I’ll review your work”; “I’ll take you on a holiday”; you get the drill. People are judged by how good they are keeping their promises. Abiding to your promises is, in real life, one of the main reasons why others respect you.

Another thing happening in real life is that this respect is communicated in private conversations. But what would happen if people were able to advertise an index of their capability to hold on their promises? Would this be of value to their peers? This site is an experiment to figure out such questions, using Facebook as a platform.

promees.es

Feel free to give it a try at promees.es and get back to me with thoughts/comments you may have (keeping in mind that it was built in 3 days or so, so dont’ be harsh!).

Sunday 5:30am fun with XHR, XSS, HTTPS and (session) cookies September 8, 2013

Posted by CK in Software.
Tags: , , , , , ,
add a comment

Ok at this time of the day there’s not much energy left, but having spent the day trying to figure this out, I decided to take a few minutes and write about it.

The use case is as follows:

  1. Browser is on HTTP page, instructed to make XHR to foo.example.com over HTTPS to authenticate (end goal to receive session cookie)
  2. Browser continues making all other requests to bar.example.com over HTTP using this session cookie.

Seems like business as usual. Same 2nd-level domain, should just work. Not really. Steps to take if you find yourself in the situation:

You will find that due to XSS and browsers setting extra request headers, or maybe because you are using application/xml or application/json content type in a POST request, you will probably need to add CORS support to your backend: Browsers will issue a pre-flight request with the OPTIONS verb. You can add the following headers to your response to this OPTIONS request:

Access-Control-Allow-Origin: *,
Access-Control-Allow-Methods: GET, POST,
Access-Control-Allow-Headers: X-Requested-With

Check if you need to allow headers other than X-Requested-With, but usually this should work for the specific task. Also, you may want to set Access-Control-Max-Age too. These response headers will allow the browser to continue with the GET or POST to authenticate.

It was an unpleasant surprise to see that, although a session cookie was returned successfully after enabling CORS, the browser would ignore it in followup XHRs over HTTP. It turns out there are two more things you need to do:

  • Add withCredentials: true in your XHRs (not sure if only the one over HTTPS needs to have it or every one, including followup over HTTP, I used it everywhere for now)
  • Add Access-Control-Allow-Credentials: true in your CORS setup from above.

Bonus: If you are using Angular.js you will need to put withCredentials configuration in the $http config object for 1.0.x, otherwise you can set it permanently on $httpProvider defaults for v1.1.1+ — see here.

Scratching one’s itch: A post long due May 11, 2013

Posted by CK in Personal, Travel.
Tags: ,
1 comment so far

In December 2011 I read an article by Umair Haque containing the following excerpt:

Create (something dangerous). Mediocrity isn’t a quest to be pursued — but a derelict deathtrap to be detonated into oblivion. Hence, I’m firmly of the belief that your youth should be spent pursuing your passion — not just slightly, tremulously, haltingly, but unrelentingly, with a vengeance, to the max and then beyond. So dream laughably big — and then take an absurdly huge risk or two. Bet the farm before it’s a ranch, a small town, and an overly comfy place to hang your saddle and your hat. Create something: don’t just be an “employee,” a “manager,” or any other kind of mere mechanic of the present. Be a builder, a creator, an architect of the future. It doesn’t matter whether it’s a sonata, a book, a startup, a financial instrument, or a new genre of hairstyles — bring into being something not just fundamentally new, but irrepressibly dangerous to the tired, plodding powers that be. Think about it this way: if your quest is mediocrity, then sure, master the skills of shuffling Powerpoint decks, glad-handing beancounters, and making the numbers; but if your quest, on the other hand, is something resembling excellence, then the meta-skills of toppling the status quo — ambition, intention, rebellion, perseverance, humanity, empathy — are going to count for more, and the sooner you get started, the better off you’ll be.

Whether I’m still in my youth is debatable, but two months later I resigned from my great job at the time to pursue a dream: Solving a small but real-world problem I had faced myself. There were many reasons why I didn’t start earlier, but at that point I just couldn’t ignore this sentence anymore: “So dream laughably big — and then take an absurdly huge risk or two’‘. It sounded like the right thing to do.

A few words about the motivation: It’s Spring of 2010 and soon I will travel to Madrid for a business meeting. It’s my first time there, and the meeting venue is on the city’s border in some business area with nothing to do but meetings. So I want to stay not too far from the meeting, but also not too far from the city center so that I can do some sightseeing if I get the time, or simply have a nice dinner. I will be using public transport, so I need to stay close to a subway stop. The hotel needs to be reasonably good and inexpensive (hey, I was working for a university at the time). And all that is before I start thinking about typical filters such as non-smoking rooms, wifi, breakfasts, etc. You get the drill: Madrid has hundreds of hotels, and even after applying all easy filters, I was left with more than 100 to check. It took the better part of a Sunday. Not pleasant.

The solution took longer than expected, but eventually the foundation is here: triptao.com promises to solve this problem, applying fancy math to hotel availability and geographical data. This is done using the excellent content of Booking.com, of whom TripTao is now an affiliate. Are you visiting London with its 800+ hotels? TripTao will filter them for you and show you a list in the range of 100 hotels. This is not fixed and depends on many factors, but that’s a typical reduction. I argue that if you would go through all 800+ hotels, eventually you would choose, anyway, one of those that TripTao will show you. Not only that: The ranking algorithm is also fairly sophisticated, and doesn’t take commission into account. The first result(s) to show is really those it considers to be the best. Usually, people will find their ideal hotel within the first 10 properties shown.

Now, this is not quite finished yet. Scaling down ambition was necessary to kick-off but the vision is still grand. Now that the first step is done, little by little it will get there. There are a lot of improvements in the pipeline, lots of new features planned, lots of ideas to research and implement. Hopefully triptao.com will eventually become the default go-to hotel search platform for plenty of people, and save a few Sundays for them too.

Dispatch with Scalatra on AsyncServlet January 15, 2013

Posted by CK in Software.
Tags: , , ,
3 comments

A basic example of using Dispatch with Scalatra on Jetty 8.x / AsyncServlet 3.0. It took me a lot of time to connect the dots how to use Dispatch asynchronously and actually process the results (not simply return them) and I could not find examples how to use Scalatra with AsyncServlet either. So here it is for anyone who could find it useful and save themselves a few –or more– hours.

import _root_.akka.dispatch._
import _root_.akka.actor._
import org.scalatra._
import org.scalatra.akka.AkkaSupport
import dispatch._

get("/asynctest") {

    // Get the AsyncContext -- or create one.
    val asctx = 
        if (request.isAsyncStarted) request.getAsyncContext 
        else request.startAsync
    // Execute the rest of the route in an Akka Future
    val result = Future {
        // Create a RequestBuilder to be used by Dispatch
        val url = host("slashdot.org") <:< Map(
                    ("Accept-Charset" -> "utf-8")
                )
        // Make the request, receive it as Bytes not to
        // disturb binary results. Http returns a Promise
        // to a result and execution moves along. More
        // information on the concepts is provided on
        // the Dispatch web site.
        val response = dispatch.Http(url OK as.Bytes)

        // Set up a handler for Dispatch' return. This
        // is bound on the Promise created earlier.
        response.onComplete { x =>
            // Get a handle to the response and its
            // output stream, we'll need this to write
            // results as soon as we have them.
            val res = asctx.getResponse
            val os = res.getOutputStream
            // 'x' is the response of the upstream web
            // service
            x match {
                // An error occurred, the exception is
                // sent to the client (of course you
                // would prefer to handle this otherwise
                // in real-world code)
                case Left(exc) => {
                    os.print(exc.getMessage)
                }
                // Response was received with a 200 HTTP
                // code, everything went fine. Data is
                // written to the output stream as bytes,
                // after having set the encoding to UTF-8.
                case Right(output) => {
                    res.setCharacterEncoding("utf-8")
                    os.write(output)
                }
            }
            // It is crucial to "complete" the Asynchronous
            // Context, otherwise no response will be sent
            // to the client.
            asctx.complete
        }
    }        
}

Big fat disclaimer: I’m fairly new to Scala/Scalatra (and the JVM for that matter), so if there are mistakes in this example –or improvements to make– let me know and I’ll correct them in the post.

Update: Ivan Porto Carrero of the Scalatra fame comments below on a much easier/concise way to achieve the same result (minor edits of my own in the code that follows but the point is the same). So it turns out you can call .complete directly on an Akka Promise, without a need to move the servlet’s asynchronous context around:

get("/async2") {
    import dispatch._
    import _root_.akka.dispatch.{Promise => AkkaPromise}

    val prom = AkkaPromise[String]()
    Http(host("slashdot.org") OK as.String) onComplete {
        case Left(ex) => println(ex.getMessage)
         case r => prom.complete(r)
    }
    prom.future
}

A new start February 14, 2012

Posted by CK in Personal.
Tags: , , ,
10 comments

On early October 2010 I started working with Exodus S.A. in Athens, Greece, following my return from Germany. I was appointed as the coordinator of NEPHRON+, a multi-million, high-risk, ambitious EU research project aiming to help End-Stage Renal Disease (ESRD) patients with a wearable device for 24×7 haemodialysis. This period was challenging (moving in a completely new domain) and rewarding every time we achieved some next step towards this great vision. I feel grateful that I was given the chance to be part of this amazing consortium and I wish them the best of luck in the remaining two years of the project.

Tomorrow I’m stepping down from that position, ready to start chasing one more dream. I have an itch on my back that I need to scratch, it’s been there for a couple of years now and it just won’t go away. The time is far from ideal to start a company, but hey — no pain, no gain.

So wish me luck, and stay tuned for more information in the near future!

A short poll December 2, 2011

Posted by CK in IT.
7 comments

I’m doing a 1-question poll. Let’s assume you can get the following web-based services, all under your own full control (domain name, private data –not “in the cloud”–, possible to export, etc):

  • Intuitive wiki system supporting WYSIWYG editing and file attachments;
  • TODO list management (specifically: GTD-based), possibly with Android/iPhone integration;
  • Bookmarks management a la del.icio.us (without the social features);
  • Standards-based calendar and address-books, that can be integrated with your desktop PIM (Thunderbird+Lightning for sure) or used over a web interface;
  • Your own non-relaying private mail server (incoming + outgoing) with encryption/authentication, anti-spam controls, and Ajax-based webmail;
  • Possibly a dropbox-like service;
  • …and a popular, easy to use CMS for your personal web site.

All of that in a 1st-class data center with power and network redundancy.

The question is: Would you be interested in that as a commercial (managed) product, and how much would you be willing to pay per month, including email-based support?

Thanks in advance for your feedback!

Update: Just to clarify, this would be addressing privacy-concerned individuals; it is not meant to target large commercial entities, who require different levels of support and integration anyway.

Function references in Scala October 17, 2011

Posted by CK in Software.
Tags: , ,
add a comment

I’m starting to learn Scala, and have some trouble coming to terms with its syntax. Maybe I’m spoiled by Python. In any case, here’s an example of things that I find annoying:


scala> def f(x:Int):Int = x
f: (x: Int)Int

scala> def g(f:Int=>Int, y:Int, b:Boolean):Int = if (b) g(f, y, false) else y
g: (f: (Int) => Int,y: Int,b: Boolean)Int

scala> def h=f
:6: error: missing arguments for method f in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
def h=f
^
scala> def h=f _
h: (Int) => Int

So basically, although it is fine to use just f when defining function g, in the definition of function h it is necessary to postfix f with an underscore.

I haven’t read the language reference yet, and there may be good reasons to do it like this (although I can’t think of any right now), but the inconsistency is quite confusing.

Looking for VPS provider June 22, 2011

Posted by CK in IT.
Tags:
1 comment so far

The home server project is more or less over, following a power outage today. I’d be very willing to keep it always on, but if I’m to use this as a service to rely upon, I have to get such disruptions out of the way. So I’m looking for an unmanaged VPS provider, who should a) be relatively cheap, b) be relatively reliable (three 9s would be nice), c) have a/the data center in Europe, d) offer Xen with plans between 512 and 768 MB guaranteed RAM and e) allow me to install the system myself or accept ready-made images, so that I can have the disk data encrypted.

If you know of such a provider, please leave a comment here or reply on twitter at @ckotso — thanks.

My personal little “cloud” May 24, 2011

Posted by CK in Internet, Productivity, Software.
Tags: , ,
2 comments

Here it is, and it works perfect:

  • You will need a VPS or a home server. I’m using the wonderful, fan-less Shuttle XS35GT with a small SSD, as it is also my HTPC
  • A Linux distribution. I very highly recommend Mint 10 if you’re using the XS35GT so that you get a working audio + wireless and a stable XBMC, otherwise you may wish to use an LTS release like Ubuntu 10.04 or Mint 9.
  • An installation of eGroupware, to use its addressbook and calendar modules with its GroupDAV and SyncML synchronization facilities. You can easily install eGroupware using the deb repository provided on the project’s site.
  • Thunderbird, Lightning and the SOGo connector to support GroupDAV. Make sure you don’t use the “SOGo Lightning” extension; at least for me it didn’t work. Then subscribe Lightning to the eGroupware calendar and addressbook. Don’t bother with TODO items, unless a flat list is your thing.
  • A SyncML application to synchronize your phones. My Nokia E71 comes installed with one, while on an Android you can use the wonderful Synthesis client. Synthesis offers clients for additional platforms, but I only tried the one for Android.
  • The amazing Tracks application for GTD. It takes some effort to install, but it is totally worth it. You can also subscribe Lightning to various views of Tracks exported calendars. I’ve subscribed only to the one for due items, so that they appear with deadlines in my calendar. There are also two mobile applications to sync with Tracks, one for the iOS and one for the Android. Unfortunately the latter doesn’t work yet with Tracks 2.0, but it looks like it’s only a matter of time before it does.
  • …and, finally, Mindtouch Core (DekiWiki) as my data sink. There’s also a for-pay version, but I’m using the free/open-source one, which is fine. It’s also installed via a deb repository. I guess others may prefer some other platform, but for me Deki is perfect.

Then, your router set to post its address to DynDNS/No-IP or a similar service, and some CNAMEs in your domain to point to the hostname you have chosen (or simply the address of your VPS). All three services (Mindtouch, Tracks, eGroupware) are powered by Apache2, on virtual servers over HTTPS.

The data is yours!

PS: Special thanks to Yannis for suggesting to use eGroupware instead of SOGo+Funambol. A great improvement, indeed.
PPS: I only accept IaaS to fall under the term “cloud computing”, hence the quotes in the title.

Follow

Get every new post delivered to your Inbox.

Join 242 other followers