[08:31] <dado_> exit
[15:01] <jcastro> ok about ready?
[15:01] <jcastro> Day 4, keep up the energy!
[15:01] <jcastro> take it away Abd4llA!
[15:01] <Abd4llA> Thanx jcastro
[15:02] <Abd4llA> Ok guys good afternoon
[15:02] <Abd4llA> As you all know today we'll be talking about debuging python apps,
[15:03] <Abd4llA> specially Quickly apps
[15:03] <Abd4llA> Well there're tons of python debuggers out there
[15:04] <Abd4llA> but I'd say in 90% of the cases, you'll be using "pdb"
[15:04] <Abd4llA> pdb comes by default with the python installation
[15:05] <Abd4llA> As its name shows, it stands for "Python DeBugger"
[15:05] <Abd4llA> You can use pdb to track your program execution,
[15:06] <Abd4llA> do post-mortum debugging
[15:06] <Abd4llA> and pretty much anything a decent debugger should do :-)
[15:08] <Abd4llA> So lets get rolling quickly with pdb
[15:09] <Abd4llA> So to start with, lets see how a normal pdb session looks like
[15:09] <Abd4llA> just in the terminal issue the command "pdb"
[15:10] <Abd4llA> You'll see that it accepts normal scripts as an argument
[15:11] <Abd4llA> so we can pretty much launch pdb normally
[15:11] <Abd4llA> pdb <script.py>
[15:11] <Abd4llA> that'll launch a pdb debug session for your script
[15:11] <Abd4llA> starting at the first line, from there you can set your break points...etc then get rolling
[15:12] <Abd4llA> or you can inject an explicit call to pdb from within your python script
[15:12] <Abd4llA> so lets see how can we do that
[15:12] <Abd4llA> First, as I said, this is about debugging quickly apps, but most of what we'll say today can be applied to any python scripts/programs
[15:13] <Abd4llA> So, lets start by creating the sample quickly ubuntu-application template application
[15:13] <Abd4llA> from your favourite workspace dir, issue create a quickly app by issuing the command
[15:14] <Abd4llA> quickly create ubuntu-application DummyApp
[15:14] <Abd4llA> And let me know what you see :) ?
[15:15] <Abd4llA> Now as you see, this is the default template app for the ubuntu-application quickly template
[15:16] <Abd4llA> It's pretty  dummy, so lets try adding some "yea, dummy" functionality
[15:16] <Abd4llA> there u'll find a "save" item in the "file" menu
[15:17] <Abd4llA> so lets call some function when we click save
[15:17] <Abd4llA> close your DummyApp
[15:17] <Abd4llA> then navigate to the dummyapp dir
[15:18] <Abd4llA> there, issue the command:
[15:18] <Abd4llA> quickly design
[15:18] <Abd4llA> That'll launch "Glade"
[15:18] <Abd4llA> now click on the file menu
[15:18] <Abd4llA> and click on the "save"
[15:19] <Abd4llA> in the properties panel on the right
[15:19] <Abd4llA> click the "Signals" tab
[15:20] <Abd4llA> You'll find a subitem called "activate" under "GtkMenuItem"
[15:20] <Abd4llA> There we'll write down the name of the method to call when we click save
[15:20] <Abd4llA> lets call it "save_me"
[15:21] <Abd4llA> so write down "save_me" in the "Handler" field of the item "activate"
[15:22] <Abd4llA> so
[15:22] <Abd4llA> now make sure to save
[15:22] <Abd4llA> ctrl+s
[15:22] <Abd4llA> close your glade
[15:23] <Abd4llA> now we need to write down that method
[15:23] <Abd4llA> so in your terminal, issue the command
[15:23] <Abd4llA> quickly edit
[15:23] <Abd4llA> that'll open all your source files
[15:23] <Abd4llA> in gedit
[15:24] <Abd4llA> now go to the file dummyapp
[15:24] <Abd4llA> That's our main file
[15:24] <Abd4llA> we need to add our save_me method to the DummyappWindow class
[15:25] <Abd4llA> so navigate there, maybe under the "on_destroy" method
[15:25] <Abd4llA> add the following method
[15:26] <Abd4llA> def save_me(self, widget, data=None):
[15:26] <Abd4llA>     introduce_bug()
[15:27] <Abd4llA> Now as you see, we're calling a method called introduce_bug
[15:27] <Abd4llA> we'll add that function to helpers.py
[15:27] <Abd4llA> so go to the top of the dummyapp file
[15:27] <Abd4llA> and import it as follows
[15:28] <Abd4llA> from dummyapp.helpers import introduce_bug
[15:28] <Abd4llA> we'll write that function ourselves
[15:28] <Abd4llA> Now navigate to helpers.py inside your gedit
[15:29] <Abd4llA> and at the very bottom, write down that method
[15:30] <Abd4llA> def introduce_bug():
[15:30] <Abd4llA>     name = "bug"
[15:30] <Abd4llA>     print "I am a " + name
[15:30] <Abd4llA>     print "I am a healthy line"
[15:30] <Abd4llA> then save your gedit
[15:31] <Abd4llA> Keeping up so far?
[15:31] <Abd4llA> Now save gedit, then close
[15:31] <Abd4llA> then run our app by firing
[15:31] <Abd4llA> quickly run
[15:32] <Abd4llA> and click "save"
[15:32] <Abd4llA> in your terminal you should see
[15:32] <Abd4llA> I am a bug
[15:33] <Abd4llA> I am a healthy line
[15:37] <Abd4llA> Make sure your import line
[15:38] <Abd4llA> is under the line
[15:38] <Abd4llA> from dummyapp.helpers import get_builder
[15:38] <Abd4llA> so at the end it'll look like
[15:38] <Abd4llA> from dummyapp.helpers import get_builder
[15:38] <Abd4llA> from dummyapp.helpers import introduce_bug
[15:38] <Abd4llA> Now run again
[15:38] <Abd4llA> quickly run
[15:38] <Abd4llA> click save
[15:38] <Abd4llA> test
[15:38] <Abd4llA> all good ?
[15:39] <Abd4llA> Now that's a bug over there
[15:39] <Abd4llA> We need to hunt it down
[15:39] <Abd4llA> there're several ways
[15:39] <Abd4llA> but lets choose the easiest
[15:40] <Abd4llA> from your command line
[15:40] <Abd4llA> issue the command
[15:40] <Abd4llA> pdb bin/dummyapp
[15:40] <Abd4llA> Now we're starting a pdb session
[15:40] <Abd4llA> it started at the first line of your script
[15:41] <Abd4llA> pdb accepts commands
[15:41] <Abd4llA> so issue
[15:41] <Abd4llA> h
[15:41] <Abd4llA> that should show the help
[15:41] <Abd4llA> now we need to add some breakpoints
[15:41] <Abd4llA> we know that the method save_me is the one that gets called when clicking save
[15:41] <Abd4llA> so lets add a breakpoint to it
[15:42] <Abd4llA> the comman b is used to add breakpoints
[15:42] <Abd4llA> (Pdb) b dummyapp:134
[15:43] <Abd4llA> this way we added a breakpoint to the file dummyapp
[15:43] <Abd4llA> line number 134
[15:43] <Abd4llA> you should match the line number of your def save_me
[15:44] <Abd4llA> my method is defined at line 134
[15:44] <Abd4llA> so now we have a breakpoint there
[15:44] <Abd4llA> let's run the code !
[15:44] <Abd4llA> c
[15:44] <Abd4llA> that'll continue execution untill the first breakpoint
[15:44] <Abd4llA> Good?
[15:45] <Abd4llA> notice the command "c"
[15:45] <Abd4llA> now we notice that it'll stop when it reads the function definition
[15:46] <Abd4llA> that's not what we want
[15:46] <Abd4llA> we wanna stop when it starts executing
[15:46] <Abd4llA> so lets try that again
[15:46] <Abd4llA> close the app
[15:46] <Abd4llA> run it inside pdb
[15:46] <Abd4llA> pdb bin/dummyapp
[15:46] <Abd4llA> now this time, lets make the breakpoint at the introduce_bug() method call line
[15:46] <Abd4llA> the first line of the "save_me" function
[15:47] <Abd4llA> (Pdb) b dummyapp:135
[15:47] <Abd4llA> now lets continue execution till first breakpoint
[15:47] <Abd4llA> (Pdb) c
[15:47] <Abd4llA> you'll see that the application shows
[15:48] <Abd4llA> and now we need to click "file-> save"
[15:48] <Abd4llA> there you'll see pdb stoping at the break point
[15:48] <Abd4llA> Good ?
[15:49] <Abd4llA> now lets try some pdb commands
[15:49] <Abd4llA> (Pdb) l
[15:49] <Abd4llA> that'll list the code
[15:49] <Abd4llA> (Pdb) w
[15:49] <Abd4llA> stack trace
[15:50] <Abd4llA> Now we can either execute the next line using "n" or step into the method "introduce_bug"
[15:50] <Abd4llA> using s
[15:50] <Abd4llA> so lets see
[15:50] <Abd4llA> (Pdb) s
[15:50] <Abd4llA> we're there now
[15:50] <Abd4llA> (Pdb) n
[15:50] <Abd4llA> will go to the next line
[15:51] <Abd4llA> (Pdb) l
[15:51] <Abd4llA> list the code there
[15:51] <Abd4llA> now I see that the "print "I am a " + name" line is the one that introduces a bug and I wanna skip it
[15:51] <Abd4llA> (Pdb) j 50
[15:52] <Abd4llA> That way we jumped to the next line
[15:52] <Abd4llA> (Pdb) c
[15:52] <Abd4llA> will continue execution without the buggy line and will print "I am a healthy line" only
[15:52] <Abd4llA> Good ?
[15:53] <Abd4llA> Lets try another way to trace that bug
[15:53] <Abd4llA> close your session
[15:53] <Abd4llA> and edit your code
[15:53] <Abd4llA> quickly edit
[15:53] <Abd4llA> go to dummyapp file
[15:54] <Abd4llA> in save_me method
[15:54] <Abd4llA> add the following line before the call to "introduce_bug"
[15:54] <Abd4llA> import pdb; pdb.set_trace()
[15:54] <Abd4llA> so the final method will be
[15:55] <Abd4llA>     def save_me(self, widget, data=None):
[15:55] <Abd4llA>         import pdb;pdb.set_trace()
[15:55] <Abd4llA>         introduce_bug()
[15:55] <Abd4llA> now run the app
[15:55] <Abd4llA> quickly run
[15:55] <Abd4llA> go to file->save
[15:56] <Abd4llA> you'll see that a pdb session will start @ the termincal
[15:56] <Abd4llA> *terminal
[15:56] <Abd4llA> that's another way to launch ur pdb , from within the code
[15:56] <Abd4llA> now type args
[15:56] <Abd4llA> that prints the arguments
[15:57] <Abd4llA> (Pdb) args
[15:57] <Abd4llA> also there's u and d
[15:57] <Abd4llA> (Pdb) u
[15:57] <Abd4llA> that goes to the upper frame
[15:57] <Abd4llA> (Pdb) d
[15:57] <Abd4llA> That goes to the lower one
[15:57] <Abd4llA> now
[15:57] <Abd4llA> (Pdb) s
[15:58] <Abd4llA> step into the introduce_bug method
[15:58] <Abd4llA> (Pdb) n
[15:59] <Abd4llA> now you can alter your name variable
[15:59] <Abd4llA> (Pdb) name = "Not a bug"
[15:59] <Abd4llA> That was a quick introduction for Pdb guys :)
[15:59] <Abd4llA> So thanks alot guys , more time would've been convenient :)
[16:00] <Abd4llA> but hopefully it was fun :-)
[16:01] <dpm> Thanks Abd4llA, and hi everyone!
[16:01] <dpm> Welcome to this session on setting up your project for translations in Launchpad.
[16:02] <dpm> My name is David Planella and I'm the Ubuntu Translations Coordinator, where I work with our translations community to bring you a localized operating System.
[16:02] <dpm> I also tend to help with any topics related to translations and Launchpad, and that's what we're going to talk about today :)
[16:02] <dpm> That's a really exciting topic to me, as Launchpad makes it really easy to make your applications translatable and available to everyone in almost any language, and I hope you enjoy it as much as I do.
[16:03] <dpm> Translators are really awesome people!
[16:03] <dpm> Anyway, let's get started, shall we?
[16:03] <dpm> = Assumptions =
[16:03] <dpm> I will start with an application ready set up for translations, so I'm not going to go into much detail there.
[16:04] <dpm> My intention is to focus in getting you started with exposing your project's translations to everyone for translation.
[16:04] <dpm> In any case, if you've got questions on this, feel free to ask either during or at the end of the session, and I'll be more than happy to answer them
[16:04] <dpm> We're going to be using these tools:
[16:04] <dpm>     bzr
[16:04] <dpm>     quickly
[16:04] <dpm>     python-distutils-extra
[16:04] <dpm> In particular quickly, which we'll use to start with a nearly ready-made project with translations set up
[16:05] <dpm> (You can install it by running the 'sudo apt-get install quickly' command or you can get it from Applications > Ubuntu Software Center)
[16:05] <dpm>  
[16:05] <dpm> = Creating the project and setting it up for translations =
[16:05] <dpm>  
[16:06] <dpm> We'll use quickly to create a project called 'fooby', and then we'll set up the last touches needed to configure translations.
[16:06] <dpm> So if you've got all those tools installed, you can simply fire up a terminal window (Applications > Accessories > Terminal) and run the following command:
[16:07] <dpm>     quickly create ubuntu-application fooby
[16:07] <dpm> This will create an application named 'fooby'
[16:07] <dpm> and give you some information about it on the first run
[16:08] <dpm> then change to the fooby folder:
[16:08] <dpm>     cd fooby
[16:08] <dpm> And finally run:
[16:08] <dpm>     python setup.py build_i18n
[16:08] <dpm> That should have finished the last bits to set up translations
[16:09] <dpm> in particular it created the po folder to contain the translations template and the translations
[16:09] <dpm> you can see the template:
[16:09] <dpm>     ls po
[16:09] <dpm> have a look at it:
[16:09] <dpm>     gedit po/fooby.pot
[16:10] <dpm> It's important to get a bit familiar with it, but you don't have to remember the whole format
[16:10] <dpm> you should simply know what it is for now :)
[16:10] <dpm> A few words on translation templates:
[16:10] <dpm>  * Gettext: They follow the gettext format: http://is.gd/fC8p6
[16:11] <dpm>  * Name: They are generally named after your project, with a .pot extension. E.g. fooby.pot
[16:11] <dpm>  * One template per app: Generally applications need only one template
[16:11] <dpm>  * Layout: They generally live in the po/ folder, along with the translations
[16:11] <dpm>  * Content: They are text files which contain:
[16:11] <dpm>     * A header with metadata
[16:11] <dpm>     * A set of message pairs: msgid are the original strings extracted from the code and exposed to translators, and msgstr are the placeholders for the translations, which are always empty in the templates.
[16:12] <dpm>  * Launchpad import: They are imported into Launchpad and exposed for translations for all languages in https://translations.launchpad.net/$YOUR_PROJECT
[16:12] <dpm>  * Updates: You update the template whenever you have new strings in your app and you think they are stable for translation (generally shortly before release)
[16:12] <dpm>  * Tools: you update templates with gettext based tools:
[16:12] <dpm>     * generally intltool -> 'cd po && intltool-update -p'
[16:13] <dpm>     * or increasingly python-distutils-extra for python projects -> 'python setup.py build_i18n -p'
[16:13] <dpm> You don't have to remember all of this
[16:13] <dpm> But at least you should know how that you must update the template from time to time
[16:13] <dpm> and the command to do it
[16:13] <dpm> You'll see that your project still does not contain any translations, but let me give you a quick overview, so you know what we're talking about:
[16:14] <dpm> A few words on translations:
[16:14] <dpm>  * Template-based: They are created from the template and share the same gettext format
[16:14] <dpm>  * Name: They are named after the $CODE.po scheme, where $CODE is an ISO 639-2 code. E.g. ca.po for Catalan, de.po for German. Some have an optional country specifier. E.g. pt_BR.po (Portuguese from Brazil)
[16:14] <dpm>  * Layout: they are all in the same directory as the POT template. So:
[16:14] <dpm>     * po/fooby.pot
[16:15] <dpm>     * po/ca.po
[16:15] <dpm>     * po/pt_BR.po
[16:15] <dpm>      * ...
[16:15] <dpm>  * Creation: Launchpad creates them for you the minute someone translates the first message online
[16:15] <dpm>  * Code integration: you can let Launchpad commit them to a branch of your choice or you can export a tarball containing them all
[16:16] <dpm> Anyway, let's continue. Now that you've added the template to your code, you can commit it:
[16:16] <dpm> You can run the following commands:
[16:16] <dpm>     bzr add po
[16:16] <dpm>     bzr commit -m 'Created my first ever awesome .pot template. Go translators, go!'
[16:17] <dpm> And let's publish it in Launchpad (note that you'll have to change the Launchpad URL to your user name instead of 'dpm'):
[16:17] <dpm>     bzr push lp:~dpm/fooby/translations
[16:17] <dpm> Nothing particularly hard to understand on the naming scheme above: dpm is my user name, fooby is the project and translations is the branch name
[16:18] <dpm> Ok, so that completed the first step!
[16:18] <dpm> Next:
[16:18] <dpm>  
[16:18] <dpm> = Setting up code hosting =
[16:18] <dpm>  
[16:18] <dpm> We want our project to be available to everyone to translate, so we'll need to publish it in Launchpad.
[16:18] <dpm> That's beyond the scope of this session, so we'll continue from the already registered fooby project in Launchpad:
[16:18] <dpm>     https://code.launchpad.net/fooby
[16:19] <dpm> In case you are interested, though, registering a new project in Launchpad is as easy as going to https://launchpad.net/projects/+new
[16:20] <dpm> Some of the URLs will not allow you some of the pages due to permissions, so if you have your own project in Launchpad, just substitute the 'fooby' part in the URL with your project's Launchpad id
[16:20] <dpm> The first thing we'll have to do in our project is registering a bzr branch,
[16:20] <dpm>     so we'll simply go to the Code tab in Launchpad, choose the "Configure code hosting" link
[16:21] <dpm> and then on the "Link to a Bazaar branch already on Launchpad" you can enter the branch we published earlier on (~dpm/fooby/translations)
[16:21] <dpm> A shortcut is to simply go to:
[16:21] <dpm> https://code.launchpad.net/fooby/trunk/+setbranch
[16:21] <dpm> to do this
[16:21] <dpm> So now we have all we need to start setting up translations.
[16:22] <dpm> You see that all components in Launchpad are integrated, so you set up a branch to be linked to translations
[16:22] <dpm> Just as a recap, you can see and explore the resulting code from here:
[16:22] <dpm>     https://code.launchpad.net/fooby
[16:22] <dpm> Feel free to browse it (http://bazaar.launchpad.net/~dpm/fooby/translations/files)
[16:23] <dpm> or download it (bzr branch lp:fooby) and play with it
[16:23] <dpm> Ok, so code hosting setup: (./) Finished!
[16:23] <dpm>  
[16:23] <dpm> = Setting up translations in Launchpad =
[16:23] <dpm>  
[16:24] <dpm> Now we come to the most interesting part
[16:24] <dpm> 1. Telling Launchpad where translations are hosted
[16:24] <dpm> The first step it to tell Launchpad that we want to host translations there.
[16:24] <dpm> On your Launchpad's project, just click on the Translations tab, or go to this URL:
[16:25] <dpm> (remember to change 'fooby' to your project's name)
[16:25] <dpm>     https://translations.launchpad.net/fooby/+configure-translations
[16:25] <dpm> Then choose the "Launchpad" option to tell Launchpad translations will be done there, and click on "Change"
[16:26] <dpm> That was an easy one, wasn't it?
[16:26] <dpm> 2. Configuring permissions
[16:26] <dpm> Now we are going to tell Launchpad how we want our translations permissions to be (i.e. who and how can translate it),
[16:26] <dpm> and which branch translators should focus on.
[16:27] <dpm> Simply go to the Translations tab again and click on the "Change permissions link"
[16:27] <dpm> Or here's the direct link: https://translations.launchpad.net/fooby/+settings :)
[16:27] <dpm> I recommend the following setup:
[16:28] <dpm>     Translations group: Launchpad Translators
[16:28] <dpm>     Translations permissions policy: Structured
[16:28] <dpm>     Translation focus: trunk (or choose your branch here)
[16:29] <dpm> Assigning the translations to a translation group will make sure a team for each language will review translations before they are submitted, ensuring the quality of translations
[16:30] <dpm> A translations group is a group of teams, one per language, that takes care of translations in their language
[16:31] <dpm> They can be specific to a project or generic. I recommend the Launchpad Translators group because it contains a set of already established and experienced teams:
[16:31] <dpm> https://translations.launchpad.net/+groups/launchpad-translators
[16:31] <dpm> as per the Structured policy
[16:32] <dpm> This gives you a good balance between openness and quality control:
[16:32] <dpm> Only the team members of an established team will be able to translate your project
[16:33] <dpm> And for languages without a team it will allow everyone to translate, facilitating the barrier of entry to translators at the expense of QA
[16:33] <dpm> The other extremes are Open or Restricted
[16:33] <dpm> You can learn more about these here:
[16:34] <dpm>     https://help.launchpad.net/Translations/YourProject/PermissionPolicies
[16:34] <dpm> It's the project maintainer's call, but I personally discourage them to use Open
[16:34] <dpm> Ok, we're nearly there, next step:
[16:34] <dpm> 3. Setting up what needs to be translated
[16:35] <dpm> You need to also tell Launchpad what needs to be translated. That's again quite easy. On the Translations tab again, choose the trunk series and specify your branch there
[16:35] <dpm> Direct link: https://launchpad.net/fooby/trunk/+linkbranch
[16:35] <dpm> Another easy one
[16:35] <dpm> 4. Configuring imports and exports
[16:36] <dpm> That's for me the most interesting bit
[16:36] <dpm> The settings on this section basically enable Launchpad to do the work of managing translations for you
[16:36] <dpm> You can tell Launchpad to import your translation templates automatically whenever you do a commit
[16:37] <dpm> So you don't have to upload them manually
[16:37] <dpm> If you are migrating a project with existing translations, you can tell it to import them too
[16:37] <dpm> And finally, you can let Launchpad commit translations automatically to a branch of your choice
[16:38] <dpm> I find that just awesome
[16:38] <dpm> So for the imports, on the Launchpad page, on the "Import translations from branch" section:
[16:39] <dpm> I recommend choosing "Import template files" and then "Save settings"
[16:39] <dpm> For exports: look at the "Export translations to branch" section and then click on the  "Choose exports branch" link
[16:40] <dpm> So that was it!
[16:40] <dpm> 4 easy steps that should not take you more than a few minutes to set up, and your app is ready for the world to translate!
[16:40] <dpm> Just a few final words:
[16:40] <dpm>  
[16:40] <dpm> = Play with translations =
[16:40] <dpm>  
[16:41] <dpm> As a developer, it might be interesting to see how translators do their work.
[16:41] <dpm> Exceptionally (remember how I advised not to use Open permissions, tough :) I've set the translations permissions on the fooby project to Open
[16:41] <dpm> So you can submit translations
[16:41] <dpm> and get a feel for the work that translators do
[16:42] <dpm> As a developer, it will give you an understanding on how they work. It is always interesting to get to know other workflows
[16:43] <dpm> and it's always good to have an insight on all areas of contribution related to your project
[16:43] <dpm> You can start translating fooby here:
[16:43] <dpm> 	https://translations.launchpad.net/fooby
[16:43] <dpm>  
[16:43] <dpm> = Summary =
[16:43] <dpm>  
[16:43] <dpm> Most of the steps described here today you'll only need to do once, unless you need to change the settings. They were:
[16:44] <dpm>  1. Setting up code hosting (in case you hadn't already)
[16:44] <dpm>  2. Setting up translations in Launchpad
[16:44] <dpm>     2.1. Telling Launchpad that it's hosting your translations (https://translations.launchpad.net/fooby/+configure-translations)
[16:44] <dpm>     2.2. Configuring permissions: recommended -> Structured, Launchpad Translators (https://translations.launchpad.net/fooby/+settings)
[16:44] <dpm>     2.3. Setting up the translations branch (https://launchpad.net/fooby/trunk/+linkbranch)
[16:44] <dpm>     2.4. Configuring imports and exports (https://translations.launchpad.net/fooby/trunk/+translations-settings)
[16:45] <dpm> So really, once your project is set up for translation, the only things you'll have to remember are:
[16:45] <dpm>   to update the template before a release,
[16:45] <dpm>   announce to translators that they can start their work,
[16:45] <dpm>   and merge the translations to your main branch.
[16:45] <dpm> If you are using the same branch for translation imports and exports, you won't even have to do that!
[16:46] <dpm> So here's a reminder on how to do these steps:
[16:46] <dpm> Updating the translation template
[16:46] <dpm> ---------------------------------
[16:46] <dpm> python setup.py build_i18n -p                   # To update the template
[16:46] <dpm> bzr commit -m"Updated translation template"     # Commit your local changes
[16:46] <dpm> bzr push                                        # Push changes to the remote branch
[16:47] <dpm>  
[16:47] <dpm> Call for translations
[16:47] <dpm> ---------------------
[16:47] <dpm> Just send an e-mail to launchpad-translators(at)losts(dot)launchpad(dot)net or to the list where the coordination of your project's translation is happening
[16:47] <dpm>  
[16:47] <dpm> Just to finish, you'll find more information on the topics covered in this session here:
[16:48] <dpm>  * https://help.launchpad.net/Translations/YourProject
[16:48] <dpm>  * https://help.launchpad.net/Translations/YourProject/BestPractices
[16:48] <dpm> So that was it! I hope you enjoyed it and that I can soon see your projects up for translation in Launchpad
[16:49] <dpm> Does anyone have any questions?
[16:49] <ClassBot> MAfifi asked: What about non-python based projects?
[16:49] <dpm> The Launchpad part is the same for those. Let's take a C project, for example
[16:50] <dpm> the only differences between languages, or rather between build systems, is how you update the template
[16:50] <dpm> In a GNOME application in C using autotools, for example, you'd just go to the po folder
[16:51] <dpm> and call intltool-update -p
[16:51] <ClassBot> MAfifi asked: What if I want to submit a translation in a language no team exists for?
[16:51] <dpm> It all depends on the permissions you've set up for your project
[16:52] <dpm> With Open and Structured permissions, the translations would just be accepted
[16:52] <dpm> With Restricted, they'd be marked as suggestions, but would not be included in the project
[16:53] <dpm> until there is a team which reviews them
[16:53] <dpm> As the maintainer, you can bypass that and do a manual upload of the translations for which there isn't a team
[16:53] <dpm> But I'd rather avoid bypassing translation teams
[16:54] <dpm> and try to find someone that can review the translations before them being accepted
[16:54] <dpm> oh, MAfifi meant for translators
[16:55] <dpm> As a translator, the same as above applies, only that you cannot bypass translation teams as a maintainer can do
[16:55] <dpm> so for Structured, it there is not a team, you'd be able to submit translations, the same as in Open
[16:56] <dpm> For Restricted, you'd be able to submit suggestions, which are recorded in Launchpad, but would not make it into the project until a team for the language is created
[16:58] <dpm> Any more questions?
[16:59] <ClassBot> apachelogger asked: how do I make my plasmoid translatable?
[16:59] <dpm> nice question, I don't think I can answer in the last minute, but we can continue on #ubuntu-translators
[16:59] <dpm> As an exchange, you get an intro:
[17:00] <dpm> ok, bye everyone, I hope you enjoyed the talk. now let's leave the room for the always awesome apachelogger and his talk on "Widgetcraft <3"
[17:00] <apachelogger> Aloha!
[17:01] <apachelogger> thank you dpm for your talk and the intro :)
[17:01] <apachelogger> welcome to an intro on Widgetcraft (imagine scary music)
[17:01] <apachelogger> ... also known as the art of creating Plasma Widgets (imagine not so scary music but thunder ;))
[17:02] <apachelogger> My name is Harald Sitter, and I am opporunistic by design.
[17:02] <apachelogger> First please make sure you have the dependencies: sudo apt-get install kdebase-workspace-bin kdebase-runtime
[17:02] <apachelogger> Also you will need a common editor.
[17:03] <apachelogger> There is a Plasma specific sort-of IDE in the works, but it has yet to see a release that I would call usable.
[17:03] <apachelogger> Please write DONE in the -chat channel once you are done installing
[17:03] <apachelogger> so I know when we can do fun things.
[17:04] <apachelogger> any more people who are not DONE yet? ^^
[17:04] <apachelogger> I think we can skip the intro and do useful things then ;)
[17:05] <apachelogger> but first let me at least outline some basics
[17:05] <apachelogger> Plasma is the technology underneath KDE's workspace components (mostly called desktop)
[17:05] <apachelogger> it comes in currently (I think) 3 favors, proper desktop, netbook sort-of desktop and mobile (yes for mobile phones)
[17:06] <apachelogger> Usually Plasma Widgets writen natively for Plasma are called Plasmoids.
[17:06] <apachelogger> Plasma can also run Apple Dashboard widgets and Google Gadgets for examples... but only Plasmoids are the real deal ;)
[17:06] <apachelogger> You can write them in either JavaScript or C++ or Ruby or Python.
[17:07] <apachelogger> However only the former two are guaranteed to be available on every system, so I recommend those.
[17:07] <apachelogger> Hence we will also use JavaScript today.
[17:07] <apachelogger> Any questions thus far?
[17:08] <apachelogger> Very well.
[17:08] <apachelogger> coding \o/
[17:08] <apachelogger> yay
[17:08] <apachelogger> hooray
[17:08] <apachelogger> woohoo
[17:08] <apachelogger> :D
[17:09] <apachelogger> A basic routine that you will almost always need when starting off with a new Plasmoid is the following:
[17:09] <apachelogger> NAME=doctor-questionmark          # Set a shell variable
[17:09] <apachelogger> mkdir -p $NAME/contents/code/     # Create everything up to the code dir.
[17:09] <apachelogger> touch $NAME/metadata.desktop      # Create the metadata file, which contains name and description...
[17:09] <apachelogger> touch $NAME/contents/code/main.js # Create main code file of the plasmoid.
[17:09] <apachelogger> You can copy this verbatim into a terminal to get started with our little example.
[17:10] <apachelogger> This will create the basic outline for any JavaScript based Plasmoid.
[17:10] <apachelogger> For other languages it is basically the same, just that the file extension of the main.js would be different :)
[17:11] <apachelogger> First let us set up the meta data. For that open the metadata.desktop file and fillit with content.
[17:11] <apachelogger> You can copy the stuff from here: http://people.ubuntu.com/~apachelogger/uadw/09.10/doctor-questionmark/metadata.desktop
[17:12] <apachelogger> As you can probably tell from looking at that file, the meta data bascially just defines name, comment, icon, author and other not all that useful information.
[17:12] <apachelogger> BUT whenever you create a new plasmoid, do not forget to change the 'Name' and 'X-KDE-PluginInfo-Name' values
[17:13] <apachelogger> those 2 get used to identify the plasmoid internally, so if you forget to change one it can easily happen that your plasmoid does not show up or loads inproperly etc. etc.
[17:13] <apachelogger> Is everyone done with the metadata.desktop?
[17:14] <apachelogger> Splendid.
[17:15] <apachelogger> And you know what, that was already all the politics ;)
[17:15] <apachelogger> We all know what comes after the politics... the code ;)
[17:15] <apachelogger> So please save the file and close it.
[17:15] <apachelogger> And open contents/code/main.js instead.
[17:16] <apachelogger> This sweet apple pie of an empty file will soon contain our beautiful code, of which I am not yet sure what it will be...
[17:16] <apachelogger> How about starting with a simple hello world?...
[17:17] <apachelogger> I will indent code lines so they are easier visible for you.
[17:17] <apachelogger>     // First create a layout we can stuff things into
[17:17] <apachelogger>     layout = new LinearLayout(plasmoid);
[17:18] <apachelogger> what is probably noteworthy at this point is that 'plasmoid' thing there, it is part of the initial environment we get in a plasmoid and by having it in brackets it becomes 'parent' of our layout
[17:18] <apachelogger> the term parent here relates to live time mostly, if the parent of an object in a plasmoid explodes, all its children will too
[17:19] <apachelogger>     // Then create a label to display our text
[17:19] <apachelogger>     label = new Label(plasmoid);
[17:19] <apachelogger> I hope until now it is still barable complicate
[17:19] <apachelogger>     // Add the label to the layout
[17:19] <apachelogger>     layout.addItem(label);
[17:20] <apachelogger> Now here is an inherted goodness, since Plasmoids are based on KDE which is based on Qt we have cool layouting features, which means for simple things we do not have to worry about layout very much.
[17:20] <apachelogger> We simply create such a layout and add items to it...
[17:20] <apachelogger> Of course something is still missing for our hello world.
[17:20] <apachelogger> Text ;)
[17:20] <apachelogger>     // Set the text of our Label
[17:20] <apachelogger>     label.text = 'Doctor ?';
[17:20] <apachelogger>     // Done
[17:21] <apachelogger> (for the record: I do like doctor who better than hello world ;))
[17:21] <apachelogger> You can now run this using plasmoidviewer $NAME (if you still have your terminal open) or plasmoidviewer PATHTOPLASMOIDFOLDER
[17:22] <apachelogger> Does everyone has a working plasmoid?
[17:23] <apachelogger> Also, there is a new trick I would like you to tell about. If you are on KDE 4.5 (default for Kubuntu 10.10) you will have a new command called 'plasma-windowed' using this command you can run most Plasmoids just like any other application in a window, is that not superb?
[17:23] <apachelogger> You can try that with our new plasmoid right now.
[17:23] <apachelogger> Or if you have the facebook plasmoid, try that
[17:23] <apachelogger> plasma-windowed facebook
[17:24] <apachelogger> Pretty neat feature.
[17:24] <apachelogger> So, lets build up on this example.
[17:24] <apachelogger> How about a button? Buttons are cool!
[17:25] <apachelogger> Just continue in the main.js
[17:25] <apachelogger>     // Create a new button
[17:25] <apachelogger>     button = new PushButton;
[17:25] <apachelogger>     // Add the button to our layout
[17:25] <apachelogger>     layout.addItem(button);
[17:26] <apachelogger> I personally have made it a habit to immediately after creating add objects to a layout.
[17:26] <apachelogger> Especially in large projects it can easily happen that you forget that and suddenly there is a button floating around somewhere where it does not belong
[17:26] <apachelogger>     // Give the button some text
[17:26] <apachelogger>     button.text = 'Do not EVER click me';
[17:26] <apachelogger> *save* the file
[17:27] <apachelogger> and try it again
[17:27] <apachelogger> It looks a bit silly, does it not?
[17:28] <apachelogger> The layout placed the button next to the text... not awesome at all... I would really like it to be below the text. Easy to do.
[17:28] <apachelogger> We just tell our layout to align stuff vertically, rather than horizontally (which seems to be the default).
[17:28] <apachelogger>     // Switch our layout to vertical alignment
[17:28] <apachelogger>     layout.orientation = QtVertical;
[17:28] <apachelogger> *save* and try again
[17:29]  * apachelogger finds it much more attractive now
[17:29] <apachelogger> everyone done?
[17:31] <apachelogger> We are pretty fast today so I am pondering a coffe break... or maybe better not.
[17:32] <apachelogger> Of course our button does not do anything (well, other then be there, sometimes that is already a lot ;))
[17:32] <apachelogger> Now what could we do to improve the situation a bit?
[17:32] <apachelogger> How about a nice image?
[17:32] <apachelogger> There is nothing like a good picture to spice up things a bit :D
[17:32] <apachelogger> First let us get the picture.
[17:33] <apachelogger> For that we will create an own 'images' folder and place our image in there, so everything stays nicely structured.
[17:33] <apachelogger> If you are still outside the doctor-questionmark folder in a terminal you can use the following command to do that:
[17:33] <apachelogger> mkdir -p $NAME/contents/images/
[17:33] <apachelogger> wget -O $NAME/contents/images/troll.png http://people.ubuntu.com/~apachelogger/uadw/09.10/data/troll.png
[17:33] <apachelogger> If not, just go to your contents folder, create the images folder in there and download the picture http://people.ubuntu.com/~apachelogger/uadw/09.10/data/troll.png into that folder
[17:34] <apachelogger> Now for the code:
[17:34] <apachelogger>     // Labels can also contain images, so we will use a label again
[17:34] <apachelogger>     troll = new Label(plasmoid);
[17:34] <apachelogger>     // But this time we set an image. The image path is constructed automatically by us telling it in what directory it is and what name it has
[17:34] <apachelogger>     troll.image = plasmoid.file("images", "troll.png");
[17:35] <apachelogger> So, we do not only have a well structured folder setup, it also makes our code more readable.
[17:36] <apachelogger> (also in case you should notice, I did intentionally not add the label to our layout, in case you have not, nevermind)
[17:36] <apachelogger>     // So that our image fits in we need to tell the label to consume as much space as possible and necessary
[17:36] <apachelogger>     troll.sizePolicy = QSizePolicy(QSizePolicyMaximum, QSizePolicyMaximum);
[17:37] <apachelogger> Usually Plasmoids will try to consume as little space as possible, this of course is a problem with a big image because then it would get cut off.
[17:37] <apachelogger> By telling our troll to try to use as much space as possible we can solve this 'problem'.
[17:38] <apachelogger>     // We only want to show the image after the user dared pressing the button, so we set it not visible and also do not add it to our layout
[17:38] <apachelogger>     troll.visible = false;
[17:38] <apachelogger> Here is the reason I did not add the image to our layout.
[17:39] <apachelogger> Instead the behaviour should be like this: user starts plasmoid, plasmoid looks nice, user is foolish enough to press button, troll comes up, user falls off chair.
[17:39] <apachelogger> What is left to make that happen is making our button actually o things.
[17:40] <apachelogger> An for that we will use a very cool feature of Qt calle signal an slot (only in a simpler version).
[17:40] <apachelogger> The basic iea is that most objects in Qt emit a signal when certain things happen.
[17:40] <apachelogger> Our button for example will emit one when it is clicked.
[17:41] <apachelogger> And those signals can be attached to so-called slots, which are basically just functions.
[17:41] <apachelogger> So we want that when the button is clicked a specific function is to be executed.
[17:41] <apachelogger>     // First add a function to handle clicking on the button
[17:41] <apachelogger>     function onClick()
[17:41] <apachelogger>     {
[17:41] <apachelogger>         // Once our button gets clicked we want to show an image.
[17:41] <apachelogger>         troll.visible = true;
[17:42] <apachelogger>         // We add the new image to our layout, so it gets properly aligned
[17:42] <apachelogger>         layout.addItem(troll);
[17:42] <apachelogger> (keep in mind, our layout is putting items below each other, so our troll will be appearing at the very bottom right now)
[17:42] <apachelogger>         // To prevent problems we set the now useless button to not visible
[17:42] <apachelogger>         button.visible = false;
[17:43] <apachelogger>     }
[17:43] <apachelogger> ^ do not forget this curly bracket there, to indicate the end of the function
[17:43] <apachelogger>     // Now we just tell our button that once it was clicked it shall run our function
[17:43] <apachelogger>     button.clicked.connect(onClick);
[17:43] <apachelogger> *save* and run again
[17:45] <apachelogger> Since bulldog98 just pointed out that the window does not resize...
[17:45] <apachelogger> Yes, that is a bug (or maybe intentional) with plasmoidviewer, the plasmoid as seen in Plasma will resize properly. In fact if you resize the plasmoidviewer window the plasmoid will look just fine.
[17:46] <apachelogger> Now since we are running out of time let us stop hacking and prepare a packge we can use to distribute our newly made Plasmoid.
[17:47] <apachelogger> Well, package is maybe a bit of an overstatement, they really are just zip files with .plasmoid as file ending.
[17:47] <apachelogger> The crucial thing that makes it work is the folder set up we used at the very beginning.
[17:47] <apachelogger> So creating a packge we can share with people we want to scare is as easy as creating a zip.
[17:48] <apachelogger> For example using the following command:
[17:48] <apachelogger> cd $NAME &&
[17:48] <apachelogger> zip -r ../$NAME.plasmoid . &&
[17:48] <apachelogger> cd ..
[17:48] <apachelogger> That again will only work if you still have the terminal with NAME set of course :)
[17:48] <apachelogger> otherwise just create a zip of the content of our folder and change the file ending.
[17:49] <apachelogger> It is however curcial that you only package the content, not the folder
[17:49] <apachelogger> You can find a finished plasmoid and the code at http://people.ubuntu.com/~apachelogger/uadw/09.10/
[17:50] <apachelogger> This .plasmoid file can either be installed via the Plasma GUI ways (i.e. like you would usually add a plasmoid) or by using the command line tool plasmapkg
[17:50] <apachelogger> e.g.
[17:50] <apachelogger> plasmapkg -i $NAME.plasmoid
[17:50] <apachelogger> either way the plasmoid should then show up in your widgets list and be ready to use \o/
[17:51] <apachelogger> So where to go from here?
[17:51] <apachelogger> Obviously this was but a simple introduction to Plasmoid programming
[17:51] <apachelogger> and also not very fancy I must say
[17:52] <apachelogger> You can however try http://people.ubuntu.com/~apachelogger/udw/10.07/trollface-6/ this plasmoid.
[17:52] <apachelogger> It basically does a very similar thing to ours but introduces fancy animations and a way to get rid of the image again.
[17:53] <apachelogger> Also at http://people.ubuntu.com/~apachelogger/udw/10.07/videos/ I created some videos which show case some basic plasmoids.
[17:54] <apachelogger> At this point I should mention that Amarok, the music player, also uses plasmoids, so it is not all that difficult to get the same plasmoid with no code changes into Amarok and Plasma at the same time (if that makes any sense)
[17:54] <apachelogger> You can find a lot more information at the Plasma community page at http://community.kde.org/Plasma
[17:54] <apachelogger> There are pointers to tutorials for all supported programming languages as well as ready to go examples.
[17:55] <apachelogger> Also, if you want to pursue writing Plasmoids in JavaScript you will need the API reference at http://techbase.kde.org/Development/Tutorials/Plasma/JavaScript/API
[17:56] <apachelogger> JavaScript is cool for simple plasmoids, but should you feel too limited by it, you can try Ruby or Python, they are not more complicated but give you greater control.
[17:56] <ClassBot> bulldog98 asked: can I simply convert your template to C++?
[17:56] <apachelogger> That depends on what you mean by convert.
[17:57] <apachelogger> You basically can use the very same program logic but you will have to adopt it to C++ code constraints.
[17:57] <apachelogger> e.g. a Plasmoid in C++ is contained within at least one class
[17:57] <apachelogger> Also you cannot do things like label.text = 'foo';
[17:58] <apachelogger> Instead you will use setter methods, like label.setText("foo");
[17:58] <apachelogger> So direct conversion is not possible, because the languages are just too difficult.
[17:59] <apachelogger> Also if you need help or have further questions feel free to drop into the Plasma IRC channel #plasma
[17:59] <apachelogger> That is it.
[18:00] <apachelogger> Good luck with creating your brilliant Plasmoids and have fun with steveire who is going to tell you about a magical thing called grantlee in a bit :)
[18:00] <apachelogger> I wonder what grantlee is anyway....
[18:00] <steveire> Hehe, you will soon find out
[18:00] <steveire> Hello everyone and welcome to my talk.
[18:00] <steveire> I am Stephen Kelly, lead developer of Grantlee and part of the KDE community, mostly working on kdepim. I am a full-time employed Qt consultant and I write and maintain Grantlee in my spare time
[18:00] <steveire> So what is Grantlee ?
[18:01] <steveire> I assume that any of you here attending the talk have done some googling to find out what it is and what it does, as the talk title is low on details.
[18:01] <steveire> Grantlee is a string template system. Such systems are common in web frameworks See more here: http://en.wikipedia.org/wiki/Template_engine_%28web%29
[18:01] <steveire> You can see in the comparison table at that link that Grantlee supports all features of most other comparable systems.
[18:01] <steveire> The only missing feature is i18n support, which should be available in a few months. That is the only open bug against Grantlee :) https://bugs.kde.org/buglist.cgi?product=grantlee
[18:02] <steveire> Grantlee is actually based on the design and syntax of the Django template system (but does not depend on Django itself)
[18:02] <steveire> It is fully implemented in QtCore and QtScript, so it can be extended with C++ and with javascript
[18:03] <steveire> It can even be used in gtk applications just by linking to QtCore and QtScript becuase Qt can run the gtk event loop
[18:03] <steveire> Packages are available for Lucid and Maverick: http://packages.ubuntu.com/search?keywords=grantlee
[18:03] <steveire> String template systems are used in web frameworks to create html markup to send to clients that request it. The template is a file containing the html that should be sent back to the browser, but with place holders for things like your username, your messages, the color that you have chosen in your profile etc.
[18:04] <steveire> Websites often use such systems for scalability and code resuse
[18:04] <steveire> On the desktop, we don't have web servers to generate html, but it is common for applications to create themed output using html. For example, Evolution email client can render the email viewer with different themes. This is done by generating different html with different css for each theme.
[18:05] <steveire> KMail also allows theming using various styles.
[18:05] <steveire> The problem with an approach like that is that the html is often hardcoded into the source code, making it difficult to change existing themes or add new themes.
[18:06] <steveire> KMail had that exact problem, and in the past there were only 6 hardcoded themes available
[18:06] <steveire> If a theme needed to be fixed or a new theme added, the application needed to be changed, compiled, packaged, and reach the distros before the fix became available to the users
[18:07] <steveire> During Summer of Code 2010 Ronny Yabar ported KMail and Akregator the RSS feed reader to use Grantlee. http://ronnyml.wordpress.com/2010/08/26/gsoc-final-report-messageviewer-kmail-and-akregator-ported-to-grantlee/
[18:08] <steveire> The project was a very useful step in the development of Grantlee becaus it shows what is possible, including sharing themes among users using GetHotNewStuff
[18:09] <steveire> Soon it can be used to create distro specific themes, such as a theme for the fluffy kde distro
[18:09] <steveire> With this change it becomes easier to fix existing themes if they are broken, and it becomes easier for third party developers to create and share themes without having to send them upstream and have them compiled into the application.
[18:10] <steveire> kde-look.org can be used to share themes already: http://kde-look.org/index.php?xcontentmode=46&PHPSESSID=ee7d4bf311c5da8621c927303587bbc3
[18:10] <steveire> There are not many available, but it shows the infrastucture is in place which is already to familiar to artists and users (opendesktop.org)
[18:11] <steveire> As a side note I would also like to say that Grantlee can generate not only HTML, but can generate any kind of text based markup - even computer code.
[18:12] <steveire> A developer could create templates for getting started creating plasmoids for example.
[18:12] <steveire> In the Grantlee examples there is an application which can generate code for IDEs in C++ python and ruby languages: http://steveire.wordpress.com/2010/04/06/using-grantlee-for-code-generation/
[18:12] <steveire> For application theming though, the more interesting use case is html generation.
[18:13] <steveire> Another application in the Grantlee examples is the books example:  http://grantlee.org/apidox/examples.html
[18:13] <steveire> We can get started by installing grantee through a package manager
[18:14] <steveire> sudo aptitude install libgrantlee-dev
[18:14] <steveire> After that we can download the grantlee source so that we can build the examples: apt-get source libgrantlee0
[18:15] <steveire> Once that is finished we can start navigating to where the examples are
[18:15] <steveire> cd grantlee-0.1.1/
[18:15] <steveire> cd examples/
[18:16] <steveire> cd books
[18:16] <steveire> The books example is derived from the books example available in Qt: http://doc.trolltech.com/4.7/demos-books.html
[18:16] <steveire> To build it we create a separate build directory.
[18:16] <steveire> mkdir build
[18:16] <steveire> cd build
[18:16] <steveire> cmake ..
[18:16] <steveire> make
[18:16] <steveire> There is no need to install it
[18:17] <steveire> The books example uses sqllite to manage a database of books. Grantlee makes it possible to create a html page from the table of data and theme it in any possible way.
[18:18] <steveire> After it is build you can run the example by executing it on the command line
[18:18] <steveire> ./books
[18:18] <steveire> The top of the application shows the books in the database, and allows managing the authors, the genre, the rating etc.
[18:19] <steveire> Near the bottom of the application you can choose a theme to use when exporting the books to a html file and an export button for doing the actual exporting.
[18:20] <steveire> If you click the export button it will ask for a location to save the html file (default to ~/book_export.html)
[18:21] <steveire> Try the export and open the file in a web browser. You will see the same data that is in the application now in the html file.
[18:21] <steveire> Try changing some of the data, like the rating or a genre and export again. You can then refresh the browser to see an updated html page
[18:22] <steveire> A html export feature like that is common in applications allowing you to export contacts for example or notes.
[18:22] <steveire> KJots has that feature too and actually uses Grantlee already for the export.
[18:23] <steveire> If you're not following along, in the screenshots you can see the generated output from a plain theme, a colored theme, and a theme that regroups the output by Author. You can also see I am not a talented artist :)
[18:24] <steveire> Using the combobox in the application you can also try out the different available themes.
[18:24] <steveire> The regrouping is possible because of a powerful system of tags and filters in the template system.
[18:24] <steveire> Grantlee has all of the same features as Django templates have, so all of the same tags are available: http://docs.djangoproject.com/en/dev/ref/templates/builtins/
[18:25] <steveire> Just so there is no misunderstanding, Grantlee does not depend on Django or on Python. Grantlee depends only on the Qt4 framework. All tags and filters are written in native Qt4 code.
[18:25] <steveire> Just like Django, Grantlee can be extended by third partes by writing new tags and filters
[18:26] <steveire> The tags and filters can't be implemented in python (yet), but can be implemented in either Qt C++ or in Javascript
[18:26] <steveire> The wide range of tags available and the fact that there are many existing developers with Django experience means that really compelling themes can be created.
[18:27] <steveire> So what does a theme file look like? There are some examples in the documentation and the links I have already given.
[18:27] <steveire> We can walk through some of the features of theme files now: http://grantlee.org/apidox/for_themers.html
[18:28] <steveire> The first example shows all the basics of template files.
[18:28] <steveire> It is possible to make comments with {# comment tags #}
[18:28] <steveire> It is possible to put placeholders into the template with {{ curly_braces }}
[18:28] <steveire> And it is possible to have more complicated structures like {% if %} condtions and {% for %} loops.
[18:29] <steveire> {% this %} is the extensible tag part of the template syntax
[18:29] <steveire> The {% for %} tag is used to loop over the book objects in the book example. http://www.gitorious.org/grantlee/grantlee/blobs/master/examples/books/themes/simple.html
[18:29] <steveire> In that template snippet, we have {% for book in books %}. books is a list of books from the database. Notice how the for loop is similiar to a python for loop, so it is familiar to people who have used python, and it is intuitive even for those that have not
[18:30] <steveire> For each book, we create a html row with <tr> tags, and put attributes of the book into the placeholders, such as {{ book.title }} and {{ book.author }}
[18:31] <steveire> This, as you would expect replaces the placeholders with the actual title and author for each row.
[18:31] <steveire> In this case book is an object, and {{ book.title }} calls the title method on the book object and puts the returned value into the placeholder.
[18:31] <steveire> Other structures apart from objects are supported, such as QHash (like a python dictionary) and QList (like a python list). For more details of what is possible see http://grantlee.org/apidox/for_app_dev.html
[18:32] <steveire> For the advanced coders, there is now even greater flexibility in the types of objects Grantlee can handle : http://steveire.wordpress.com/2010/09/29/grantlee-pairs-up-with-the-other-template-system/
[18:32] <steveire> Grantlee also supports advanced features like template including and inheriting. That allows sharing of snippets within a theme or with other themes.
[18:33] <steveire> All of the themes in the books example share a common base template which sets up the structure of the output so that all the themes are consistent
[18:34] <steveire> We can see that one in grantlee-0.1.1/examples/books/themes/base.html
[18:35] <steveire> It defines a simple html structure with a html <head> element and a <body> element
[18:35] <steveire> It also contains several elements I have not mentioned before: {% block %} elements
[18:36] <steveire> block elements are the basis for the template inheritance and reuse system.
[18:36] <steveire> The base template defines some placeholder blocks which the inheriting themes can fill, and reuse the rest
[18:37] <steveire> http://www.gitorious.org/grantlee/grantlee/blobs/master/examples/books/themes/base.html
[18:37] <steveire> Looking again to the simple theme : http://www.gitorious.org/grantlee/grantlee/blobs/master/examples/books/themes/simple.html
[18:37] <steveire> At the top it declares that it extends the template called "base.html".
[18:38] <steveire> In a complex system there could be many possible base templates to inherit from with a different structure in each.
[18:38] <steveire> The simple theme too has some block elements.
[18:39] <steveire> These ones are used to fill the place holders defined in the base.html
[18:39] <steveire> Some of them also use the keyword {{ block.super }}
[18:40] <steveire> This tells Grantlee that the block in the base template should be reused, not overridden
[18:41] <steveire> So the "My Books" part of the header is defined in the base template, and the name of the theme is defined in simple.html, and they are combined into the title as you can see in the screenshot.
[18:41] <steveire> A theme could of course decide not to use the {{ block.super }} keyword, and not get the "My Books" part.
[18:42] <steveire> It is optional to override all or no blocks in the base template
[18:42] <steveire> We can make some simple edits to the theme now.
[18:43] <steveire> Start by editing the base.html so that the title line looks like {% block title_row %}<tr style="background-color:blue"><th>Author</th><th>Title</th><th>Genre</th><th>Rating</th></tr>{% endblock %}
[18:44] <steveire> You can then re-export without rebuilding or even restarting the books application, refresh the browser and the displayed html will be updated wiht a blue background
[18:44] <steveire> See the other theme files for more simple examples of changes that you can make to the generated output.
[18:45] <steveire> Adding such a capability to an existing application is ver easy.
[18:46] <steveire> It uses the Qt QVariant and QMetaType system and supports all the basic Qt types.
[18:46] <steveire> It is actually quite similar to the way QtQuick QML is used.
[18:47] <steveire> Apart from KMail and KJots it is also used in several other code generation projects, and in a proof of concept twitter application by Ryan Paul:  http://steveire.wordpress.com/2010/05/20/grantlee-in-use/
[18:48] <steveire> That's all I have prepared. I hope it was informative for you and you can consider using Grantlee for your next application theming or code generation needs.
[18:49] <steveire> The grantlee community hangs out in the #grantlee channel on IRC
[18:49] <steveire> And is also reachable through the kdepim mailing list if you have any questions
[18:49] <steveire> kde-pim@kde.org
[18:50] <steveire> Some more useful links to get started on understanding and using Grantlee:  http://www.gitorious.org/grantlee/pages/Home http://steveire.wordpress.com/2009/06/27/some-clarifications-regarding-grantlee/ http://grantlee.org/apidox/ http://www.djangobook.com/en/2.0/chapter04/ http://steveire.wordpress.com/
[18:50] <steveire> Any documentation relevant to Django is also relevant to Grantlee, so there are lots of ideas to find on the web :)
[18:52] <steveire> Thanks for attending the talk. In a few minutes there will be a talk about enriching applications with zeitgeist data. Don't miss it :)
[19:18] <jcastro> ok, looks like Seif is having connection problems
[19:18] <jcastro> We might need to bump this class until tomorrow, please stand by!
[19:22] <jcastro> ok since Seif can't get online we'll take a break until the top of the hour
[19:22] <jcastro> so smoke if you got em!
[20:01] <flan> Well, I guess that means it's time.
[20:01] <flan> First time I've done anything like this, so please let me know if I'm getting off-topic.
[20:02] <flan> Okay, so, this is a presentation on using Quickshot, a program designed to help you write better documentation by making it easier to get screenshots.
[20:04] <flan> It's still not in Ubuntu's standard library, but it should be packaged and available by 11.04. For now, we have PPAs and Bazaar access.
[20:04] <flan> We'll be using the latter of those options for today, if anyone wishes to follow along with the client itself.
[20:04] <flan> To begin, you'll need to instal bzr, if you haven't done so already.
[20:04] <flan> I'd imagine most of you have, for some reason or other.
[20:05] <flan> If not, though, it's a simple matter of "sudo apt-get install bzr".
[20:05] <flan> Around the 10th, Quickshot will be formally packaged into its final PPA form, but we're still working through last-minute changes and bug-fixes, so it's best to work with source right now.
[20:06] <flan> I'm going to assume everyone's got bzr now.
[20:06] <flan> If not, please stop me.
[20:06] <flan> So the next step is to pull the client's source from Launchpad, where we're hosting it.
[20:06] <flan> Oh, before that, I should mention who "we" are.
[20:07] <flan> jenkins and I are Quickshot's principal authors.
[20:07] <flan> Please feel free to ask us anything after the session is over.
[20:07] <flan> To pull its source, use the command "bzr branch lp:quickshot".
[20:07] <flan> This will create a quickshot/ directory under your current path.
[20:07] <flan> You can delete it once this is done.
[20:08] <flan> This lesson, I mean.
[20:08] <flan> There's a lot of revision history, so it may take a minute or two.
[20:08] <flan> I'll use that time to spam you with information about what Quickshot it.
[20:08] <flan> is*
[20:08] <flan> It's the screenshot-capturing tool created for the Ubuntu Manual project (http://ubuntu-manual.org/); it addresses a critical issue we encountered in preparation for 10.04: our inability to capture and catalogue thousands of screenshots in a limited timeframe.
[20:08] <flan> We needed something that could ensure that we'd be able to capture screenshots in a consistent manner across languages, always have them available to drop into the documentation's build process, and allow for volunteers to help out with very little training.
[20:09] <flan> Our solution was to create a client-server system that would centralise rules and data, which formed the basis of the original Quickshot: a bunch of simple PHP scripts, text files, and a monolithic Python client cobbled together in a couple of weeks.
[20:09] <flan> The new version is far more robust.
[20:09] <flan> The server is implemented using Pylons and has the ability to scale to any number of hosted projects and languages.
[20:09] <flan> The client is Python with Glade, designed to work with any number of servers (and with plans for full internationalisation support for the next iteration).
[20:09] <flan> There's a decoupled client library that allows anyone to programmatically interact with the server, to script screenshot captures as part of a controlled build process.
[20:10] <flan> Contributor credit is logged on a per-project basis, so volunteers don't have to be anonymous if they don't want to be.
[20:10] <flan> The server provides a means of allowing any number of owners to review and accept screenshots submitted by volunteers.
[20:10] <flan> And progress reports are neatly broken up by language and stage, making gauging performance in large projects easy.
[20:10] <flan> Initially, I'd like to have everyone play the role of a volunteer, capturing a screenshot or two to learn how the process works in case you want to deploy Quickshot to support your own projects and need to train users.
[20:11] <flan> (If you never use it again, maybe you'll be able to mention it to someone who will need something like it)
[20:11] <flan> After that, anyone who's interested will be invited to hold the role of owner over what we've done today, letting you see the other half of the system.
[20:11] <flan> While we're waiting for any remaining pulls to finish, does anyone have any questions? I'll entertain them in either channel.
[20:13] <flan> Okay, I'm going to continue.
[20:13] <flan> Before I have any of you run the client, a disclaimer is in order: there is a lot of code and it has not been thoroughly peer-reviewed.
[20:13] <flan> If you do not feel comfortable trusting that what you've just downloaded is safe, you are not obligated to execute it, and you can still benefit from this lesson.
[20:13] <flan> If you're in the doesn't-fee-safe-running-unsigned-code group, please follow with the discussion and jump in again when we get to the server-management part.
[20:13] <flan> feel*
[20:13] <flan> For those willing to actively follow along, please let me know what you get when you type "echo $LANG".
[20:14] <flan> I'll add your languages to the server so you don't get any "language not supported" messages.
[20:14] <ClassBot> google-fu asked: I've tried Quickshot a while ago and from what I remember, in order to use the program you have to create a new user and log in to that user for the program to work. I find this thing annoying, is this still required?
[20:14] <flan> No, not for this demonstration.
[20:14] <flan> That's still a requirement for our parent project, the Ubuntu Manual Project.
[20:15] <flan> But it's now fully optional, and can be toggled on a per-project basis.
[20:15] <flan> Same with screen resolution.
[20:15] <flan> We won't be changing any of that stuff today.
[20:16] <ClassBot> TobiS asked: whats the line to pull Quickshot from the remote repository?
[20:16] <flan> bzr branch lp:quickshot
[20:18] <flan> Okay, I'm going to continue.
[20:18] <flan> Please paste the following command: "wget http://flan.uguu.ca:5000/appdevweek/10-10/%5Bappdevweek%5D10-10.qsproj"
[20:18] <flan> This will download a "qsproj" file, which is really just a chunk of text that tells Quickshot about a project. Live details are always pulled on connection.
[20:18] <flan> When done, type "cd quickshot/source", followed by "bin/quickshot".
[20:19] <flan> You will see some WNCK-related warnings. These are entirely benign, so don't worry about them.
[20:19] <flan> Browse for the file you just downloaded in the "Local files" section of the Quickshot window, then click "Get started!"
[20:19] <rooligan> Where to issue wget?
[20:19] <flan> In any terminal.
[20:20] <rooligan> In any directory?
[20:20] <flan> Sorry. I should have been more clear.
[20:20] <flan> Yeah. It just downloads a file.
[20:20] <flan> You may wish to join #ubuntu-classroom-chat. There's more discussion going on there.
[20:21] <flan> After a brief moment, you should see a list of six screenshots.
[20:21] <flan> If you see a message about the connection to the server timing out, that's not entirely unexpected (the server we're using today is single-threaded). Just retry or click "Reload" when you see the empty list.
[20:21] <flan> This presumes you've pointed Quickshot at the .qsproj file.
[20:21] <flan> Just in case anyone missed that part.
[20:21] <flan> You'll all also see another window in front of the list of screenshots. Feel free to enter any information you'd like, or use "anonymous@example.org" and leave the other fields blank.
[20:21] <flan> This window will only appear once. If you wish to change your settings, you can access the window under the "Edit" menu.
[20:22] <flan> Okay, now please resist the temptation to click anything.
[20:22] <flan> And let me know if I'm going too quickly.
[20:22] <flan> I'd like a volunteer who is using a non-English Ubuntu environment to help get us started.
[20:23] <flan> So, serapophis has volunteered. Yay.
[20:24] <flan> serapophis, please pick the 'gedit' screenshot by either double-clicking it or highlighting it and clicking 'Forward'.
[20:24] <flan> You'll be presented with a list of steps on the left and a message on the right saying "No reference screenshot available"; the rest of you will see something similar soon.
[20:24] <flan> Quickshot uses any accepted language's version of a given screenshot as a reference for future captures, but nothing's been accepted yet.
[20:24] <flan> Once you're comfortable with what you've been asked to do, click "Capture".
[20:24] <flan> At this point, I'd like to ask everyone else to either click the "Quickshot progress" link on their clients or visit http://flan.uguu.ca:5000/appdevweek/10-10
[20:25] <flan> You'll all see three progress bars, one for 'en', which includes 'en_US' and 'en_GB', and one for the language of our brave volunteer. And daker's crazy language. Il est fou.
[20:25] <flan> Quickshot automatically reduces languages into a parent if no specialization was declared.
[20:26] <flan> If we created en_CA, Canadian screenshots would be captured independently of American ones.
[20:26] <flan> This is for languages that have significant differences between dialects.
[20:27] <flan> Okay, so, getting back on topic, serapophis, please foloow any on-screen instructions.
[20:27] <flan> All you should see is a message telling you you have three seconds, after clicking 'OK', to give gedit focus.
[20:27] <flan> It'll automatically look at the last-activated window and try to use that if you don't explicitly give focus to any window.
[20:28] <flan> Please let us know once you're presented with a window that asks you to confirm that everything looks good.
[20:28] <flan> The rest of you will be doing this soon.
[20:28] <flan> Except you'll have the benefit of reference screenshots.
[20:29] <flan> Okay, serapophis, just click 'Submit'.
[20:29] <flan> Everyone else, reload the page I asked you to open.
[20:29] <flan> You should see progress in the de_DE field.
[20:29] <flan> ...Or maybe you won't.
[20:30] <jenkins> i was about to say the same :)
[20:30] <flan> Have you been returned to the screenshot list, serapophis?
[20:30] <flan> Okay, it might just be taking a while to upload.
[20:30] <flan> I guess I'll need to work on that. Sorry.
[20:31] <flan> The interface is supposed to freeze during the upload process, but I figured it would be graceful.
[20:32] <flan> Okay... I was able to upload an English one without issue...
[20:32] <flan> serapophis, what sort of connection do you have?
[20:34] <jenkins> i guess we can carry on with the en one I will try and work out what if it is just serapophis connection
[20:37] <flan> 13:37 <+flan> Okay, so we're a little off from where we should have been, but  can I get everyone else to try taking a screenshot for gedit now?
[20:37] <flan> You should now all see a reference screenshot on the right side of the window.
[20:38] <flan> jenkins, please take the IRC screenshot so I can let them see it, too.
[20:38] <jenkins> will do
[20:38] <flan> If you click this reference screenshot, you'll see a full-size (but JPEG-compressed, for transmission speed purposes) version of what was captured.
[20:39] <jenkins> done
[20:40] <flan> Okay, for our German users, try capturing the IRC screenshot.
[20:40] <flan> You'll now see what everyone else is seeing with Gedit.
[20:40] <flan> Feel free to take whatever screenshots you want for the next couple of minutes.
[20:41] <flan> In the meantime, I'd like everyone's OpenID. You should have one from Launchpad.
[20:41] <flan> Mine is https://launchpad.net/~red-hamsterx ; yours will be similar, only with your name at the end.
[20:41] <flan> The Quickshot server doesn't use passwords, opting instead for OpenID. The virtues of this system are the subject of another lesson, though.
[20:41] <flan> Other OpenID providers are okay, too, of course; Launchpad's probably just something you've probably all used.
[20:43] <flan> Okay, for anyone who's offered their OpenIDs, you can now log in at http://flan.uguu.ca:5000/appdevweek/10-10
[20:43] <flan> The field's in the top right.
[20:43] <flan> It should be the same process as with any other OpenID-enabled site.
[20:44] <flan> You provide your URL, your provider tells Quickshot that you're really you, and you get access.
[20:44] <flan> WARNING: Quickshot, like almost every program, has the ability to run arbitrary commands on your system. In a moment, your peers will be able to control the commands it runs. Please be sure to check the command to be executed before you capture a screenshot.
[20:44] <flan> I don't think anyone here's malicious in the slightest, but it doesn't hurt to be paranoid.
[20:45] <flan> Once you've logged in, you'll notice that there's now a new bar in the top right that says "Manage version". Each language will also be clickable.
[20:45] <flan> First, click any language with progress. You'll notice that some screenshots are in the "pending" state, which means that they can be approved or rejected.
[20:45] <flan> Please feel free to play around, but show a little restraint, since the server is, again, single-threaded, so you don't want to choke out anyone else.
[20:46] <flan> Also, this is actually running on a home connection, so please refrain form clicking the 'download archive' links; I need my bandwidth for other things.
[20:46] <flan> So, yeah, just click around.
[20:46] <flan> Submit multiple versions of pending screenshots and see what happens.
[20:47] <flan> This is what people who are managing Quickshot projects will see, allowing them to collaboratively decide what to accept and what to reject.
[20:47] <flan> (We're very open to feedback on how to make it simpler, if there's room for improvement)
[20:47] <flan> As you accept screenshots, the credit report on the project page will also be filled out.
[20:49] <flan> Once you've played around with that stuff to your satisfaction, go back to http://flan.uguu.ca:5000/appdevweek/10-10 and click 'Manage version' in the upper right.
[20:50] <flan> You can use this itnerface to add new languages (like fr_CA, for crazy Quebec types), change screenshot details, change the order of screenshots, and add new screenshots.
[20:50] <flan> Your changes will be immediately reflected on every Quickshot client.
[20:50] <flan> There's also a feature that allows to you translate a screenshot's steps, but we won't be playing with it today.
[20:51] <flan> You'll notice that 'en' doesn't appear in this section.
[20:51] <flan> That's because it's actually a property of the parent project, http://flan.uguu.ca:5000/appdevweek
[20:52] <flan> This means that every Quickshot project that's a part of AppDevWeek needs to support English.
[20:52] <flan> But de_DE and fr_FR are specific to this one week.
[20:52] <flan> Oh. Please do not toggle the username or resolution settings.
[20:52] <flan> We don't want to force anyone to create a new user account for this demonstration. That would just be mean.
[20:53] <flan> Anyway, please feel free to keep playing with the system for the next little while (I'll leave the project active for a couple of hours).
[20:54] <flan> I don't really have anything else to say or add, but I do hope you've found this informative and know that, yes, there is now a tool that exists to make putting screenshots into big documentation projects a not-so-daunting task.
[20:54] <flan> It just involves getting a bunch of volunteers together.
[20:54] <flan> We'll be launching production-ready versions of the client and server shortly after the next edition of the Ubuntu Manual is out, around the 10th of October.
[20:55] <flan> The code, and a set-up guide for the server (and maybe a brief user guide for the client) will be available at http://quickshot.org.
[20:55] <flan> If you have any questions, please ask either myself or jenkins.
[20:55] <flan> If you want to know how something was built, please ask me.
[20:55] <flan> If you want to report a bug or usability enhancement, please ask jenkins. (He's better at handling criticism. =P)
[20:57] <flan> If you know of any projects that could benefit from Quickshot, please let them know about it,.
[20:57] <jenkins> apport will still sent the logs to launchpad with out a hard crash iirc
[20:57] <flan> And let them know what we can always be found in #ubuntu-manual.
[20:57] <flan> that*
[20:57] <flan> And now I clear the stage for the next session.
[20:57] <flan> Thank you for your patience and interaction, everyone.
[20:58] <flan> Okay, so I've got the channel to myself, to bend to my twisted, evil whims.
[20:58] <flan> Excellent.
[20:58] <flan> Now I just need some twisted, evil whims.
[20:58] <flan> Anyone else want server access?
[20:59] <flan> Just costs an OpenID URL.
[20:59] <flan> (Your OpenID provider retains rights to your soul and banking information)
[21:11] <rooligan> byebye