Saturday, November 2, 2013

Next step was to get libchamplain working so that the location data can be shown on a map. That turned out to be pretty easy. I found the easiest way was to do a git clone of their current repository. Doing that also meant that I could look at some of the example code, especially the python bindings they have with that library.
git clone git://git.gnome.org/libchamplain
./autogen.sh
./configure
make
sudo make install
I found launcher-gtk.py particularly helpful in understanding how the map drawing works.

If you prefer to just install the binaries, then this should do the trick:
sudo yum install libchamplain-devel libchamplain-gtk-devel libchamplain-demos
With both GeoClue2 and libchamplain installed, I now had enough information to get started on my mini-project to get my current (IP-based) location plotted. The code for this can be found here.

Wednesday, October 30, 2013

buidling geocode2 from source

So I've officially given up on figuring out how to get the right libraries installed for GTG so that I can test out its geolocalization features. But, if you've seen my previous posts, you know it's been a painful process since I just can't seem to get the right libraries installed to get things working. But I'm going to go out on a limb and guess that this might not be entirely my fault because, from what I can tell, it seems like this particular feature is a rather old project? So maybe it's not surprising that the necessary libraries are a bit out of synch from the latest downloads that come bundled with Debian/Gnome/GTG. (Update: this bug report seems to confirm that this might be the case after all.)

So, with that sentiment, I'm moving on and am now going to try and install the libraries directly to see if I can get localization working separately from GTG. I've been advised that I need GeoClue2 to get location information, Champlain in GIR to show locations on a map, and GTK3 in GIR to show a map on a window. So I'm going to break it down and tackle the problem piece-wise.

First step: get GeoClue2 working.
  • Building the source: After digging around, I came across this, which looked a lot more promising. I also found this experimental deb release here, which is useful for those who don't want to deal with sources.
    [Note: I also came across this repo as well. But this is specifically for geocoding and is something different than GeoClue2.] So I pulled the source. To avoid getting the same install errors I did, first installed the gtk-doc package:
    git clone git://anongit.freedesktop.org/geoclue
    sudo yum install glib-devel gtk-doc json-glib-devel 
    sudo yum install intltool itstool libxml2-devel libtool libsoup-devel
    sudo yum install gobject-introspection-devel
    
    Now you should have all the pre-reqs for running GeoClue2:
    ./autoget.sh --prefix=/usr
    ./configure --prefix=/usr
    make
    sudo make install
    
    A couple of things to note here. First, if you don't use the --prefix=/usr flags, then the dbus files get put in /usr/local/share instead of /usr/share. Second, you have to use root credentials to do the install because you're installing dubs services.
  • Now that everything compiles nicely, you can try out the demo by going to the demo folder and running ./where-am-i. You may get an error message like this:
    CRITICAL **: Failed to connect to GeoClue2 service: 
    Error calling StartServiceByName for org.freedesktop.GeoClue2: 
    GDBus.Error:org.freedesktop.DBus.Error.Spawn.ChildExited: 
    Launch helper exited with unknown return code 253
    
    If you do, it's because you didn't use the --prefix=/usr flag I mentioned before. So go back, do a make clean and repeat the build process.
    If you're sure you did add the flags, then it's possible that the install still went incorrectly. On my Fedora machine, it added the /usr prefix in front of a /etc install, which led to things being installed under /etc instead of /usr/etc. You can change the script, or just hack it for now (like I did) and move the necessary files:
    sudo mv /usr/etc/system.d/org.freedesktop.GeoClue2.* /etc/dbus-1/system.d/
    Now you should be able to run the GeoClue2 demo:
    cd demo
    ./where-am-i
    
    And you'll see output that looks like this:
    Latitude: 40.440601
    Longitude: -79.995903
    Accuracy (in meters): 15000.000000
    Description: Pittsburgh, Pennsylvania, United States
    
  • Note if you want to get things installed on Ubuntu, I had to first install these packages:
    sudo apt-get install intltool itstool libxml2-utils 
    sudo apt-get install libgeocode-glib-dev libjson-glib-dev libsoup2.4-dev
    sudo apt-get install libgirepository1.0-dev 
    
    The rest of the install process (including the --prefix=/usr flags I mentioned before) is the same.
    For 'fun', I also tried this process on a Debian machine and ended up having a much harder time getting things to just work. So I decided to ditch that and just stick with Fedora (or Ubuntu) for now.

geolocalization & gtg, take 2

OK, I'm trying to install GTG again. This time, I'm using Ubuntu 13.10 Desktop (64-bit). To get things started, I ran the same pre-steps as before: added myself to the sudo list, installed some basic tools, and set up bzr, and grabbed the code from launchpad. I tried running:
sudo apt-get install python-liblarch python-liblarch-gtk
But it turns out that this installs v1.0 and GTG is expecting v2.1. No worries. Just follow the instructions to do a git clone. The trick after that is to run ./gtg -l (instead of just ./gtg). To eliminate the other warning messages that GTG throws, just do:
sudo apt-get install python-dateutil python-suds python-evolution
Now to get the geolocation stuff to work, installing geoclue is easy:
sudo apt-get install python-geoclue
To get python-clutter, I had to update my sources.list to reference squeeze, since it seems it's not listed in the wheezy dist. So that definitely fixes it so that apt-get can find the package, but it still gave me problems, just like before:
The following packages have unmet dependencies:
python-clutter:
Depends: libclutter-1.0-0 (>= 1.0.8) but it is not going to be installed
Depends: python (< 2.7) but 2.7.3-4+deb7u1 is to be installed
E: Unable to correct problems, you have held broken packages
So this is saying that, to use python-clutter, I need to downgrade my python to something < 2.7. OK, so I found that one of the easiest way to install older versions of python is to add PPAs like this to your sources.list:
sudo add-apt-repository ppa:fkrull/deadsnakes
sudo apt-get update
sudo apt-get install python2.6 python2.6-dev
ls -lsa /usr/bin/python* # you should see python2.6 listed here now
Now that I have a version that might work with python-clutter, I can set up a virtual environment that only has python2.6 and see if it works:
sudo apt-get install python-virtualenv
mkdir ~/<gtg_virtualenv>
cd <gtg_virtualenv>
virtualenv -p /usr/bin/python2.6 --no-site-packages .
source bin/activate
The --no-site-packages is important, as it says that we won't look at any of the packages that are in our host environment (like python2.7). Of course, that also means that you'll have to reinstall any packages that you need. And that explains why, if you go run GTG right off the bat, you'll get error messages like:
File "./gtg", line 26, in <module>
from gtk.gdk import Screen
ImportError: No module named gtk.gdk
And that's where my patient with this experiment ends. I couldn't seem to figure out an easy way to install the right set of packages. I tried the usual suspects (pygobject, etc), but none of them worked or they were already installed, so it didn't help. Oh well, back to the drawing board!

Monday, October 28, 2013

configuring 3rd party blogging software for blogger

In case anyone else had trouble searching for how to setup a 3rd party app (in my case, MarsEdit) to be used with Blogger, here's what you need to know:
  • Blog ID: Follow these instructions to find your Blog ID.
  • API Endpoint URL: http://www.blogger.com/feeds/[YourBlogID]/posts/default

geolocalization & gtg, take 1

Came across the GTG project and was interested in possibly doing some development on it. The first major hurdle I encountered was getting a VM setup that worked with the right libraries. Since I was interested in working on the geolocalization features in GTG, I had to install the python modules for geoclue, clutter, and champlain. Turns out I was having a hard time getting python-clutter to install because it seemed that the apt sources were from an older version of Debian (squeeze) than what I was running (wheezy). Modifying the /etc/apt/sources.list, as suggested here, worked so that at least the module was found when I tried to sudo apt-get install it. But it turns out that it's only compatible with python version < 2.7. And Debian 7 (wheezy) comes with python 2.7 installed by default. I tried downgrading python, but then that cascaded and a whole slew of other dependencies also needed to be downgraded. So I decided to start from scratch again and just use Debian 6 (squeeze), which comes with python v2.6.6 installed by default. From there, it was a breeze in getting things setup. Just a few administrative things to install up front:
  1. Add myself to the sudo list. After running the following commands, I had to reboot the VM. It seems a simple logout/login didn't work for me. After restarting, I was able to use the sudo
    su
    adduser myusername sudo
    
  2. Add git and bzr so that I can checkin/checkout code. Xsel allows me to use a handy shortcut. Note that, if you're using VMWare, you'll still need to have VMWare Tools to be installed so that you can pass stuff between your VM and your host computer.
    sudo apt-get install git bzr xsel
    cd ~
    nano .bashrc 
    # inside .bashrc add this line:
    alias pbcopy='xsel --clipboard --input'
    # save the file and exit out
    source .bashrc
    
  3. Created a sshkey for myself, pasted that into bzr, and then setup bzr.
    ssh-keygen -t rsa -C "email@address.com"
    ssh-add id_rsa.pub
    pbcopy "
    bzr launchpad-login <launchpad-username>
    
From here, I followed the setup guide here . Here's how I solved (or tried to solve) the errors I encountered:
  • After downloading the code from launchpad and then running ./gtg, I encountered this error message:
    E: Unable to locate package python2
    I did have python installed, but it was mapped to python, not python2. Solution:
    sudo ln -s /usr/bin/python /usr/bin/python2
  • Running ./gtg shows me this message:
    GTG can't find liblarch and liblarch_gtk
    The error messages provides a possible solution:
    To install missing libraries, run the following command in the current folder:
    git clone https://github.com/liblarch/liblarch ../liblarch
    I decided to use apt-get to install the missing libraries. But it turns out that liblarch (and liblarch-gtk) don't have packages for squeeze, only for wheezy. So first I had to edit the sources.list file and then run apt-get:
    sudo nano /etc/apt/sources.list
    # add this line to the file, feel free to change the url 
    # to whichever/wherever is most appropriate for you
    deb http://carroll.aset.psu.edu/pub/linux/distributions/debian/ wheezy main
    # save file and exit
    # to ensure you get the new package list from the url you just added, run this: 
    sudo apt-get update 
    
    I tried to run sudo apt-get install python-liblarch python-liblarch-gtk, but I got a bunch of errors saying I had unmet dependencies, so I went with aptitude instead, searched for python-liblarch, and then went with its recommendation of how to resolve the dependencies. I repeated the same step with installing python-liblarch-gtk.
...And, what do you know - I hit another wall. I'm able to install liblarch and liblarch-gtk, but when I'm back at the prompt, I get greeted with this error message:
/usr/bin/sudo: No such file or directory
Looking at my PATH variable suggests that the right path is there (i.e., /usr/bin is included), but looking inside that directory, sudo isn't listed. And which sudo return nothing. Looking online, suggests something reinstalling the OS and/or booting to a Live disc, mounting it and then copying the necessary files over. So, I'm back to square 1 and trying to figure out how to set everything up - this is frustrating!

Saturday, October 26, 2013

git/github workflow

In the past, I've only used github for personal projects, so I didn't have to deal with collaborating with other folks. Now that I'm working on an open-source project, I'm starting to get more familiar with all the cool features of git and github. So here's the scenario:
  • Project A is on github (aka the original repo).
  • Alice has forked Project A on github and created a branch(/patch) off of that fork. (As a side note, the branch was already sent as a pull request to the original repo, but it hasn't been merged yet.)
  • I have to work on a new feature that is based off of Alice's branch. So should I fork off of Alice's repo or the original repo?
I decided on the latter option. Why? Because I'd like to make sure I keep up-to-date with the original repo, in case there are changes there that aren't being pulled by Alice in her copy of the repo. So here's how I set things up:
  • Went on github and forked Project A so that I had my own personal copy of the original repo.
  • Cloned my copy of the repo onto my machine. By default, cloning creates a remote called origin that points to my copy of Project A on github.
    git clone https://github.com/kpytang/[project-name.git]
    
  • To make sure I keep tabs on the original repo, I add a remote called upstream pointing to the original Project A on github.
    cd [project-name]
    git remote add upstream https://github.com/[project-github-username]/[project-name].git
    
  • Before pulling in Alice's changes, I wanted to make sure my master branch remained as clean as possible, so I created a new branch for the feature I'm working on, and pulled Alice's repo into that branch. To make sure things semantically made sense, I gave the branch a generic name based on the feature I'm responsible for (instead of the specific feature, which I'll use later).
    git branch [generic-feature-name] # creates a new branch
    git checkout [generic-feature-name] # makes it the active branch
    
    Alternatively, the shortcut below does the same thing:
    git checkout -b [generic-feature-name]
    
  • Added Alice's repo as a remote off of the newly created branch. I needed to add her entire repo before I could get to the one branch that I really wanted.
    git remote add [alice] https://github.com/[alice]/[alice-project-name].git
    
  • Grabbed Alice's repo and merged that into my branch (off of the master branch, which is a clean copy of the original project).
    git fetch [alice]
    git merge [alice]/master 
    
  • Grabbed Alice's branch and merged that into the same branch
    git merge [alice]/[branch-name]
    
  • Created a new branch for the specific feature I'm working on. This way when I go to create another feature that's also based Alice's branch, I have an easy starting point to work off of.
    git branch [specific-feature-name]
    git checkout [specific-feature-name]
    
Now I can start working and doing local commits of the new [specific-feature-name] branch and then when I'm ready, I can push my local commits to github. From there I can do a pull request to Alice's branch and she can see what changes I've done. Alternatively, I can also do a pull request to the original repo as well. By separately out the two repos (Alice and the original repo), we can also easily do merges from one or both of those remote repos. Other tips:
  • To pull changes from the original repo later on, make sure you're on the right branch (i.e., the master branch) and pull in upstream changes from the original repo.
    git checkout master # makes "master" the active branch
    git fetch upstream # grabs commits from the original repo
    git merge upstream/master # merges commit from original repo with the master branch
    
  • To merge changes from one branch to another:
    git checkout master # makes "master" the active branch
    git merge [branch] # merges commits from "branch" to the master branch
    
  • To get a list of all your branches:
    git branch
    
  • To delete a branch:
    git branch -d [branch] # deletes the "branch" branch locally
    git push origin :[branch] # deletes the "branch" branch on github (note the ':')
    
  • Push changes to your own github repo doesn't change:
    git checkout master # makes "master" the active branch
    git push origin master # push commits from master branch to your copy of the repo on github
    
  • Merging a pull request locally (useful for when you want to test things out first or when you don't have push permissions for a repo):
    git checkout master # makes "master" the active branch
    git pull https://github.com/[other-user]/repo.git [branchname]
    
    Now you can work on the pull request, make local commits, etc. When you're happy with the merged fix, you can push it back to your own repo:
    git push origin master # push commits from master branch to your copy of the repo on github
    
Refs: https://help.github.com/articles/fork-a-repo
https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches

Friday, October 25, 2013

bootstrap v3 accordion

Was banging my head on the wall for hours trying to figure out a bug in Bootstrap's accordion component. I followed the example code in the Bootstrap doc, but for some reason, the accordion would only toggle once. So if it was initially open, then I could collapse it, but clicking on it again, wouldn't open it. If the accordion was initially closed, I could open it (once), but then clicking on it again wouldn't close it. Turns out this was the issue: http://stackoverflow.com/questions/17202285/bootstrap-collapse-only-toggles-once The solution suggests that there's a conflict with an old prototypeJS library. However, I checked out all the js files attached to the project and didn't see any explicit linking to prototypeJS, so I'm not sure where the conflict is occurring. Nevertheless, if this affects you, follow the instructions at the stackoverflow's link and modify that one line from
this.$element.trigger(startEvent)
to
this.$element.triggerHandler(startEvent)