/srv/irclogs.ubuntu.com/2011/09/09/#ubuntu-classroom.txt

=== jussi01_ is now known as jussi
=== david is now known as Guest58753
=== jussi01_ is now known as jussi
=== genupulas is now known as raju
dpmEveryone ready for the last day or UADW?15:59
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - https://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Questions in #ubuntu-classroom-chat || Event: App Developer Week - Current Session: Getting A Grip on Your Apps: Multitouch on GTK apps using Libgrip - Instructors: Satoris
dpmthe people on #ubuntu-classroom-chat say yes! :)16:00
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/09/%23ubuntu-classroom.html following the conclusion of the session.16:01
dpmHello everyone and welcome to this last edition of the Ubuntu App Developer Week16:01
=== BuZ-T is now known as BuZZ-T
dpmlots of sessions with great speakers today,16:01
dpmspeaking of which, let's give a warm welcome to Satoris, who'll be talking about adding multitouch support to your GTK+ apps with libgrip!16:02
SatorisHi all. My name is Jussi Pakkanen, and I am a member of the uTouch team at Canonical.16:03
SatorisToday I'll be talking about adding gesture support for existing apps using libgrip.16:03
SatorisLibgrip is a simple, "GTK-flavored" library for gestures.16:04
SatorisThe uTouch stack has lots of other parts as well, but I won't talk about them. If there is demand and time at the end, I can give an overview.16:04
SatorisThe first thing you might want to do is to open the libgrip tutorial page, which is here: https://wiki.ubuntu.com/Multitouch/GripTutorial16:05
SatorisI'm going to go through it so it pays to have it open. Get the code as well, it is attatched to the page.16:06
SatorisA word of warning, I'm going to describe libgrip 0.3.1 and newer.16:06
SatorisThis is not available in Natty, and won't be. So if you are using Natty, you need to compile libgrip from source.16:07
SatorisThere is also a known bug in Oneiric's libgrip. We pushed a fix to that some 20 minutes ago.16:07
SatorisSo it should be available soon.16:08
SatorisThe main things to know about libgrip are device types and subscriptions.16:09
SatorisThere are three different kinds of devices: touchscreens, touchpads and independent devices (Apple Magic Mice).16:09
SatorisWhenever you say you want certain types of gestures, you create a subscription.16:10
SatorisSo the basic structure of a libgrip application is to subscribe to gestures, such as "one finger drags on touchscreens" or "two finger rotates on any device".16:11
SatorisWhen these gestures are performed, libgrip calls your callback functions.16:11
SatorisIt is very similar to how GTK sends "redraw" or "mouse motion" events.16:11
SatorisI forgot to mention that libgrip 0.3 requires GTK 3.0. You can't use it on GTK+ 2 apps.16:12
SatorisBut who has those anymore. :)16:12
SatorisThe subscription is describe on the tutorial page under "subscription".16:13
SatorisIt is very straightforward.16:14
SatorisIn the tutorial all subscriptions have the same callback function.16:14
SatorisYou can have different ones, it does not really matter.16:15
SatorisPeople seem to prefer having one and then demultiplexing stuff by themselves.16:15
SatorisIn the test app we have a viewport and we want to be able to move it around with finger drags.16:16
SatorisSo we subscribe two finger drags for all devices and also one finger drags for touchscreens.16:17
SatorisVery simple.16:18
SatorisThe gesture callback function is also quite straightforward.16:18
SatorisWe check how much the user has dragged and update the viewport correspondingly.16:19
SatorisHowever there is one thing to note.16:19
SatorisWhen dragging on a touchpad, the scroll directions need to be changed.16:20
SatorisThis is because historically dragging down on a touchpad moves the "document" up.16:20
SatorisThis is something that may change in the future, newest OSX has the option to make drags on touchpad the same as on touchscreens.16:21
SatorisLibgrip does not invert the axes for you, because it can't know whether you are dragging an object or scrolling a view.16:22
SatorisThis is the app developer's responsibility.16:23
SatorisThe rest of the code is pretty standard GTK.16:24
SatorisSo in this case adding gestures took a couple of dozen of lines of code.16:24
SatorisFor a more complicated example, I recommend you to look at the gesture patches for Evince and EOG.16:25
SatorisThey can be found in the respective oneiric source packages.16:25
SatorisThis means that the oneiric's EOG and Evince will be gesture enabled out of the box.16:26
SatorisThose patches have drags, document rotations and pinch to zoom.16:28
SatorisSubscribing to gestures is quite simple, but there are certain things that will most likely surprise you.16:29
SatorisThe main thing being that gestures that human beings make are rarely pure.16:29
SatorisSimply dragging two fingers along most likely triggers pinches or rotations as well.16:30
SatorisThat is because the human beings are not robots, at least not yet.16:30
SatorisTheir fingers move involuntarily, even if they try to keep them steady.16:31
SatorisUnfortunately it is impossible to differentiate between "drag only, but fingers get slightly rotated accidentally" and "drag with a touch of rotation" in the general case.16:32
SatorisSo again, the app developer has to do work here.16:33
SatorisUsually it is best to design the UI so that spurious events do not matter.16:34
SatorisThe basic guideline is that the gesture recognition stack can not read the user's mind. That is the job of an app developer.16:35
SatorisAnother thing to note is that trackpads especially have very different sizes.16:36
SatorisA basic mini-laptop's touchpad is only about one quarter (or less) of a MacBook Pro's touch pad.16:37
SatorisSo you really have to consider these things when dealing with, e.g. pinch sensitivity.16:38
SatorisAnd on the other hand if you want your app to be used on a touch screen, those are even bigger.16:38
SatorisAnd the last thing: you should probably never subscribe to single finger drags on touchpads.16:40
SatorisThat grabs the mouse pointer, because one finger drags are mapped to mouse motion.16:40
SatorisThat's roughly what I had prepared. I'm open for questions.16:42
ClassBottomalan asked: The MacBook Pro touchpad can distinguish between "tap" and "click". Is libgrip also capable of this?16:44
SatorisIf by "click" you mean pushing the pad so that it produces a mouse click, then yes.16:45
SatorisPushing it so hard that it produces the clicking sound, that is.16:45
SatorisI use a Macbook for development (and am using it at this very moment) and have set it up so that taps do not produce mouse clicks and you use two fingers for scrolling.16:46
SatorisRather than using the edge for scrolling.16:47
SatorisYou can get the taps by subscribing to the GRIP_GESTURE_TAP event.16:48
SatorisI'm not sure what happens if you have set it up so that tapping the pad lightly causes a mouse click.16:49
SatorisI find that behaviour hugely irritating and always disable it as the first thing I do.16:50
ClassBottomalan asked: In OSX i also like the feature that i open the context menu by "clicking" with two fingers and if I keep clicked and move to the menu entry and then release the selected menu entry gets activated. Do you know if it's possible to configure Ubuntu to behave the same?16:50
ClassBotThere are 10 minutes remaining in the current session.16:50
SatorisYou can set up Ubuntu so that clicking with two fingers creates a right-click. That brings up a context menu most of the time.16:51
SatorisThis behaviour might even be the default. Not sure though.16:51
SatorisYou have to release one finger to be able to select stuff on the menu.16:53
ClassBottomalan asked: I meant that i keep the pad pressed with one finger, navigate to my target with the other one and the release the second finger to activate the entry, so i don't have to click twice16:53
SatorisThis needs some plumbing and code changes that are not present currently AFAIK. But we will work on these issues in the next cycle.16:54
ClassBotThere are 5 minutes remaining in the current session.16:55
SatorisLast chance for questions.16:58
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - https://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Questions in #ubuntu-classroom-chat || Event: App Developer Week - Current Session: Creating a Google Docs Lens - Instructors: njpatel
dpmthanks Satoris for a great session!17:00
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/09/%23ubuntu-classroom.html following the conclusion of the session.17:00
njpatelHi! My name is Neil Patel, I'm the System Architect in the Canonical Desktop Experience (DX) Team and I am also the Technical Lead for the Unity project. I'd like to talk today about the massive changes we've done to the Lens infrastructure in Unity this cycle, with an introduction to writing a simple Google Docs Lens & Scope!17:01
njpatelAlthough I have a rough outline for at least the first half of this session, feel free to ask questions in #ubuntu-classroom-chat as you have them, and I'll answer as soon as it makes sense :)17:01
njpatelI should add, all the information here, and much more, will be available on https://wiki.ubuntu.com/Unity/Lenses later on today and across the weekend.17:01
njpatelSo, a quick history on Lenses: They started off being named "Places", and they were, in Natty, little daemons that would show up on your Launcher and allow you to search through Applications/Files/AskUbuntu/Gwibber etc.17:02
njpatelAlthough Lenses in that form were pretty good, we wanted them to be more powerful (as did the Lens authors!) so for Oneiric we decided that we should swallow our pride and re-archtect them to provide more features, and make it easier to add new features later on i.e. make a base API that we can carry forward through 12.04 and beyond.17:02
njpatelSo, people who are currently re-writing their Places as Lenses, sorry :) We promise it won't be this bad again!17:02
njpatelOne of the largest changes we made to the Lenses was to split out the concept of what controls the renderering/filters of a Lens to what provides data. In essence, we wanted to be able to make a Lens be able to just define it's properties, but then let anything be able to provide data to the Lens.17:02
njpatelSo, the job of a Lens is to create an Lens instance, add some categories, add some filters and thats it, it no longer does any searching of it's own. So what does the searching? Scopes!17:03
njpatelScopes are the engine of the Dash. They plug into Lenses over D-Bus and then provide data to the Lens.17:03
njpatelThis is best described in an example: We now ship a Music Lens by default in Oneiric. It ships with a Banshee Scope which provides search results for Banshee. However, instead of being stuck with a usesless Lens because you use Amarok or Rhythmbox (or you having to create an alternative Lens for your favourite music player), you can just create the Amarok or Rhythmbox Scope for the Music Lens.17:03
njpatelThe Scope would plug right into the Lens, providing results from Amarock in the main Lens.17:03
njpatelAlso, a Lens is not confined to having only one Scope. The Music Lens could easily have a Banshee Scope, a GrooveShark Scope, a Spotify Scope etc. So you can search multiple data sources from one Lens, just install the ones you like :)17:04
njpatelDue to not many people likely to want to ship a Lens by itself without a Scope (wouldn't be very useful!) we have made it easy for you to ship a default Scope with your Lens, without having to create an extra daemon, and you'll see this later on.17:04
njpatel 17:04
njpatelThe largest user-visible change we made for a Lens is it can now create Filters17:05
njpatelFilters allow the user to easily, er, filter the search results17:05
njpatelWe ship with four filters by default: CheckOption, RadioOption, MultiRange and Ratings17:05
njpatelYou can create as many as you'd like, and show/hide them as needed17:06
njpatelThe filters API is meant to be easy to use and we hope to add more filters in the 12.04 cycle17:07
njpatel(we'd love to hear ideas!)17:07
njpatelwoah, lag :)17:08
njpatelAndy80 asked: how do we control how the data found by a scope is displayed? The Lens provide the filters, ok... but can I design the view and incorporate it into the dash?17:09
njpatelThe Lens controls how the results are displayed per-category17:09
njpatelSo, we ship with a vertical or horizontal orientation for the results, but we really would like to see more17:09
njpatelThe complexity comes in that the results are rendered by Unity, and so must be written with Nux17:10
njpatelWe'd happily accept new renderers and are planning to add some whizzbang ones for 12.04!17:10
njpatel 17:11
njpatelOn that point, the two most important things a Lens will do is add Filters and Categories to itself17:11
njpatelWe spoke about filters (and will come back to that in the example), so i should cover Categories17:12
njpatelCategories are headings inside the dash when you search for something inside a Lens17:12
njpatele.g. the Apps lens has "Most Frequently Used", "Installed" and "Apps Available for Download"17:13
njpatelWhen you want to add a result to the results model inside a Scope, you tell Unity which category to put the result in. If a Category has no results, Unity will not show it17:14
njpatelWe normally add three Categories, but there is no limit17:14
njpatelthree just seems to fit nicely in the way Unity renderers the Dash :D17:14
ClassBotAndy80 asked: how do we control how the data found by a scope is displayed? The Lens provide the filters, ok... but can I design the view and incorporate it into the dash?17:15
njpatelwoops17:15
ClassBotAndy80 asked: I suppose we will have to write two different Lens (one for Unity and one for Unity-2D) but since the Scope exposes data trough an API/d-bus ecc... is the same Scope usable on both versions of Unity?17:15
njpatelAny Lens you write works fine with both Unity and Unity-2D, they share the same code for talking to Lenses17:16
njpatelThis is because a Lens does not contain any specific UI code (i.e. gtk or Qt or Nux), it just requests that a category should use the horizontal tile, for instance, and it's up to the Unitys to render it correctly17:17
njpatelIt's actually one of my favourite things about Lenses/Scopes, they are purely data with requests for renderering, the actual renderering is handled elsewhere and therefore can be changed to match it's environment (i.e. searching your lenses from a webpage ;)17:18
njpatel<Andy80> njpatel: so they can be written in any language? C, C++, Python, Vala ecc...?17:18
njpatelYep17:18
njpatelDue to this boundary between the renderering-side (Unity) and the data side(Lenses or Scopes), you can write them in any language17:19
njpatellibunity (the library you use to write them in) is a GObject library with full GObject introspection support17:19
njpatelit also means, C++ Unity can have a Vala Applications Lens which has a Python Freedesktop-menus Scope and a Javascript Web Apps Scope :)17:20
njpatelwe like that :D17:20
njpatel 17:21
njpatelOkay, so the other important thing is for Unity to actually find the Lens17:21
njpatelfor this, you need to choose a "id" for your lens i.e. Music lens = "music", Google Docs Lens = gdocs17:22
njpatelyou use that id and install your .lens file in /usr/share/unity/lenses/$id/$id.lens17:22
njpatelThis is an example .lens file: http://paste.ubuntu.com/685980/17:22
njpatelWe use DBus activation to start a lens, so you also need to install a .service file into /usr/share/dbus-1/services17:23
njpatelwith the .lens file, Unity can start up, have a look at what lenses are installed, be able to load their icon etc, and then, when the user does  a search, activate the Lens daemon (which will in turn activate it's scopes)17:24
njpatelif you are writing a Scope, you have a Scope file which only contains the DBusName and DBusPath attributes and you install it in the Lens's folder in /usr/share/unity/lenses17:25
njpatelyou'll also need a dbus .service file as Scopes are also started with dbus activation17:26
njpatel 17:26
njpatelAs I mentioned earlier, we recognise that there are not many Lenses that people would like to ship which don't have at least one Scope readily available to make it useful17:26
njpatelWhat we didn't want was to  have you jump through hoops to create .scope files, .service files and a new binary just for this, so we have a little function that allows you to ship a Lens daemon with an in-built Scope easily17:27
njpatelthis does't stop other Scopes from plugging into your Lens, but just lets you get up-and-running much more easily17:28
njpatel 17:28
njpatelSo, for this session I had originally wanted to write a  Scope for the Music lens, but ran into some difficulty with getting an API key for an OSS project (urgh), so I decided to be a bit daring and started a Google Documents Lens + Scope using Python (a language which we did not have support for until this morning!)17:29
njpatelThe code is available at lp:unity-lens-gdocs17:30
njpatelbut I have some pastes of the a few stages of the code which I thought would be useful to go over17:30
njpatelSo, the first commit I did looked something like: http://paste.ubuntu.com/685979/17:31
njpatelI should say, excuse any bad python in there, I'm a C/C++ guy :)17:31
njpatel 17:32
njpatelSo, from line 2717:32
njpatelYou can see we create the Lens object17:32
njpatelhopefully the properties we set are obvious enough17:33
njpatelbut you have some top-level control here over your Lens, like whether you want it to show in the global search results17:33
njpatelwhat the search hint is, etc etc17:33
njpatelthen the first two important things are done17:33
njpatelpopulate_filters() does exactly what it says on the tin17:34
njpatelAs in the comments, I love the RadioOption filter as it's one of the easiest to use :)17:34
njpatelCheckOption, RadioOption and MultiRange filters are all "OptionFilter" sub-classes in libunity. This type of filter is basically one which can have multiple options in it, and an option can be active or inactive17:35
ClassBotAndy80 asked: you defined both scope + lens in that single python code?17:36
njpatelYep, I'm using the lens.add_local_scope() method to have my Lens be automatically useful when installed without having to also ship a separate scope in the package17:37
njpatelthis does mean that my lens and scope are in the same process, and this might be okay for some lenses and not okay for others, you would need to judge that yourself17:37
njpateldue to this Lens being very much tied to a single service, having the scope ship with the lens and in the same process is fine17:38
njpatelMy goal is to make gdocs lens also ship a scope for the files lens, if you'd just like to search all files in one lens17:38
njpatelbut this is a good enough example for now  :)17:38
njpatel 17:38
njpatelSo, the filters you add here are synced with Unity (so it knows what to display) and also down to the Scopes (so they can query them during search)17:39
njpatelI'll show you how the Scope uses the filters during a search later on17:39
njpatelAs mentioned, check, radio and multi-range work very similarly, the Ratings filter is the simplest, providing you with a rating of 0.0 to 1.0 depending on how many stars the user has clicked17:40
njpatelUsing the visible property on a filter, you should be able to show/hide filters depending on which other options are clicked17:41
njpatelbe a bit careful, though, i don't think either Unity has a nice transition for that change yet, so it might surprise the user a bit!17:41
njpatel 17:42
njpatelso, in populate_categories() we add the categories we'd like to use17:42
njpatelfor each category, we can choose and icon, set it's name and choose how we'd like it rendered17:43
njpatelThe order in which you add these categories is the numbering you use in the Scope when adding a result. So, for the first category, the integer you'd use when adding the result would be 017:44
njpatelusually an enum would be best to make your code readable for others and yourself down the line!17:44
njpatelcoming back up, if you ignore line 46 & 47, calling lens.export() would get you ready for Scopes that want to plug in and ready fro Unity to start showing/search your lens17:45
njpatelif you plan on making a Lens and separate scopes, this is all you need to do17:45
njpatelhowever, for our GDocs lens we want to also provide some results from GDocs (as we're not really expecting anything else to plug into such a specific Lens)17:46
njpatel 17:46
njpatelso, looking at lines 46 & 47, we can see we create a class that internally creates a Scope, and then inform our Lens that a "local scope" exists i.e. tell it that there is a scope that doesn't have a .scope file and cannot be activated, but is actually in the same process as itself17:47
njpatel 17:48
njpatelOkay, so looking at the UserScope class17:48
njpatelMy idea is to give this Lens the ability to handle multiple google accounts (say work + personal), so i've encapsulated the logic of talking to a single account into one class and one scope17:48
njpateltherefore, when I do add support for multiple accounts, I'll be creating a UserScope for each, and calling lens.add_local_scope() for each too17:49
njpatelthe start of the __init__ of the class mostly deals with the gdata bits17:49
njpatelline 129 onwards does the fun stuff, namely it creates the Scope by telling the Unity.Scope class where to export it's internal dbus object17:50
ClassBotThere are 10 minutes remaining in the current session.17:50
njpatelafter that, it connects to two signals to know when the normal search and global search changes17:50
njpatelwe keep them different, including two different results models, as we fully expect the Lens to behave a bit differently with global search versus with normal search. A good example of this is that a normal search will take into account filters but the global one won't17:52
njpatelmoving on, you can see there are some methods to grab the search string and then just one method to actually update the results, either global or normal17:52
njpatelin update_results_model(), we have a placeholder that just grabs all the documents and throws it in the results model, it doesn't deal with the search string yet17:53
njpatelso, the next thing would be to get it to do that17:54
njpatelhttp://paste.ubuntu.com/685988/17:54
njpatelthat is the diff for making the Scope  actually search17:54
njpatelas you can see, we now take into account the global search (though as we are not doing any filtering we can still keep it simple when searching)17:54
njpatelthe rest of the diff is mostly just constructing a good gdata search URI17:55
njpatelrunning out of time!17:55
ClassBotThere are 5 minutes remaining in the current session.17:55
njpatelmoving on, this http://paste.ubuntu.com/686007/ shows us responding to filters17:55
njpatelif you look at apply_filters()17:56
njpatelYou can see that, for each filter that we know/care about, we query the scope to get the Filter object, and then we query the filter to see what the current active option is17:57
njpatelhowever, we only do this if we are not doing a global search17:57
njpatelthe "id" property of the filter is the same as what the Lens set when creating the filter. Through this mechanism, you can always be sure you are reacting to the correct filter17:58
njpatelalso you can see I changed the filters a bit so I could be a bit lazy with ids :)17:59
njpatelso, we're at the end, it would have been good to have more time but I'll be updating the wiki page with lots more info17:59
njpatelhttps://wiki.ubuntu.com/Unity/Lenses17:59
njpatelalso, I'll be continuing to develop this lens if you want to subscribe to the branch on Launchpad to keep up!18:00
dpmthanks a lot njpatel, that was awesome!18:00
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - https://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Questions in #ubuntu-classroom-chat || Event: App Developer Week - Current Session: Practical Ubuntu One Files Integration - Instructors: mterry
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/09/%23ubuntu-classroom.html following the conclusion of the session.18:00
dpmtalking of which, next up mterry will be talking about connecting your apps to the cloud with ubuntu one :)18:01
mterryHello everybody!  Thanks njpatel!18:01
mterrySo I'm Michael Terry, an Ubuntu developer as well as the developer of Deja Dup, a backup program18:01
mterryI recently added support for Ubuntu One to my program, and I thought I'd share how that went, and some simple examples of how to connect to Ubuntu One Files18:02
mterryI have lots of notes for this session here: https://wiki.ubuntu.com/mterry/UbuntuOneFilesNotes11.1018:02
mterryWhich you may be interested in going through as I talk18:02
mterryPlease ask questions any old time18:02
mterrySo, for this session (and for my purposes with Deja Dup), I only needed simple file functionality18:03
mterryget, put, list, delete basically18:03
mterrySo we'll go through each of those basic ideas to help anyone else that's interested in integrating do so easily18:03
mterryWe'll use Python, since that's most convenient18:03
mterrySo let's create together a simple python script that can do basic file operations with U118:04
mterryYou'll need an updated ubuntuone-couch package from Ubuntu 11.1018:04
mterryI've backported it in my PPA18:04
mterryFor this sessoin18:04
mterrySo if you want to play along at home, but are stuck on Ubuntu 11.04, please do the following:18:04
mterrysudo add-apt-repository ppa:mterry/ppa218:05
mterrysudo apt-get update18:05
mterrysudo apt-get upgrade18:05
mterryThat will give you a new ubuntuone-couch18:05
mterrySo to start, let's write a super simple Python script that can just accept an argument18:05
mterry===18:05
mterry#!/usr/bin/python18:05
mterryimport sys18:05
mterryif len(sys.argv) <= 1:18:05
mterry  print "Need more arguments"18:05
mterry  sys.exit(1)18:05
mterryprint sys.argv[1:]18:05
mterry===18:05
mterryVery basic.  We'll augment this with more in a second18:05
mterrySave that as u1file.py18:06
mterryAnd open a terminal in that same directory18:06
mterryThe first thing you have to do when interacting with U1 is make sure the user is logged in18:06
mterryThere is a helper library for that in ubuntuone.platform.credentials18:06
mterryIt's designed to work with Twisted and be asynchronous18:06
mterryBut we just want simple synchronous behavior for now18:07
mterrySo I'll show you a function that will fake synchronousity by opening an event loop and waiting for login to finish18:07
mterry===18:07
mterry#!/usr/bin/python18:07
mterryimport sys18:07
mterry_login_success = False18:07
mterrydef login():18:07
mterry  from gobject import MainLoop18:07
mterry  from dbus.mainloop.glib import DBusGMainLoop18:07
mterry  from ubuntuone.platform.credentials import CredentialsManagementTool18:07
mterry  global _login_success18:07
mterry  _login_success = False18:07
mterry  DBusGMainLoop(set_as_default=True)18:07
mterry  loop = MainLoop()18:07
mterry  def quit(result):18:07
mterry    global _login_success18:07
mterry    loop.quit()18:08
mterry    if result:18:08
mterry            _login_success = True18:08
mterry  cd = CredentialsManagementTool()18:08
mterry  d = cd.login()18:08
mterry  d.addCallbacks(quit)18:08
mterry  loop.run()18:08
mterry  if not _login_success:18:08
mterry    sys.exit(1)18:08
mterryif len(sys.argv) <= 1:18:08
mterry  print "Need more arguments"18:08
mterry  sys.exit(1)18:08
mterryif sys.argv[1] == "login":18:08
mterry  login()18:08
mterry===18:08
mterryThis may be easier to see on the wiki page https://wiki.ubuntu.com/mterry/UbuntuOneFilesNotes11.10#Logging_In18:08
mterryThe important bit is from ubuntuone.platform.credentials import CredentialsManagementTool18:08
mterryfollowed by18:08
mterry   cd = CredentialsManagementTool()18:08
mterry   d = cd.login()18:08
mterryThe rest is just wrappers to support the event loop18:08
mterryAnd to support calling "python u1file.py login"18:08
mterrySo try running that now, and you should see a neat little U1 login screen18:09
mterryUnless...  You've already used U1, in which case, nothing happens (because login() doesn't do anything in that case)18:09
mterrySo let's add a logout function for testing purposes18:09
mterry===18:09
mterrydef logout():18:09
mterry  from gobject import MainLoop18:09
mterry  from dbus.mainloop.glib import DBusGMainLoop18:09
mterry  from ubuntuone.platform.credentials import CredentialsManagementTool18:09
mterry  DBusGMainLoop(set_as_default=True)18:09
mterry  loop = MainLoop()18:09
mterry  def quit(result):18:09
mterry    loop.quit()18:09
mterry  cd = CredentialsManagementTool()18:09
mterry  d = cd.clear_credentials()18:09
mterry  d.addCallbacks(quit)18:09
mterry  loop.run()18:09
mterryif sys.argv[1] == "logout":18:09
mterry  logout()18:10
mterry===18:10
mterryNow add that to your script and you can call "python u1file.py logout" to go back to a clean slate18:10
mterryOK.  So we have a skeleton script that can talk to U1, but it doesn't do anything yet!18:10
mterryLet's upload a file18:10
mterryOh, whoops18:10
mterryFirst, we have to make sure we create a volume18:10
mterryIn U1-speak, a volume is a folder that can be synchronized between the user's computers18:10
mterryBy default, new volumes are not synchronized anywhere18:11
mterryBut let's create a testing volume so that we can upload files without screwing anything up18:11
mterryNote that the "Ubuntu One" volume always exists18:11
mterryCreating a volume is a simple enough call:18:11
mterry===18:11
mterrydef create_volume(path):18:11
mterry  import ubuntuone.couch.auth as auth18:11
mterry  import urllib18:11
mterry  base = "https://one.ubuntu.com/api/file_storage/v1/volumes/~/"18:11
mterry  auth.request(base + urllib.quote(path), http_method="PUT")18:11
mterryif sys.argv[1] == "create-volume":18:11
mterry  login()18:11
mterry  create_volume(sys.argv[2])18:12
mterry===18:12
mterryYou'll see that we make a single PUT request to a specially crafted URL18:12
mterryThere is no error handling in my snippets of code.  I'll get into how to handle errors at the end18:12
mterryAdd that to your u1file.py, and now you can call "python u1file.py create-volume testing"18:12
mterryIf you open http://one.ubuntu.com/files/ you should be able to see the new volume18:12
mterryCongratulations if so!18:13
mterryYou'll also note that I included a call to login() before creating the volume18:13
mterryThis was to ensure that the user was logged in first18:13
mterryYou'll also note that I made this weird auth.request call18:13
mterryThis is a wrapper function provided by ubuntuone-couch that handles the OAuth signature required by U1 to securely identify the user18:14
mterryThis is why you had to log in first18:14
mterryAnd the 11.10 version has some important fixes, which is why I backported it for this session18:14
mterryOK, *now* let's upload a file18:14
mterry(any questions?)18:14
mterryUploading is a two-step process18:14
mterryFirst, we tell the server we want to create a new file18:15
mterryThen the server tells us a URL path to upload the contents to18:15
mterryI'll give you the code then we can talk about it18:15
mterry===18:15
mterrydef put(local, remote):18:15
mterry  import json18:15
mterry  import ubuntuone.couch.auth as auth18:15
mterry  import mimetypes18:15
mterry  import urllib18:15
mterry  # Create remote path (which contains volume path)18:15
mterry  base = "https://one.ubuntu.com/api/file_storage/v1/~/"18:15
mterry  answer = auth.request(base + urllib.quote(remote),18:15
mterry                        http_method="PUT",18:15
mterry                        request_body='{"kind":"file"}')18:15
mterry  node = json.loads(answer[1])18:15
mterry  # Read info about local file18:15
mterry  data = bytearray(open(local, 'rb').read())18:16
mterry  size = len(data)18:16
mterry  content_type = mimetypes.guess_type(local)[0]18:16
mterry  content_type = content_type or 'application/octet-stream'18:16
mterry  headers = {"Content-Length": str(size),18:16
mterry             "Content-Type": content_type}18:16
mterry  # Upload content of local file to content_path from original response18:16
mterry  base = "https://files.one.ubuntu.com"18:16
mterry  url = base + urllib.quote(node.get('content_path'), safe="/~")18:16
mterry  auth.request(url, http_method="PUT",18:16
mterry               headers=headers, request_body=data)18:16
mterryif sys.argv[1] == "put":18:16
mterry  login()18:16
mterry  put(sys.argv[2], sys.argv[3])18:16
mterry===18:16
mterryThere are three parts to this18:16
mterryFirst is the request to create a file18:16
mterryWe give a URL path and PUT a specially crafted message "{'kind':'file'}"18:16
mterryThen, we read the local content18:16
mterryAnd push it to where the server told us to18:16
mterry(this is the "content_path" bit)18:16
mterryThe response from the server (and the specially crafted message we gave it) is called JSON18:16
mterryIt's a special format for encoding data structures as strings18:17
mterryLooks very Python-y18:17
mterryThe 'json' module has support for reading and writing it18:17
mterryAs you can see18:17
mterryWe also use a different base URL for uploading the content18:17
mterryWe use "files.one.ubuntu.com"18:17
mterrySo now, let's try this new code out:18:18
mterry"python u1file.py put u1file.py testing/u1file.py"18:18
mterryThis will upload our script to the new testing volume we created18:18
mterryAgain, you can visit the U1 page in your browser and refresh it to see if it was created18:18
mterryIf so, congrats!18:19
mterryAlso note that we had to specify the content length and content type18:19
mterryThese are mandatory18:19
mterryI calculated both in my example (using the mimetypes module)18:19
mterryBut if you already know the mimetype, you can skip that bit of course18:19
mterryOK, let's try downloading the script we just uploaded18:20
mterryThis is very similar, but uses GET requests instead of PUT ones18:20
mterryAgain, two step process18:20
mterryWe first get the metadata about the file, which tells us the content_path18:20
mterryAnd then we get the content18:20
mterry===18:20
mterrydef get(remote, local):18:20
mterry  import json18:20
mterry  import ubuntuone.couch.auth as auth18:20
mterry  import urllib18:20
mterry  # Request metadata18:20
mterry  base = "https://one.ubuntu.com/api/file_storage/v1/~/"18:20
mterry  answer = auth.request(base + urllib.quote(remote))18:20
mterry  node = json.loads(answer[1])18:20
mterry  # Request content18:20
mterry  base = "https://files.one.ubuntu.com"18:21
mterry  url = base + urllib.quote(node.get('content_path'), safe="/~")18:21
mterry  answer = auth.request(url)18:21
mterry  f = open(local, 'wb')18:21
mterry  f.write(answer[1])18:21
mterryif sys.argv[1] == "get":18:21
mterry  login()18:21
mterry  get(sys.argv[2], sys.argv[3])18:21
mterry===18:21
mterryNothing ground breaking there18:21
mterryAgain, we hit files.one.ubuntu.com for the content18:21
mterryAnd again, there is no error checking here18:21
mterryWe'll get to that later18:21
mterryLet's try to download that script we uploaded18:21
mterry"python u1file.py get testing/u1file.py /tmp/u1file.py"18:21
mterryThis will put it in /tmp/u1file.py18:22
mterryNow let's see what we downloaded18:22
mterry"less /tmp/u1file.py"18:22
mterryIt should look right18:22
mterrySo we can create volumes, upload, and download files18:22
mterryBig things left to do are list files, query metadata, and delete files18:23
mterryLet's start with listing18:23
mterry===18:23
mterrydef get_children(path):18:23
mterry  import json18:23
mterry  import ubuntuone.couch.auth as auth18:23
mterry  import urllib18:23
mterry  # Request children metadata18:23
mterry  base = "https://one.ubuntu.com/api/file_storage/v1/~/"18:23
mterry  url = base + urllib.quote(path) + "?include_children=true"18:23
mterry  answer = auth.request(url)18:23
mterry  # Create file list out of json data18:23
mterry  filelist = []18:23
mterry  node = json.loads(answer[1])18:23
mterry  if node.get('has_children') == True:18:23
mterry    for child in node.get('children'):18:23
mterry      child_path = urllib.unquote(child.get('path')).lstrip('/')18:23
mterry      filelist += [child_path]18:23
mterry  print filelist18:23
mterryif sys.argv[1] == "list":18:23
mterry  login()18:23
mterry  get_children(sys.argv[2])18:23
mterry===18:23
mterryThis is very similar to downloading a file18:23
mterryBut we add "?include_children=true" to the end of the request URL18:23
mterryThen we grab the list of children from the JSON data returned18:24
mterryblack_puppydog has noted that my ubuntuone-couch backport has a bug preventing it from working right18:25
mterryI will prepare a new package18:25
mterryBut you can fix it by doing the following18:25
mterrysudo gedit /usr/share/pyshared/ubuntuone-couch/ubuntuone/couch/auth.py18:26
mterrySearch for ", disable_ssl_certificate_validation=True" near the bottom18:26
mterryAnd remove it18:26
mterrySorry, I really thought I had tested with that18:26
mterryI've uploaded a fixed package, but it will take a few minutes to build18:27
mterrySo to download the complete file we've got so far...18:27
mterrygrab it here: https://wiki.ubuntu.com/mterry/UbuntuOneFilesNotes11.10?action=AttachFile&do=view&target=6.py18:27
mterryI'll give everyone a few seconds to catch up18:28
mterrySave that 6.py file as u1file.py18:28
mterryAnd do the following commands to get to the same state:18:28
mterrypython u1file.py login18:28
mterrypython u1file.py create-volume testing18:28
mterrypython u1file.py put u1file.py testing/u1file.py18:29
mterrypython u1file.py get testing/u1file.py /tmp/u1file.py18:29
mterrypython u1file.py list testing18:29
mterryReally sorry about that18:29
mterryNote that if you are working on a project that needs to work in 11.04 but you still want this functionality18:30
mterryYou can just locally make a copy of ubuntuone-couch's auth.py file and use it in your project (as long as the license is compatible of course)18:30
mterryOK, I'm going to wait just a moment longer to let people catch up and re-read the file now that it will actually work when they run it18:31
mterrySo when you run "python u1file.py list testing" you should get a list of all the files you put there18:31
mterryWhich I expect will just be the one u1file.py file18:32
mterrySo now, let's see if we can't get a bit more info about that file18:32
mterrySometimes you'll want to query file metadata18:32
mterryThis is very much like downloading18:32
mterryBut without getting the actual contents18:32
mterry===18:32
mterrydef query(path):18:32
mterry  import json18:32
mterry  import ubuntuone.couch.auth as auth18:32
mterry  import urllib18:32
mterry  # Request metadata18:32
mterry  base = "https://one.ubuntu.com/api/file_storage/v1/~/"18:32
mterry  url = base + urllib.quote(path)18:32
mterry  answer = auth.request(url)18:32
mterry  node = json.loads(answer[1])18:33
mterry  # Print interesting info18:33
mterry  print 'Size:', node.get('size')18:33
mterryif sys.argv[1] == "query":18:33
mterry  login()18:33
mterry  query(sys.argv[2])18:33
mterry===18:33
mterryAdding that to your file will let you call "python u1file.py query testing/u1file.py"18:33
mterryYou should see the size in bytes18:33
mterryThere is a bit more metadata available (try inserting a "print node" in there to see it all)18:33
mterryAnd the last big file operation we'll cover is the easiest18:33
mterryDeleting files18:34
mterry===18:34
mterrydef delete(path):18:34
mterry  import ubuntuone.couch.auth as auth18:34
mterry  import urllib18:34
mterry  base = "https://one.ubuntu.com/api/file_storage/v1/~/"18:34
mterry  auth.request(base + urllib.quote(path), http_method="DELETE")18:34
mterryif sys.argv[1] == "delete":18:34
mterry  login()18:34
mterry  delete(sys.argv[2])18:34
mterry===18:34
mterryThat's simple.  Merely an HTTP DELETE request to the metadata URL18:34
mterryThis covers the basic file operations you'd want to do18:34
mterryI promised I'd talk about error handling18:34
mterrySo behind the scenes, this is all done using HTTP18:34
mterryAnd the responses you get back from the server are all in HTTP18:35
mterrySo it makes sense that to check what kind of response you got, you'd use HTTP status codes18:35
mterryYou may be familiar with these18:35
mterryTo look at a status code, with the above examples, you'd do something like:18:35
mterryanswer = auth.request(...)18:36
mterrystatus = int(answer[0].get('status'))18:36
mterryanswer is a tuple of 218:36
mterryThe first bit is HTTP headers18:36
mterryThe second is the HTTP body18:36
mterrySo we're asking for the 'status' HTTP header here18:36
mterryAny number in the 200s is an "operation succeeded" message18:36
mterryThere are a few important status codes to be aware of18:36
mterry400 is "permission denied"18:36
mterry404 is "file not found"18:37
mterry503 is "servers busy, please try again in a bit"18:37
mterry507 is "out of space"18:37
mterryYou may also just receive a boring old 500 status18:37
mterryThis is like an "internal error" message18:37
mterryWhich isn't very helpful, but usually you are also given an Oops ID to go with it18:37
mterryoops_id = answer[0].get('x-oops-id')18:38
mterryIf you give this to the U1 server folks, they can tell you what happened and fix the bug18:38
mterrySo if you're going to print a message for the user, include that so that when they report the bug, you'll have the Oops-ID to hand over18:38
ClassBotblack_puppydog asked: how about checksums? this is needed for example in dejadup, right?18:39
mterryOne piece of metadata is "hash"18:40
mterryThat the server will give you18:40
mterryI actually have not used that, so I don't know what checksum algorithm it uses18:40
mterryBut you can also just download the file and see (which is what Deja Dup does)18:41
mterrySee https://one.ubuntu.com/developer/files/store_files/cloud/18:41
mterryFor a list of other metadata pieces you can get from the server18:41
mterryThat also has other useful info.  It's the official documentation for this stuff18:41
mterryIf anyone is interested, the Deja Dup code is actually in duplicity, a command line tool that Deja Dup is a wrapper for18:42
mterryhttp://bazaar.launchpad.net/~duplicity-team/duplicity/0.6-series/view/head:/duplicity/backends/u1backend.py18:42
mterryThat's real code in use right now18:42
mterryIf you ever have a problem playing with this stuff, the folks in #ubuntuone are very helpful18:43
mterryWith Oops that you run into or whatever18:43
mterryAnd that's all I have!  I'll hang around for questions if there are any18:44
ClassBotblack_puppydog asked: this file you used here, shouldn't that be some sort of library?18:46
mterryblack_puppydog, yeah, it very well could be18:46
mterryYou mean, some sort of library supported by the U1 folks to make this all easier?18:46
mterryWell...  They've already provided a lot of the code around it.  I think their intention is to focus on providing the best generic API (the web HTTP one) that all sorts of devices and languages can use.18:46
mterryI think they'd be happy to see an awesome Python wrapper library, but I don't think they want to maintain and promote one such library at the expense of others18:47
mterryThis is close, it would just need much better error handling and such18:47
mterryBut I also don't want to maintain it  :)18:47
mterryBut really, it's not *that* much code.  A bit boiler plate, true18:48
mterryubuntuone-couch takes care of most of the icky parts that are hard to do well (OAuth authentication)18:48
mterryMost languages have REST and OAuth libraries that can be used in conjunction to talk to the servers18:49
ClassBotThere are 10 minutes remaining in the current session.18:50
mterryblack_puppydog makes a good point in the chat channel.  The duplicity code has better error handling than I've presented.  So it may be a better jumping-off point to just steal wholesale than the script we've built here18:51
mterryNote that it is licensed GPL-2+18:52
mterrySo if that's not appropriate, maybe just whip something similar up yourself18:52
=== cscarney_ is now known as cscarney
ClassBotThere are 5 minutes remaining in the current session.18:55
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - https://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Questions in #ubuntu-classroom-chat || Event: App Developer Week - Current Session: Publishing Your Apps in the Software Center: The Business Side - Instructors: zoopster
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/09/%23ubuntu-classroom.html following the conclusion of the session.19:00
=== jpugh is now known as zoopster
zoopsterOk then...sorry for the delay...I thought I was being smart, but I wasn't!!!19:05
zoopsterHi everyone. My name is John Pugh. I'm responsible for business development for the Ubuntu Software Center.19:05
zoopsterWhat does that mean? Well it means I'm trying to find new and interesting content, apps, games, etc for inclusion in the paid marketplace of the Ubuntu Software Center.19:06
zoopsterWe have several very cool games in there right now - Braid, SpaceChem, Uplink, Oil Rush, etc.19:06
zoopsterAs well as some magazine titles...Ubuntu User19:07
zoopsterI'm working with some large 3D game engine companies, HTML5 application developers, several publishers, as well as trying to get every linux supported application, game, or content I can into the Software Center.19:07
zoopsterHopefully...this session will explain some of the workings from a business side...so throw out the questions if you have 'em and I'll answer as I go along19:08
zoopsterOur goal is to have a large catalog of apps that are useful to those who use Ubuntu desktop.19:08
zoopsterWe've already heard from Anthony about MyApps on the Ubuntu Developer Portal19:08
zoopsterhttps://wiki.ubuntu.com/MeetingLogs/appdevweek1109/PublishingAppsInSoftwareCenterMyApps19:08
zoopsterachuni went over the details of submitting an app...it's quite straightforward19:09
zoopsterand we heard from Stephane about ARB and it's use of the MyApps portal.19:09
zoopsterhttps://wiki.ubuntu.com/MeetingLogs/appdevweek1109/PublishingAppsInSoftwareCenterARB19:09
zoopsterstgraber talked about how the ARB can take advantage of the MyApps portal, too. So everyone can have a single place to submit new applications no matter how they are licensed.19:10
zoopsterI want to talk about the "business side" of the MyApps portal.19:10
zoopsterThere really isn't much to it, but I can at least introduce the terms and what you can expect from us19:11
zoopsterFor edification, we have the https://developer.ubuntu.com portal and a application submission portal called MyApps at https://myapps.developer.ubuntu.com19:11
zoopsterThe Ubuntu Developer Portal is about to be refreshed with a new look and new content so keep your eye out for it. John Oxton and David Planella discussed it on Thursday.19:11
zoopsterI didn't see a direct link to that session posted yet, but the link to it will be on the wiki shortly.19:12
zoopsterFor this session I want to talk about submitting paid applications that will show up in the "For Purchase" area of the Ubuntu Software Center.19:12
zoopsterI'm fairly certain that Anthony covered it in his session, but generally the submission process is 5 steps.19:12
zoopsterYou have to register (if you don't have a Launchpad.net account already) and accept the terms of service, then you are able to submit a new package.19:13
zoopsterOnce submitted, the packaging team will package up your application or verify the packaging source if you submitted debian source with your package.19:13
zoopsterI think jml talked about pkgme in one of the sessions earlier this week...that will eventually be part of the process to help automate some of the packaging needs.19:14
zoopsterCurrently packaging of application submissions is a manual process so it does take time to get your package through the system because of that manual setp19:15
zoopsteror step even19:15
zoopsterOnce the app is packaged it goes through a QA and returns back to the submitter for them to make it visible on the software center.19:15
zoopsterOk enough of that...if you need more details on the application submission process...take a look at Anthony's session.19:16
zoopsterThe business terms are simple. We help package the app, we host the app, we provide the payment service via pay.ubuntu.com19:16
zoopsterWe will return 80% of the purchase price after any applicable taxes to the developer.19:16
zoopsterPayments are processed quarterly at present and payments are via paypal19:17
zoopsterThe developer can change the price anytime they wish - the minimum price we can accept is US$2.9919:17
zoopsterI'm cruising right along....any questions so far?19:18
zoopsterWe only allow non-DRM, non-licensed applications at present. Anthony mentioned the work his team is doing on licensing/activation keys19:19
zoopsterThe "For Purchase" section of the Ubuntu Software Center is a "blind channel".19:20
zoopsterDue to the plethora of privacy rules/laws worldwide and Canonical's privacy policy we cannot release any user identifiable information to the developer.19:20
zoopsterSo it works very similarly to Apple's AppStore and the Android Marketplace at present19:21
zoopsterWe are able to consume nearly any content...and will allow apps with adverts or in-app purchases (which apple does not allow) and will allow "free" clients for online games (think minecraft)19:22
zoopsterWe can also accept HTML5 apps19:23
zoopsterWhat we cannot accept currently are trial (try before you buy) apps19:23
zoopsterand we cannot take demo's yet...but you can link to the demo and such via the text in the description19:24
zoopsterOnce the application is submitted you are able to "unpublish" the application at any time19:25
zoopsterThis will remove the visibility from the Software Center, but the application will continue to be available for those who have already purchased it19:25
zoopsterOnce published on the Ubuntu Software Center you can link to the app directly and that link will launch the Software Center desktop application and present the app to the user for purchase19:26
zoopsterthe url is simply http://apt.ubuntu.com/p/<pkgname>  - pretty slick.19:27
zoopsterSo mterry asked a question...there has been tepid interest in the program. It has only been "open beta" for about 3 weeks...previously it was not available unless we specifically added the dev to the beta19:30
zoopstermterry: prior to the myapps portal being opened...I was the primary "motivator" to get applications submitted19:31
zoopstermterry: now we are averaging a new app everyday and that is picking up.19:31
zoopsterand the 3rd part mterry everyone so far has been very happy with it...they are getting good sales numbers, the process was simple and they have a whole new market available to them!19:32
zoopstermterry: might want to clarify your "2nd" question not sure what you mean there19:34
zoopsteroh wait...mterry you mean seeing for purchase apps in the Oneiric beta for example19:34
ClassBotmterry asked: As a developer, always living in the development version, I'd like access to For Purchase apps earlier in the dev cycle (usually they are turned off until RC or whatever).  Is that possible?19:36
zoopsterhah...nice19:36
zoopstermterry: right now we're smoke testing the apps...they are not specific to any release so it's possible that we can just make them visible as the dev's test the next release19:37
ClassBotmterry asked: How happy are users?  Obviously it hasn't been available long, and you can't give specific numbers, but are we seeing the same thing the humble bundles saw, that Linux users are willing to pay money for games/apps, contrary to popular thought?19:37
zoopstermterry: another good one...the user feedback so far has been good...they are keen to purchase the apps, but we're not seeing the numbers like the humble bundle overall19:38
zoopstermterry: we are seeing similar numbers to the linux side though...it correlates relatively well19:38
ClassBotpaglia_s asked: what about updates? updates can be submitted always or they need to wait for the next cycle like for free apps?19:39
zoopsterpaglia_s: updates can be submitted anytime - once we package we can show or help with an update - the process is not as clean as submitting a new app, but we'll allow updates19:39
zoopsteroil rush is a good example...it's in "beta" pre-order mode and we're about to finish up an update19:40
zoopsterthe user will receive notice as they do with other apps and can accept the update...new installs will get the updated app directly19:40
zoopsterI hope we'll get a cleaner process to give "beta" users access earlier to the apps....we're working on it now so we'll shoot to have some if not all for purchase apps ready for the 12.04 beta19:43
ClassBotmterry asked: How is developer perception of Ubuntu vs other distros?  Is Ubuntu perceived as the top tier distro to support?19:43
zoopsterah19:44
zoopstermterry: when it comes to linux and desktop apps, we're top tier for sure19:45
zoopstermterry: you'd be surprised about that pie...it's growing quite rapidly...especially with android coming on scene...that has opened the eyes of dev's.19:45
zoopstermterry: while mobile rules right now, it's relatively simple for them to support a bigger screen with ubuntu once they have a android app done19:46
ClassBotmterry asked: Is it possible to talk about where we hope to be against other platforms?  Do we eventually want developers to think, "I have to support Win, Mac, Android, and Ubuntu?"19:46
=== afb_ is now known as afb
zoopstermterry: the goal is to have a catalog of apps that are useful to the Ubuntu user base...we have some large targets for growth as you know19:47
zoopstermterry: we do want them to think at least Win, Mac, Android, Linux...Ubuntu would be the ideal situation, yes19:47
zoopstermterry: right now the focus is on any and all linux supported applications that we can support with what we currently have available19:48
zoopstermterry: however the goal is just that...prove that Linux and specifically Ubuntu is a platform of choice and have developers look at Ubuntu and linux as a necessary platform to support19:49
ClassBotmterry asked: Is there any idea that we might want to try to get "exclusives" for Ubuntu?19:50
ClassBotThere are 10 minutes remaining in the current session.19:51
zoopstermterry: sure...would love to - we do have a few that are making some specific "extras" for ubuntu and we're getting some dev's running "specials" as well19:51
zoopstermterry: short answer is yes. I think it's a little early to attempt something like that, but for 12.04 you may see some interesting things along those lines19:52
zoopsterWow...great questions...19:53
ClassBotmterry asked: Are magazines and/or books much of a focus?  I see we have Ubuntu User.  Android recently upgraded their store for books as a top tier item.  Obviously books on Ubuntu devices is a bit different than Android...19:53
zoopstermterry: we have Ubuntu User right now and there are others that are interested19:54
zoopstermterry: so yes...that is a focus as well...stay tuned.19:55
ClassBotThere are 5 minutes remaining in the current session.19:55
zoopstermterry: and yes...books are a different animal...and publishers are VERY protective of their copyrights so there's a bit of work to dothere19:56
zoopsterOthers questions?19:56
ClassBotpaglia_s asked: there isn't a section for books, do you plan do add it?19:56
zoopsterpaglia_s: we've asked for it, but it won't be available in 11.10 as far as I know19:57
zoopsterpaglia_s: it's a topic for UDS though19:57
ClassBotblack_puppydog asked: are there "subcategories" for books planned/implemented in the new softwarecenter? so for example ubuntuuser could get an own category19:57
zoopsteranswered that one...19:58
ClassBotmterry asked: Are you finding that we want to be doing more Software Center features to support new store capabilities(like special book support, support for marketing promotions, etc)  faster than the 6 month cycle can support?19:58
zoopstermterry: yes...but we are limited to the current cycles for the back end processes19:58
zoopstermterry: and the client side too19:58
ClassBotpaglia_s asked: what about deals? are them publicized by something like "20% off for x time"?19:59
zoopsterpaglia_s: no...but they could by editing the description19:59
zoopsterpaglia_s: the dev can change the price anytime they wish...and edit the description anytime as well although the desc edit requires review (you can hit me up and I can change it)20:00
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - https://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Questions in #ubuntu-classroom-chat || Event: App Developer Week - Current Session: Writing an App with Go - Instructors: niemeyer
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/09/%23ubuntu-classroom.html following the conclusion of the session.20:00
niemeyerHello everyone!20:01
niemeyerSorry for interrupting the amazing set of questions zoopster :)20:01
niemeyerSo, I'm here to talk about how to develop apps in Go today20:02
niemeyerThis is the Go language not the game board obviously20:02
niemeyerhttp://golang.org20:02
niemeyerI'll be using an Etherpad over the conversation to put content20:02
niemeyerPlease follow up here:20:03
niemeyerhttp://pad.ubuntu.com/ep/pad/view/ro.vJnRUh5vWNI/latest20:03
niemeyernigelb, pleia2: Can we have that in the topic?20:03
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - https://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Questions in #ubuntu-classroom-chat || Event: App Developer Week - Current Session: Writing an App with Go - Instructors: niemeyer http://pad.ubuntu.com/ep/pad/view/ro.vJnRUh5vWNI/latest
niemeyerPlease feel free to ask any questions as I go.. I'll be happy to talk20:04
niemeyerI don't have a specific script in mind, so I'll be happier to solve doubts and to talk to you than to be in a monologue presenting the language20:04
niemeyerThere's plenty of material online to follow, and I'll be providing some pointers20:04
niemeyerSo let's make the most of our time here to exchange ideas and solve questions20:04
niemeyerSo20:05
niemeyerMy name is Gustavo Niemeyer, and I'm responsible for the area of Amazing And Unknown Projects at Canonical20:05
niemeyerWas pushing Landscape for several years, and then when it started to get well known I moved to the Ensemble project20:06
niemeyerhttps://landscape.canonical.com, https://ensemble.ubuntu.com20:06
niemeyerNow Ensemble is getting well known, but I think I'll stick for a little longer ;-)20:06
niemeyerLittle more than a year and a half ago I started playing with Go in my personal time20:07
niemeyerNot really expecting much20:07
niemeyerI've been doing that with every other language for a while.. Haskell, Erlang, Java, etc20:07
niemeyerPython was the last language to hook me up for a long time as the "preferred whenever possible" choice20:07
niemeyerAfter I started some projects with Go, though, I started to really appreciate what was there20:08
niemeyerIt didn't really hook me up for any _specific_ feature, though20:08
niemeyerWhat's most amazing about it is really the sum of the parts20:08
niemeyerIn fact, it's a pretty simple language20:08
niemeyerSo most aspects you'll see there will be a "Ah, but that's done elsewhere too" moment20:08
niemeyerand that's surely the case20:08
niemeyerThe detail is precisely that it's putting all of those things in _one_ language20:09
niemeyerIn a very nice to digest fashion20:09
niemeyerFor instance,20:09
niemeyerGo is statically compiled, but has good reflection capabilities20:09
niemeyerIt also has what I like to call "static duck typing"..20:09
niemeyerIf you've used Python or similar languages before, you know what I mean by that..20:10
niemeyerIn Python, you just provide a value to a function, say, and expect that the function will handle it correctly20:10
niemeyerSo any method that has, say, a read( ) method, can be provided to a method that calls value.read()20:11
niemeyerIn Go, there are interfaces20:11
niemeyerBut they're not like interfaces in languages like Java, for instance20:11
niemeyerif you declare an interface like this:20:11
niemeyertype Validator interface { IsValid() bool }20:11
niemeyerYou can use that to declare a function..20:12
niemeyerfunc MyF(v Validator) { println(v.IsValid()) }20:12
niemeyerand any objects at all that define such a method can be used20:12
niemeyerthey don't have to _declare_ that they implement the Validator interface.. they simply do as long as they have the right methods20:12
niemeyer...20:13
niemeyerAnyway20:13
niemeyerThat's called structural typing, btw.. if you fancy CS20:13
niemeyerA few other factors of the top of my head..20:13
niemeyerGo is20:13
niemeyer- Garbage collected20:13
niemeyer- Capable of producing good tracebacks20:14
niemeyer- Debuggable with gdb20:14
niemeyer- Has an easy to use module/package system20:14
niemeyerHmm.. lots of leavers :)20:15
niemeyerMaybe I should get into some action.20:15
niemeyerLet's get it working then.20:15
niemeyerFirst thing, you'll need to install the language20:16
niemeyerIt's available in Oneiric20:16
niemeyerIf you're using an older release, there is a PPA available20:16
niemeyerSupporting down to Lucid20:16
niemeyersudo add-apt-repository ppa:gophers/go20:16
niemeyersudo apt-get update20:17
niemeyersudo apt-get install golang20:17
niemeyerJust the last command for Oneiric20:17
niemeyerNow, let's produce a hello world example..20:17
niemeyerI'll guide you towards having a sane environment that you can evolve from, rather than just a quick and dirty one20:17
niemeyerSo, create a directory:20:18
niemeyermkdir ~/gopath20:18
niemeyerand export the variable:20:18
niemeyerexport GOPATH=~/gopath20:18
niemeyerThis instructs goinstall that you want to be using that directory for installing programs and packages20:18
niemeyerNow, let's create a source directory for our program20:19
niemeyermkdir -p ~/gopath/src/example.com/mycmd20:19
niemeyercd ~/gopath/src/example.com/mycmd20:19
niemeyerWhen you host your source code, you'll have only that last bit withing the revision control, usually20:20
niemeyerthe example.com is just namespacing the import.. it'll become more clear as we go on20:20
niemeyerSo, you're now within that directory20:21
niemeyerLet's type the following on that file (on the fly! ugh)20:21
niemeyerpackage main20:21
niemeyerimport "fmt"20:21
niemeyerfunc main() {20:21
niemeyer    fmt.Printf("Hello world\n")20:21
niemeyer}20:21
niemeyerPut that within a main.go file20:21
niemeyerThe name is actually not important20:22
niemeyerNow, if you type this command:20:22
niemeyergoinstall example.com/mycmd20:22
niemeyerYou should get mycmd within ~/gopath/bin/mycmd20:22
niemeyerTry to execute it20:22
niemeyerCongratulations!20:23
niemeyerYou've just run your first Go program :-)20:23
niemeyerLet's go a bit further to understand what we're doing20:23
niemeyerStill within ~/gopath/example.com/mycmd20:23
niemeyerLet's create a second file called util.go20:24
niemeyerand type this within it:20:24
niemeyerpackage main20:24
niemeyerfunc Hello() {20:24
niemeyer    println("Hello there!")20:24
niemeyer}20:24
niemeyerNow, edit your main.go, and replace the Printf(...) with this:20:25
niemeyer    Hello()20:25
niemeyerand try the command again:20:25
niemeyergoinstall example.com/mycmd20:25
niemeyerYou'll get an error regarding "fmt" not used.. simply remove the line import "fmt"..20:26
niemeyerand try again20:26
niemeyerAnyway.. the point I'm trying to make is this:20:26
niemeyerAll files within a single package in Go are part of the same namespace20:26
niemeyerYou can name files as you wish20:27
niemeyerThey're just organizational20:27
niemeyerNow, let's get a bit fancier..20:27
niemeyerLet's introduce a package20:27
niemeyerLater we'll be playing with concurrency a bit too..20:27
niemeyerSo.. let's create our package directory20:28
niemeyermkdir -p ~/gopath/src/example.com/mypkg20:28
niemeyercd ~/gopath/src/example.com/mypkg20:28
niemeyerAgain, same idea20:28
niemeyerFiles are just for organization..20:28
niemeyerLet's name ours as hello.go20:28
niemeyerOpen hello.go within mypkg and put this content there:20:29
niemeyerpackage mypkg20:29
niemeyerfunc Hello(ch chan string) {20:29
=== yofel_ is now known as yofel
niemeyer    println("Hello", <-ch)20:30
niemeyer    println("Hi as well", <-ch)20:30
niemeyer}20:30
niemeyerLet me copy & past locally to follow20:30
niemeyerAlright..20:31
niemeyerWe have a package!20:31
niemeyerOne very interesting detail:20:31
niemeyerThis package is within its own namespace..20:31
niemeyerWe can only access Hello() because it starts with a capital cased letter20:32
niemeyerThis is the way Go differentiates private from exported variables, constants, functions, methods, etc20:32
niemeyerIn all of those cases, capital case == exported20:32
niemeyerAt first this feels a bit strange, but it has a pretty interesting consequence:20:32
niemeyerEvery _usage_ of any of those things makes it clear if what's being used is public or not20:33
niemeyerSo.. let's go..20:33
niemeyerGo back to our command20:33
niemeyercd ~/gopath/example.com/mycmd20:33
niemeyerAnd type this new code in there:20:33
niemeyerWithin file main.go, that is:20:33
niemeyerpackage main20:33
niemeyerimport "example.com/mypkg"20:34
niemeyerfunc main() {20:34
niemeyer    ch := make(chan string)20:34
niemeyer     go mypkg.Hello(ch)20:35
niemeyer    ch <- "Joe"20:35
niemeyer    ch <- "Bob"20:35
niemeyer}20:35
niemeyerIf I didn't screw up, you can run this now:20:35
niemeyergoinstall example.com/mycmd20:36
niemeyerand then20:36
niemeyer~/gopath/bin/mycmd20:36
niemeyerTry that out20:36
niemeyerI made a mistake, which I'll mention in a bit, but first let's go over what just happened20:37
niemeyerWe imported the package "example.com/mypkg"20:37
niemeyerThis causes goinstall to look for this package, *download* it if necessary, compile, and install it20:38
niemeyerYou can check that this is indeed the case by listing: ls ~/gopath/pkg/*/*20:38
niemeyerYou should get a mypkg.a inside it20:39
niemeyerThis is your package example.com/mypkg compiled into binary form20:39
niemeyerThen, we've called the Hello() function within it20:40
niemeyerBut we haven't simply called it20:40
niemeyerThe "go" keyword we've used ahead of the function call instructs the compiler that the function call should be put in the background20:40
niemeyerSo mypkg.Hello() was running concurrently with your main() function20:40
niemeyerThen the statement20:41
niemeyer  println(..., <-ch)20:41
niemeyerWill block in the channel receive expression (<-ch) before a value is available for consumption20:41
niemeyerwhich is exactly what we did next in main()20:41
niemeyerch <- "Joe" sends a value20:41
niemeyerThe mistake I made in that case, is that the main() function is not waiting for the concurrently running function to terminate20:42
niemeyerThere are tricks that may be used for this, such as20:42
niemeyerselect{}20:42
niemeyerThen, in case you wanted to actually publish that code to be easily consumable,20:43
niemeyeryou could put the code within Launchpad or Github20:43
niemeyerExactly as it is20:43
niemeyerJust put the content of "mypkg" for instance within the trunk of a project launchpad.net/mypkg20:43
niemeyerAnd people will be able to "goinstall launchpad.net/mypkg"20:43
niemeyerSo.. that's a quick introduction to the language..20:44
niemeyerBut there's a _lot_ more to talk about it20:44
niemeyerunfortunately I cna't type that fast and we don't have as much time :)20:44
niemeyerSo I'll provide some resources20:44
niemeyerAnd open to questions20:44
niemeyerThe main site is the key documentation point:20:45
niemeyerhttp://golang.org20:45
niemeyerThere's _very_ good introductory documentation there..20:45
niemeyerI recommend the Getting Started, Tutorial, and Effective Go, in that order20:45
niemeyerYou should be quite proficient after that20:45
niemeyerWell.. or able to use it at least..20:45
niemeyerProficiency comes with practice20:46
niemeyerI'm one of the external contributors of the language as well, so I'll be happy to answer deeper questions which I'm happy to be familiar with in case you have any20:46
niemeyerSo, that was it.. please shoot the questions..20:46
niemeyerOr maybe not.. :-)20:47
niemeyerAlright.. I guess I'm alone in here. :-)20:49
niemeyerThanks for attending, and please drop me a message if you have questions.20:49
niemeyer#go-nuts in this same server is also a good place to talk about it.20:50
niemeyerI'll be happy to answer questions in the -chat as well20:50
ClassBotThere are 10 minutes remaining in the current session.20:51
=== jsjgruber is now known as Guest4606
ClassBotThere are 5 minutes remaining in the current session.20:55
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - https://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Questions in #ubuntu-classroom-chat || Event: App Developer Week - Current Session: Qt Quick At A Pace - Instructors: donaldcarr_work
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/09/%23ubuntu-classroom.html following the conclusion of the session.21:00
donaldcarr_workGood evening21:02
donaldcarr_workMy name is Donald Carr, I am a PSO engineer with Nokia in Sunnyvale.21:02
donaldcarr_workI joined Trolltech in Oslo in 2005, and left for a brief sabbatical as a Qt customer working on a Skypesque client (for 2 years) in New York before relocating to the Bay Area office.21:02
donaldcarr_workI work on various embedded targets, track Qt's development across the breadth of the framework and am one of the parents of http://www.qtmediahub.com/ which is one of the largest QML projects I am aware of outside of Intel's tablet (1.2) UX stack.21:03
donaldcarr_workI work with many commercial customers who ship embedded Linux based products21:03
donaldcarr_workEmbedded Linux is almost ubiquitous in embedded devices21:03
donaldcarr_workQt is very strong in the Linux space, and the Webkit/DirectFB acceleration in particular have placed us primely in the STB (Set top box) market21:04
donaldcarr_workI am here today to discuss QtQuick21:04
donaldcarr_workThis is a very laxly structured talk, and we can adjust the content to peoples needs21:04
donaldcarr_workbasically I have hacked on and around QML a fair amount21:04
donaldcarr_workand rather than just showing people trivial examples21:05
donaldcarr_workwill cover:21:05
donaldcarr_workWhat QtQuick is21:05
donaldcarr_workHow you can get hacking on it21:05
donaldcarr_workHow you can use it in your projects or large projects21:05
donaldcarr_workGotchas/strengthes associated with it21:05
donaldcarr_workForgive my shoddy spelling, I am cut and pasting half of the material, live tapping the rest of it21:06
donaldcarr_workFeel free to rain questions down on me21:06
donaldcarr_workMy question queue is empty21:06
donaldcarr_workand I feel neglected :)21:06
donaldcarr_workI would suspect/hope that people would have questions out of the gate21:07
donaldcarr_workI have no clue how big my audience is21:07
donaldcarr_workand at what level to pitch my talk21:07
donaldcarr_workWe can deal with hairy QML issues if you want, feel free to direct questions to me at any point21:07
donaldcarr_workI will start with introducing QtQuick to the unitiated21:07
donaldcarr_workuninitiated21:07
donaldcarr_workQtQuick is an umbrella term used to refer to QML and the associated tooling. QML is a declarative markup language with tight bindings to javascript which enables you to rapidly create animation rich pixmap orientated UIs.21:08
donaldcarr_workThere has been a fair amount of controversy surrounding QML21:08
donaldcarr_workPeople seem to think it is too focused on mobile devices, and that it is less suitable for desktop usage21:09
donaldcarr_workI would contest this, and will hopefully have justified our hard emphasis on the usefulness of this tech by the end of this session21:09
donaldcarr_workIn order to get you hacking on this, let me step you through getting this on Ubuntu21:10
donaldcarr_workqt-sdk is available in the Ubuntu 11.04 repos21:10
donaldcarr_workin order to grab it, all you have to do is run21:10
donaldcarr_worksudo apt-get install qt-sdk21:10
donaldcarr_work(It will pull in all dependencies, if you want just grab Qt Creator and the required subset of packages for Qt development)21:10
donaldcarr_workPlease be advised, the SDK version shipped with 11.04 is a little long in the tooth at this point21:11
donaldcarr_workand you can grab binaries for 32/64bit Linux here http://qt.nokia.com/downloads/21:11
donaldcarr_workOur website will provide you with Qt SDK version 1.1.3 (Qt Creator 2.3.0, Qt 4.7.4) which includes its own updating mechanism and will have infinitely superior QML tooling.21:12
donaldcarr_workI was hoping this was going to be an interactive session21:12
donaldcarr_workI am one of the parents of: http://gitorious.org/qtmediahub21:12
donaldcarr_workThis project is an attempt to recreate the look and feel and a subset of the functionality that XBMC provides21:13
donaldcarr_workThe functionality we provide is basically everything Qt/QML gives us for free21:13
donaldcarr_worknamely accelerated multimedia playback21:13
donaldcarr_workand a heavily pixmap centric layouting engine21:14
donaldcarr_workAs mentioned, I am heavily involved with aiding people in using Qt in their set top boxes, and demonstrating its performance, readibility and high level accessibility is incredibly valueable21:15
donaldcarr_workYou can check out the whole project21:15
donaldcarr_workor simply browse the QML code here:21:15
donaldcarr_workhttp://gitorious.org/qtmediahub/confluence/trees/master21:15
donaldcarr_workThis code is for the primary skin21:16
donaldcarr_workand I can happily explain/walk you through any points of interest you may have21:16
ClassBotteemperor asked: ok, some question, is qml only a language/tool for guis or for whole applications?21:17
donaldcarr_workteemperor: There is no theoretical limitation which confines it to gui usage21:17
donaldcarr_workteemperor: Any person who starts a QML application will find themselves exposing a great set of Qt functionality to QML in order to use it, so there is certainly merit to dealing with non-gui elements in QML21:18
donaldcarr_workteemperor: It is not hard to imagine headless apps written using QML21:18
donaldcarr_workteemperor: That said, one of the nicest things about it is the way the bindings allow for relatively layouting21:19
donaldcarr_workIf you look at XBMC skins21:19
donaldcarr_workYou will see they are fundementally simple skins with a very limited number of relatively placed items21:19
donaldcarr_workThey are far less like widget based applications and far more distance friendly21:20
donaldcarr_work(10 foot UIs?)21:20
ClassBotniemeyer asked: Is there any good path today/in the works to have QML handled by a C program?21:21
donaldcarr_workniemeyer: No, there is no straight forward way to do this21:22
donaldcarr_workniemeyer: I have no doubt a braver man than me could attempt it an succeed21:22
donaldcarr_workniemeyer: I am not that man21:22
donaldcarr_workgnomie just mentioned that Unity2D is QML based21:23
donaldcarr_workthis is true, and it is really clean and small21:23
donaldcarr_workThe Meego tablet UX is also QML based21:23
donaldcarr_workand is the broadest most ambitious of QML I have seen in a public project21:23
donaldcarr_workevery single application is QML based21:24
donaldcarr_workand all launcher via a single engine21:24
donaldcarr_workI would love to see more QML applications in the desktop domain21:24
donaldcarr_workWe tried to craft a compelling demo for CES 2009 using graphicsview21:25
donaldcarr_workAnd we found we were struggling against it every step of the way21:25
donaldcarr_workWhat we produced in a similar timeframe was completely uncomparable to the QML code we managed to churn out and demo21:26
donaldcarr_workThe Confluence skin I have supplied a link to above is pretty big21:26
donaldcarr_workit is also vey ugly, but valuable in that it demonstrates various problems with large QML projects21:26
donaldcarr_workand should inspire you to contrain your QML to your own set of criteria21:27
donaldcarr_workbasically21:27
donaldcarr_workthe language does not constrain you, and allows you to use global variables and generate spagetthi code21:27
donaldcarr_workYou have to be aware of this21:27
donaldcarr_workfrom the outset21:28
donaldcarr_workand set the appropriate coding conventions at the outset21:29
donaldcarr_workif you look at the Delphin skin:21:29
donaldcarr_workhttp://gitorious.org/qtmediahub/delphin/trees/master21:29
donaldcarr_workYou will see it is infinitely cleaner21:29
donaldcarr_workI would urge any of your interested in QML to checkout out and build our project21:30
donaldcarr_workas it can get you hacking QML within minutes21:30
donaldcarr_workwe are more than happy to field questions21:30
donaldcarr_workhttp://www.qtmediahub.com/21:30
donaldcarr_workgives information about the project21:30
donaldcarr_workand our respective email addresses21:30
donaldcarr_workwhere you can spam us to your hearts content21:30
donaldcarr_workI have to stress that we are pushing QML everywhere21:31
donaldcarr_workand experimenting with the extent to which it increases the accessibility of otherwise incredibly complex tasks21:32
donaldcarr_workThis blog posting:21:32
donaldcarr_workhttp://labs.qt.nokia.com/2011/08/24/qt-quick-3d-tutorial-video/21:32
donaldcarr_workdemonstrates the use of QML3D to render and interact with a 3D model of a car using QML21:32
donaldcarr_workIf you are in the market for more formal training, or curious as to specifics, we have free training material for Qt Quick available here:21:33
donaldcarr_workhttp://qt.nokia.com/learning/online/training/materials/qt-quick-for-designers21:33
donaldcarr_workand here:21:33
donaldcarr_workhttp://qt.nokia.com/learning/online/training/materials/qt-essentials-qt-quick-edition21:33
donaldcarr_workAs you would have gathered ARM based devices are gaining momentum in an increasing array of tasks21:35
donaldcarr_workmy job involves dabbling with these devices on a daily basis21:35
donaldcarr_workIs there any remaining question about what QML is?21:35
donaldcarr_workQt has historically had a painter algorithm paint engine21:35
donaldcarr_worka style api based on this, and widgets which render using this21:36
donaldcarr_workThis resulted in an ungodly mapping of atomic painters algorithm calls resolving to GL calls and massive amount of overhead21:36
donaldcarr_workThis will be resolved by the scenegraph work going into Qt 521:37
donaldcarr_workAs I mentioned earlier, there has been some public concern that Qt will become less applicable for desktop apps21:37
donaldcarr_workOur engineers have already blogged about:21:37
donaldcarr_workhttp://labs.qt.nokia.com/2011/03/10/qml-components-for-desktop/21:37
donaldcarr_workwhich demonstrates higher level native controls for usage from within QML21:38
donaldcarr_workThese are still be actively researched and should mature over the coming months21:38
donaldcarr_workWhen QtQuick was first released, it provided very little higher level widget functionality and this caused something of a panic and pigeon holing of the tech as being undesktop like21:39
donaldcarr_workThis was caused by the lag time in actually implementing and releases Components, which clearly could not be implemented in parallel to the core QML language itself21:40
donaldcarr_workWe are having a session on this at this years Qt Developer Days (Munich 24-26th Oct, SF 29Nov-1Dec):21:40
donaldcarr_workhttp://qt.nokia.com/qtdevdays2011/qt-technical-sessions#qtquickcomponentsdesktop21:40
donaldcarr_workDoes anyone have any questions of statements to make at this point21:41
donaldcarr_work?21:41
donaldcarr_workIf people want to use QML components now21:41
donaldcarr_workhttp://labs.qt.nokia.com/2011/07/06/ready-made-ui-building-blocks-at-your-service-qt-quick-components-for-symbian-and-meego-1-2-harmattan/21:42
donaldcarr_workdocuments the release of the Symbian component set which have no dependency outside of Qt so you can happily use them outside of Symbian development. (YMMV)21:42
ClassBottomalan asked: gtk-applications tend to have a "foreign" look on OSX. How is that with QT?21:43
donaldcarr_worktomalan: I am going to assume you are asking this question in the QML context21:43
donaldcarr_worktomalan: Jens provides this screen shot in the comments section: http://labs.qt.nokia.com/wp-content/uploads/2011/03/mac2.png21:43
donaldcarr_worktomalan: I would assume the controls would look passably macish, although I clearly can't vouch for them until the surrounding work has matured21:44
donaldcarr_worktomalan: I also cant vouch for the feel (even though the look as clearly quite far along)21:45
donaldcarr_worktomalan: We are also exposing native theming functionality via other QML constructs21:45
donaldcarr_workas documented in this blog: http://labs.qt.nokia.com/2011/04/08/mac-toolbars-for-qt-quick/21:45
donaldcarr_workIf you are interested in Qt development21:46
donaldcarr_workPlease subscribe to the Qt developer mailing lists:21:46
donaldcarr_workhttp://lists.qt.nokia.com/mailman/listinfo21:46
donaldcarr_workwhere flame wars abound21:46
donaldcarr_work(but they have to be constructive flamewars)21:46
donaldcarr_workIf in dabbling with QML you hit any issues please feel free to address questions to:21:47
donaldcarr_workPlease direct any queries to qt-qml@qt.nokia.com where we can collectively address them.21:47
donaldcarr_workIf there are no further questions21:47
donaldcarr_workI will show you interesting items from Qt Media Hub21:48
donaldcarr_workif you do not interject with questions21:48
donaldcarr_workthe way the project is currently structured21:48
donaldcarr_workall models, model population, file system crawling, threading is done in c++21:48
donaldcarr_workthe only thing the QML model cares about are structures which are explicitly exposed to it21:49
donaldcarr_workthis is done in:21:49
donaldcarr_workhttp://gitorious.org/qtmediahub/qtmediahub-core/blobs/master/src/skinruntime.cpp21:49
donaldcarr_workstarting on line 26621:50
donaldcarr_workYou can see we create a property map21:50
donaldcarr_workand then attach it to the root context21:50
ClassBotThere are 10 minutes remaining in the current session.21:50
donaldcarr_workthis is a clear point where you can see the division of functionality between c++ and QML21:51
donaldcarr_workbasically, media player skins are completely unconstrained other than the fact they have to use the APIs of these common exported contructs21:51
donaldcarr_workSo where as XBMC has a fixed XML layout engine21:52
donaldcarr_workwhere the themes are bound to formatting/layout constraints imposed by this intermediate engine21:52
donaldcarr_workour QML skins can take any liberties extended by QML21:53
donaldcarr_workWe currently have around 5 skins21:53
donaldcarr_workdepending on the targets we are aiming them at: automotive, directfb hardware, GL based devices21:53
donaldcarr_workYour QML skin changes depending on the acceleration mechanisms available and the input mechanisms21:54
donaldcarr_workOne of the trickiest things about QML (it has to be said) is the focus handling21:54
donaldcarr_workWhen using a keyboard to change focus between a hierarchy of controls, especially in a project where multiple people are hacking,  we found we had to adopt a procedual way of switching focus between components21:55
ClassBotThere are 5 minutes remaining in the current session.21:55
donaldcarr_workWe have 5 minutes remaining, does anyone have any questions?21:56
donaldcarr_workI hope some of you managed to grab the qt-sdk package21:56
donaldcarr_workand are curious enough to look further into it21:56
donaldcarr_workIf any of you are interested in joining our project feel free to join us at #qtmediahub21:57
donaldcarr_workfor QML related questions you can always hop on #qt-qml21:58
donaldcarr_workAs you would have gathered for Qt 5, QML is the first class citizen, he has the key to the city and hence familiarizing yourself with this technology is very adviseable21:58
donaldcarr_workI for one am thoroughly convinced that the new model/architecture of Qt (for Qt 5) makes it very plausable for wide usage in the embedded (and desktop) space21:59
donaldcarr_workI think I am about to get booted21:59
donaldcarr_workthank you for your time21:59
donaldcarr_work I hope that this has been useful21:59
ClassBottomalan asked: When will QT5 be available?22:00
donaldcarr_worktomalan: I can't give explicit dates for clear reasons22:00
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/09/%23ubuntu-classroom.html22:00
donaldcarr_worktomalan: I would expect it to be quite useable by the end of the year22:00
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - https://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Questions in #ubuntu-classroom-chat ||
=== cyphermox_ is now known as cyphermox

Generated by irclog2html.py 2.7 by Marius Gedminas - find it at mg.pov.lt!