La Vita è Bella

Tuesday, January 01, 2019

Play with LIFX Tile devices

Over the last few days, during the holiday season, I wrote some Go code to play with my LIFX Tile device I bought several months ago. The result is a library, and the following 2 videos:

The main reason I wrote yet another Go library for LIFX LAN Protocol is that although there are several Go libraries available, at the time of writing none of them support tiles, and tiles are the stuff I'd like to play with. As the result of that, the library is incomplete and focused on tile related APIs. It's incomplete to the extreme that it cannot control normal LIFX lights yet, at the time of writing this blog post. But while designing the API, I intentionally made it very extendible and export as many stuff as possible. As an example, the tile library is in its own package by using the base library as a library and extending it.

Another reason I did this is this is fun and exciting. The LIFX LAN Protocol is on UDP, and the last time I wrote UDP related code was 10+ years ago. I needed to relearn a lot of stuff in the past few days.

The code is on GitHub.

22:52:23 by fishy - opensource - Permanent Link

no comments yet - no trackbacks yet - karma: 28 [+/-]

Sunday, September 10, 2017

Kotlin Android in Bazel

The past week I took some of my spare time to make building Kotlin Android in Bazel work. The result is merged into pubref/rules_kotlin, which is kind of the "official" Kotlin rules for Bazel at the moment, and in its 0.4 release. Here I'm going to talk about some backgrounds and explain some technical details of this work.

Kotlin actually added Android support long before Android's announcement of official Kotlin support, and I did some attempts to make it work in Bazel, but to no avail. That's why I turned to Scala and sbt-android for my NotifBot project.

Recently I did some googling and found aaronj1335/bazel-kotlin-android, which is actually very nice, and the main inspiration of my work. I learnt a few interesting points from this project:

So I tried to rewrite NotifBot using Kotlin (from Scala), and followed the example of that project, but hit a problem: AAR libraries imported.

AAR libraries are kind of like JAR libraries, but with additional Android things in it. (e.g. resource files, AndroidManifest.xml, etc.) Since they are different from JAR files, when we generating the JAR file out of the Kotlin sources, they'll pose a problem.

To resolve this problem, I created the kotlin_android_library rule/macro to do the following things:

With these changes, the rewriting of NotifBot in Kotlin worked. As a next step, I tried to rewrite OneKey in Kotlin (this time from Java directly). This rewriting discovered a bug in depended kotlin_library rules, and I fixed that.

After that the rewriting of OneKey was also a success, so I think the work of getting Kotlin Android support in Bazel is done. Yes it's still possible (and trivial) to add a kotlin_android_binary kind of rule to include everything in a single rule, but I think that's not very useful or needed. If you really think that will be useful in some cases, or if you find any bugs in the implementation, please do let me know.

If you are looking for an example of building Kotlin Android in Bazel, please take a look at my BUILD files for NotifBot and OneKey.

21:33:00 by fishy - opensource - Permanent Link

no comments yet - no trackbacks yet - karma: 65 [+/-]

Sunday, May 28, 2017

NotifBot: Android app to forward notifications to Telegram bot

In my last blog post, I discussed why do I need Android Auto compatible SmartThings notifications, and why my attempt, AutoNotif, was rejected by Google Play because of Android Auto nofication policies.

After the rejection, I decided to use Telegram bot instead, because Telegram's Android app has very good Android Auto support, and Telegram itself has a very good bot platform.

The result is NotifBot: an Android app with a Telegram bot. It's an open source project released under BSD license

The Android app was written in Scala. It's mostly the same as the previous app, AutoNotif, just changed sending direct Android Auto notifications into sending Telegram messages.

The Telegram bot was written in Go, running on Google App Engine. It handles both Telegram's webhook and Android app's requests to forward the message. All connections are encrypted using HTTPS, and on the client side there are basic token authentication, and the token is revocable anytime with /stop Telegram command. I used Cloud Datastore for persistent storage (telegram token, user tokens).

In order to keep it under AppEngine's free tier for as long as possible, I chose the standard environment, which has some weird restrictions on Go (e.g. only has Go 1.6, has AppEngine specified APIs for Datastore, etc.). But in the end that's not a really big problem.

Please give it a try, and send me feedbacks.

tags: , , ,

11:48:59 by fishy - opensource - Permanent Link

no comments yet - no trackbacks yet - karma: 34 [+/-]

Thursday, November 24, 2016


This is an open source project I started 5 years ago, and just "finished" recently.

Back in 2011, my friend tension7 released a Chrome extension called One Password. It has a simple idea: using HMAC-MD5 to generate unique passwords for different sites.

I thought that was a good idea, and started to use it myself. (The idea is actually called "deterministic password manager/generator", and there are some discussions about it recently. I agree that it doesn't make your password stronger, but it do works better in certain cases. I use it on some sites myself, but not all of them.) I wrote a python version of it so that when I can use it easily while I'm not on Chrome.

And I also started writing an Android app for it. This is the Android app.

The sad thing is just that there're too many distractions in life, so I never found time to finish it. I made it "usable" at some point of 2013 or 2014, put it on my phone, and just put it away.

But I suddenly had some time due to various reasons recently, so I finally finished it. By "finish it" I mean I did a 1.0 release and listed it on Google Play, 5 years after I started the project.

There are still some TODOs, for example I would like to add the feature to save the master password with fingerprint, but I didn't figure out a good way to design the UI to make it work. But it's mostly feature complete, with highlights:

On the technical side, I chose Buck as the building system for this project, because it was the build system used by my day job project, and it worked great. I also tried to move it from Buck to Bazel, but Android's incompatible with Java8 is causing a lot of problems. I will probably switch to Bazel after that is sorted out.

Anyway, if you found the idea of deterministic password generator appealing to you (at least in certain cases), please give it a try. I hope you enjoy it.

tags: , , ,

21:54:18 by fishy - opensource - Permanent Link

no comments yet - no trackbacks yet - karma: -13 [+/-]

Monday, January 10, 2011

Purge Strikes Back to Android!

A Little Bit History

Back in 2005, after graduation from college, I got my first job at TrendMicro. After I got paid for enough money, I went to the store and brought a Palm Treo 650 home. That's the dream phone of that time. It have good hardware spec and more important, PalmOS.

My Treo 650 was broken at 2007. The radio module is died. So I can't use it as a phone, but can still use it as a PDA. I've made a nature choice: bought a Treo 680 to replace it. The reason is quite simple: it have PalmOS inside.

But the bad thing is I lost my Treo 680 at the end of 2007, left it on a table of a restaurant and never got it back again. This time I didn't buy Centro (but I recommended it to my then roommate :P). I decided to try something new. So I bought a Symbian phone (Nokia E51), Symbian looks like something comes from Stone Age compare to Palm OS. Then I bought a Windows Mobile phone (Sony Ericsson Xperia X1), but realized later that I do hate Windows Mobile. I bought a Samsung Galaxy (not to be confused with Samsung Galaxy S) at 2009, as I thought Android was mature enough to use. And I do love Android! But the lack of support and upgrade from Samsung makes me unhappy.

Finally, Google released Nexus One and I ordered one at the first time. This becomes the first phone after Treo 680 that I'm still happy after using it for half year, and I'm still happy with it while it's nearly a whole year already for now.


But there's still something I missed from Palm, like "Purge":


(I dug out my broken Treo 650 today, blow away the dusts, insert the battery, and it still works! so comes this photo.)

"Purge" is a simple feature to do the cleanup work: delete all old messages older than N days. Yes Android is much more powerful compare to Palm OS in the old days, and it can keep "almost everything" (actually for SMS, it will keep only the recent 200 messages per conversation and automatically delete old ones by default). But I don't like to keep too many meaningless "everything", I prefer the old Palm way.

So I took the last weekend to make Purge Strikes Back!

Purge Strikes Back!


Something I must mention is that for SMS deletion, I used some undocumented API. What did this mean? It means that this app may or may NOT work for you. It may or may NOT work as you expected. It may DELETE ALL YOUR SMS even you didn't mean to. It works on my Nexus One with Froyo and system Message app, it may not work with other phones, Android versions or Message apps. And it may break anytime even it works fine for you now. You take it totally on your own risk.

The call log deletion is implemented with system API, which should works fine, but I took no responsibility for your unexpected data loss, either.

So you'd better BACKUP YOUR SMS BEFORE TRYING IT. Personally I'm using SMS Backup + to do this for me and it works fine (it also backups call logs, too). There may be better ones but this is a choice you can consider.


How to Get It

Download it from its GitHub repo. It's free. You can also get the source code there, licensed under GPL v3.

I'll publish it to the Android Market in the coming days.

What to Expect in the Future


Some UI elements took from another awesome open source Android app Financisto, which is licensed under GPL v2.


project homepage

tags: , , ,

23:53:07 by fishy - opensource - Permanent Link

no comments yet - no trackbacks yet - karma: 60 [+/-]

Wednesday, October 13, 2010

Say "Goodbye and Thank you" to POPFile

POPFile is an awesome mail classifier works as a local POP3 proxy. It's written in Perl and use a web UI so it can run on any platform.

I started using it back from about 2004. First I use it to filter spams, later to filter work mail, personal mail and important mails apart. Time moves on, as I stop using POP3 on Gmail, the main job for POPFile became to picking not-so-important script generated reports from other work mails (combined with Thunderbird filter based on "X-Text-Classification" header).

As I also use Gmail for work mail now at Google, I have only a few POP3 accounts that rarely get some non-spam mails. So it's finally the time to say goodbye to POPFile. As a record, here's the final statistics for my POPFile history, since Jul. 2007, the last time I reset the stats:

Messages classified: 135,631,
Classification errors: 910,
Accuracy: 99.32%

That's very impressive result. Thank you POPFile for so many years of service. If you are still using POP3 account, you should try it right now!

BTW, I always hope Gmail can auto label my mails, just like POPFile. Finally we got priority inbox, but that's not enough for me.

tags: , , ,

22:54:43 by fishy - opensource - Permanent Link

no comments yet - no trackbacks yet - karma: 35 [+/-]

Sunday, October 11, 2009

Modified Pwitter to support 3rd party twitter API

Pwitter is a good open source Twitter client for Mac. I just added supporting for 3rd party twitter API to it to make it better.

You can get my patch here or my build here.

There's no GUI for setting 3rd party twitter API address. Instead, you need to change the configuration file. You can use either Property List Editor or the Terminal "defaults write" way. Here's an example:

$ defaults write com.aki.Pwitter twitter_https -bool NO
$ defaults write com.aki.Pwitter twitter_base ""

To restore the default settings ( https and "" ), you can just delete the custom settings by:

$ defaults delete com.aki.Pwitter twitter_https
$ defaults delete com.aki.Pwitter twitter_base

It's useful when you can't connect to directly, like me in China. Enjoy it.

tags: , , , ,

22:06:13 by fishy - opensource - Permanent Link

no comments yet - no trackbacks yet - karma: 73 [+/-]

Tuesday, August 12, 2008

Note: how to delete an error calendar in Lightning

As Bug #428274, I can't accept any meeting requests sent to my work mailbox, and have to add the meetings into Lightning manually. This is really annoying. As the bug got fixed, I decided to upgrade Lightning to a 0.9pre nightly to get it working.

After upgrading, the following error dialog will greet me every time I start Thunderbird:

The error message after I upgrade Lightning to 0.9pre nightly

I googled this error message and found that it was caused by the incompatible extension ThunderBirthDay. OK, delete the calendar should fix it. No! The calendar was hide from Lightning's calendar list!

Fine, downgrade Lightning and then remove the calendar should work. But unfortunately, Lightning 0.9 have changed the storage format and can't downgrade to 0.8 anymore.

So how to delete that calendar? Maybe I should delete the calendar direct from Lightning's storage. According to the official FAQ, it's stored as an SQLite database file.

Under Thunderbird's profile directory, I got a "storage.sdb" file. I tried to use the command line sqlite to open it, and it works:

$ sqlite3 storage.sdb 
SQLite version 3.5.0
Enter ".help" for instructions
sqlite> .tables
cal_attachments              cal_metadata               
cal_attendees                cal_properties             
cal_calendar_schema_version  cal_recurrence             
cal_calendars                cal_relations              
cal_calendars_prefs          cal_todos                  
cal_calmgr_schema_version    cal_tz_version             

The "cal_calendars" table seems to be the one I'm looking for:

sqlite> select * from cal_calendars;

Yes it is! so I need to know how to delete that record:

sqlite> .schema cal_calendars
CREATE TABLE cal_calendars (id INTEGER PRIMARY KEY, type TEXT, uri TEXT);

OK, then this should work:

sqlite> delete from cal_calendars where type = "thunderbirthday";
sqlite> select * from cal_calendars;

It DOES work!

Now my Thunderbird is quiet on starting.

But, the guys in Lightning really should give a chance to delete calendars that aren't compatible. I should file a bug for it. I've filed Bug #450121!

tags: , , ,

00:51:44 by fishy - opensource - Permanent Link

4 comments - no trackbacks yet - karma: 34 [+/-]

Monday, May 26, 2008

Miao cancelled

I've started the Miao project one year ago, aim to build a smart pinyin input method for Mac. But I just got a new job 2 weeks after I started this project. This is quite a busy year, and I haven't really wrote much code for it.

A month ago Yong Sun from Sun begin to port SunPinyin to Mac, and now it's more than just works. I'm satisfied with the Mac port and use it everyday. As the Miao project is scratching my own itch, and I'm not itchy anymore, I should call it a day.

Sorry for anyone who waits for Miao, but I'm not going to reinvent the wheel.

tags: , , , , , ,

20:29:46 by fishy - opensource - Permanent Link

1 comment - no trackbacks yet - karma: 29 [+/-]

Sunday, December 02, 2007

Yet another NP_Trackback hack

I've got an email from my host administrator to warn me that one of my MySQL table consumed lots of system load, and the table is nucleus_trackback.

But I haven't got any "real" trackbacks, so they are all spams, and more accurate, crazy spams, that simply too much to overload my DB.

So I have to wrote this patch to add an option to NP_Trackback: drop blocked trackbacks directly. After enabled, trackbacks that blocked by NP_Trackback (failed spam test or no link) will not be stored into the DB.

tags: , , , , , ,

12:35:40 by fishy - opensource - Permanent Link

no comments yet - no trackbacks yet - karma: 38 [+/-]

May the Force be with you. RAmen