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

=== jsjgruber_ is now known as jsjgruber
=== callaghan_ is now known as callaghan
codingenesiswhat is ubuntu classroom chat ??08:47
codingenesiscan anyone give a light on it ??08:47
nigelbcodingenesis: https://wiki.ubuntu.com/Classroom would be helpful08:50
codingenesisi would definitely like to be a part of it..08:51
codingenesishow can i join ??08:51
devcalaisare there scheduled discussion/classrooms in here? if so, where can I access a timetable?12:00
nigelbdevcalais: You can see the schedule in the Calender.12:02
nigelbThe link to the calender is in the topic12:02
devcalaisCheers. :)12:13
conscioususer 14:08
smitpatelHello all .. I apologize if this query isn't posted on right channel. After I upgraded to 11.10 I got this msg in recovery mode "var/run/dbus/system_bus_socket connection refused" and I am unable to login in my a/c.15:01
smitpatelSomeone please help me out15:01
=== dpm is now known as dpm_
=== Wilczek_ is now known as Wilczek
=== 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 an App Developer Website: developer.ubuntu.com - Instructors: dpm, johnoxton
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/08/%23ubuntu-classroom.html following the conclusion of the session.16:01
dpmWelcome everyone to Day 4 of the Ubuntu App Developer Week!16:01
dpmok, so let's get started, shall we?16:02
=== shadeslayer_ is now known as shadeslayer
dpmSo hi everyone16:03
dpmAgain, welcome to Ubuntu App Developer Week and to this session about the App Developer _site_16:03
dpmMy name is David Planella, and I work on the Community team at Canonical as the Ubuntu Translations Coordinator16:03
dpmWhile still working on translations, this cycle I've been spending some time on the app developer side of things,16:04
dpmthat is, contributing to the goal of making Ubuntu a target platform for application developers,16:04
dpmso that they can easily create or port software in Ubuntu and they can publish it and distribute it to and grow our increasing user base.16:04
dpmMy main area of focus has been so far developer.ubuntu.com, of which we're going to talk today,16:05
dpmand for this I've had the pleasure of working with the awesome web design team at Canonical.16:05
dpmCo-presenting this session and representing them we've got the luxury of having John Oxton,16:05
dpmwho's recently joined Canonical and has been doing fantastic work in shaping up the site16:05
dpmBut I'll let him introduce himself best16:06
* dpm hands the mike to johnoxton16:06
johnoxtonHi everyone, as David said, my name is John Oxton and I am a user experience architect on the web team at Canonical. I have been with the company for a few months and this is my first assignment.16:06
johnoxtonI will be using the word ‘we’ quite a lot as we go along and this is just a shortcut to represent a group of very busy people (inside and outside Canonical) who have given their time generously to this project, not because they have to but because they care about it deeply and believe it to be very important to the future success of Ubuntu. In that light my contributions to this project really are very 16:07
johnoxtonto theirs.16:07
johnoxtonOk, enough with the Oscar acceptance speech, let’s get on!16:07
johnoxtonAs has been mentioned the goal of this site is to help get more and better apps into the Ubuntu Software Centre.16:07
johnoxtonFrom the developer.ubuntu.com website point of view that is an interesting challenge and not one we can possibly hope achieve in one step.16:08
johnoxtonWhere to begin?16:09
johnoxtonThe first question really is what is an ‘app’ anyway? Is LibreOffice an app? Is Mozilla’s Thunderbird an app? What about Chromium? Skype? Firefox?16:09
johnoxtonWell the answer is yes and each a very good one but also advanced and relatively mature and, importantly, already on Ubuntu.16:09
johnoxtonThe point being, for this upcoming release we aren’t really targeting developers of these kinds of apps because they are already working it out.16:09
johnoxtonOf course, nor is the aim to exclude them.16:10
johnoxtonInstead we want to start a dialogue with individuals, or small teams, with an “itch to scratch”16:10
johnoxtonor small indie developers/companies who are already making small, useful, or just plain cool, apps for other platforms.16:11
johnoxtonWith that in mind we shaped two personas, and the journeys we’d expect them to make, to reflect these sorts of developers16:11
johnoxtonand began sketching ideas about how we thought we could encourage and support them through the app development lifecycle.16:11
johnoxtonFor those who’ve never encountered personas, here is a brief summary from UX mag:16:12
johnoxton“A persona represents a cluster of users who exhibit similar behavioral patterns in their purchasing decisions, use of technology or products, customer service preferences, lifestyle choices, and the like."16:12
johnoxtonYou can find out more at http://uxmag.com/design/personas-the-foundation-of-a-great-user-experience16:13
* dpm mentions: before I forget, please feel free to ask any questions throughout the session, prepending them with QUESTION: on the #ubuntu-classroom-chat channel16:13
johnoxtonSo with personas firmly in our head, this is what we sketched: http://madebymake.com/16:14
johnoxtonTo access the site: Username: developer and Password: ubuntu16:14
johnoxtonPlease keep in mind that our focus here was on the structure of the navigation and the general concept of the site so the visual design seen here is in no way representative of the finished site.16:14
johnoxtonFeel free to click around, most pages are present; I’ll grab a much needed cup of tea whilst you do.16:14
johnoxtonAnyway, with that done we hired an independent research company to help us test this prototype.16:17
johnoxtonWe did this because we needed someone neutral to help us really dig for what was good and what was not so good.16:17
johnoxtonFrom there we recruited a cross-section of ‘app developers’ who were developing for a variety of platforms; some professionally, some in their spare time.16:18
johnoxtonWe ran them through the prototype you have seen, asking them about their expectations before they clicked through to different pages16:19
johnoxtonand also talking to them about their usual app development workflow to see if the site could be truly useful to them.16:19
johnoxtonDavid, meanwhile, ran an in-depth survey to give us some quantitative data to support or challenge what our qualitative research was suggesting.16:19
johnoxtonThese sessions and the survey were incredibly important. They challenged all of the assumptions we had made and helped us verify that our personas were even closely matching reality.16:20
johnoxtonIn short the response to our first prototype was fairly unanimous: We like where you are going but this isn’t right.16:20
johnoxtonIt also started to hint that our personas were close but not quite close enough.16:20
johnoxtonWith the first round of testing complete we went back to the drawing board and considered everything we’d learnt.16:20
johnoxtonSo what did we learn?16:20
johnoxtonWhat came back consistently was: marketing sucks, so just stop it. I just want to ‘Get started’, tell me how to proceed.16:21
johnoxtonGive me an ‘Hello World!’ app to play with and I want really good documentation.16:21
johnoxtonOh, and packaging, I don’t like thinking about packaging if I can help it.16:21
johnoxtonJust ‘Get started’, hmmmm, this is where things get challenging.16:21
johnoxtonLinux, and therefore Ubuntu, prides itself on having a rich, flexible development environment16:21
johnoxtonwhich is great but also has the potential for confusion for people just starting out16:22
johnoxtonOn the back of the findings we felt we really ought to be a little more decisive and dare to be a little opinionated because without that the site won’t have the clarity it needs to attract developers to the platform.16:22
johnoxtonThankfully the springboard for that was already in place in the form of Quickly (https://wiki.ubuntu.com/Quickly)16:22
johnoxtonand after much debate, for now at least, we’ve put it up front.16:22
johnoxtonWe have stated that THIS is the way to get going when developing for Ubuntu.16:23
johnoxtonWe are aware that this might be a somewhat controversial decision to make and we have been careful to show that there are other options16:23
johnoxtonbut Quickly delivers a route in and a good one as it elegantly stitches together classic, and very powerful, Linux development tools.16:23
johnoxtonVery importantly it also helps with packaging.16:23
johnoxtonSomething our research has suggested is that whilst great apps are being written for Ubuntu they aren’t making it all the way into the Software Centre.16:24
johnoxtonPackaging seems to be part of what’s stopping that happening16:24
johnoxtonThinking about Quickly, and the tools it brings together, helps shape our content strategy for another important area of the site: Resources16:24
johnoxton... or Reference... or Documentation (we’re still trying to decide what we should call this section).16:24
johnoxtonWhatever it ends up being called, the potential for this section of the site is enormous and our research suggests it is an area that really could improve the success rate of apps hitting the Software Centre.16:24
johnoxtonBut there is a problem.16:25
johnoxtonThere’s so much content for this section, generally, but it’s all over the place, it’s not well organised in one authoritative spot.16:25
johnoxtonOn the flip side there’s not enough of the right content to help those people who are just getting started; or if there is it’s a real struggle to find it.16:25
johnoxtonGetting this section right in one hit is impossible without a bigger discussion with developers.16:26
johnoxtonSo we’ve scoped it carefully and our message will be clear: We need help with this!16:26
johnoxtonWhich is where you come in. To begin with let’s keep things simple and engage with you, the community, around a single topic and from there build up the infrastructure we need to make this site something truly special.16:26
johnoxtonSo what next?16:26
johnoxtonBefore we get to that I just want to share a couple more rough sketches with you so you can, hopefully, see the difference the testing made to how we approached the flow of the site.16:27
johnoxtonand so far they've tested pretty well:16:27
johnoxtonhttp://dl.dropbox.com/u/24134/developer/Home.jpg16:27
johnoxtonhttp://dl.dropbox.com/u/24134/developer/getstarted.jpg16:27
johnoxtonhttp://dl.dropbox.com/u/24134/developer/resources.jpg16:27
johnoxtonThis really has been a very quick skip and a hop through a quite detailed process and I’ve had to boil it down to what I think is the essence of it because I want to leave space for Q&A.16:29
johnoxtonSuffice to say, the site will go live fairly soon and, once it does, we start listening and we start talking.16:29
johnoxtonWhen we launch, we consider it the beginning of something, not the end. This is when the UX processes really start to kick in.16:29
johnoxtonAs I said, I am still fairly new to Canonical and still have to get to know the Ubuntu community better and I need to work out the best ways to collect qualitative feedback and turn it into something actionable.16:29
johnoxtonI will be talking this through with David, and others, as time goes on.16:30
johnoxtonMy first step, though, is to try and plan a workshop at the upcoming UDS16:31
johnoxtonso we can investigate any issues that come up in detail, with the aim of coming up with some big themes on which to base future work as well as how we engage with developers in an ongoing discussion about *their* site.16:31
johnoxtonMeanwhile, I hope you will enjoy your new developer site and find it useful when it launches.16:31
johnoxtonYou can see my notes here: http://pastebin.com/8wwHufVs16:31
johnoxtonThank you.16:31
dpmAwesome, thanks John16:32
dpmNow you can see how much work is involved behind the planning and creating the concept of such a site16:32
dpmI'll continue from here on. I see there is a question already, so I'll handle that16:33
dpmin the meantime, if you've got any other questions so far, feel free to ask16:33
ClassBotpaglia_s asked: in some words how does quickly work? which languages does it support and which design library (gtk, qt...) ?16:33
dpmwell, the first thing to understand here is that quickly is just a wrapper16:34
dpmquickly helps us adding the glue to all of the tools we've decided to recommend for developing in Ubuntu16:35
dpmas such, quickly puts together python, gtk, debian packaging, bzr, launchpad and a few more16:36
dpmso quickly is a command line tool that provides easy commands to perform actions which otherwhise would be more complicated16:37
dpmin other words, it hides the complexity for the developer, who can then just worry about coding16:37
dpmSo just to give an example, to package an app, if you've started a project with quickly, in most cases running the 'quickly package' command will be enough16:38
dpmrather than having to read tons of documentation and learn how to package16:38
ClassBottau141 asked: why does ubuntu recommend PyGtk for creating Applications?16:38
dpmI was expecting that one :)16:39
dpmThere are many, many good technologies in the open source world and while that is an asset, we do want to make an opinonated choice on the tools we recommend16:40
dpmRight now python + gtk + debian packaging are the best options to a) provide full integration with the Ubuntu Platform (talk unity, indicators, notification, etc) and b) support the application's full lifecycle16:41
dpmwe want to make it easy for developers to create their apps and publish them in the Software Center16:41
dpmand for that, we cannot support all technologies and have to concentrate on one we recommend16:42
dpmright now pygtk (or probably pygi in the near future) is the best option16:42
dpmwhich does not mean that when other tools mature or provide better integration with the platform we will not review that choice16:43
dpmso in short: that's the decision we've done now, but we will continue exploring the options that allow Ubuntu being the best platform of choice for app developers16:43
ClassBottomalan asked: The PyGTK-Project was cancelledin april, are you sure you don't mean the PyGobject-Introspection?16:44
dpmgood point. I mentioned just before that pygtk might need to be reworded to pygi in the near future :)16:44
dpmafaik quickly has not yet been ported to use gobject introspection16:45
dpmbut it's just a minor detail, whenever it does, we'll make sure to update the site's wording16:45
dpmok, so if there are no more questions, let me continue with the rest of the session16:46
dpmWhile John mentioned the next Ubuntu Developer Summit  (UDS) and future plans, at the _last _ UDS we already devoted a session to discuss the developer site,16:46
dpmand what you'll be seeing very soon is the result of that work,16:47
dpmcarried out mainly by the web design team with the help of many other folks at Canonical16:47
dpmOne thing I want to stress is that this is just the beginning16:47
dpmThe App Developer Site is just one part (and a key one) of the overall app developer strategy that we're fleshing out as we speak16:47
dpmThis cycle you'll have noticed many of the visible pieces coming together:16:48
dpm* Jonathan Lange becoming the Developer Program Specialist,16:48
dpm* the release of the MyApps online portal to streamline the process of submitting apps and get them published in the Software Centre,16:48
dpm* more apps flowing into the Software Centre...16:48
dpmYou should definitely check out the log of Jonathan Lange's session last Monday16:49
dpmwhere he delivered an overview of the vision and the strategy for app development in Ubuntu16:49
dpmAlso Anthony Lenton and Stéphane Graber talked about different aspects of submitting applications through MyApps last Tuesday16:49
dpmYou'll find it all here: https://wiki.ubuntu.com/UbuntuAppDeveloperWeek/Timetable16:49
dpmAnd finally, to wrap up the topic with good coverage from all sides, John Pugh will talk about the business side, that is,16:49
dpmhow Canonical makes money from commercial applications to become a sustainable business and better support the development of Ubuntu16:50
dpmIn short, we want to put Ubuntu on the app development map.16:50
dpmWe want to provide a top level experience through a platform that makes it easy for developers to create applications and distribute them to millions.16:50
ClassBotThere are 10 minutes remaining in the current session.16:50
dpmWe're laying out a set of solid foundations for that goal, and we're going to build upon them16:50
dpmDeveloper.ubuntu.com will be a place to present developers with a clear journey that will guide them through the process of creating and publishing applications for Ubuntu.16:50
dpmAlong the way, they will find all the resources that will enable them to make the right design decisions and direct them to the infromation they need in a clear and consistent manner.16:51
dpmAnd another important purpose of the site will be to become the starting point to build an app developer community.16:51
dpmAs such, this upcoming release is what we could consider the first iteration of developer.ubuntu.com.16:52
dpmBy Oneiric's release we'll have a site that we can be proud to direct app developers to, with a place that not only is up to the Ubuntu design standards,16:52
dpmbut also to provide application developers the information they need to get started writing applications in Ubuntu.16:52
dpmThat is the primary goal of that iteration, but we are aware that this will not be enough, and that the site will need to evolve and to grow16:52
dpmSo we will need your help to use it, to participate with your feedback and be part of this effort to make Ubuntu the platform of choice for application development and distribution.16:53
dpmAnd with this, I think that's all we wanted to cover16:54
dpmI hope you found our presentation useful, and if you've got any questions, feel free to ask now16:54
dpmwe've still got a few minutes to answer a few16:54
ClassBotThere are 5 minutes remaining in the current session.16:55
ClassBottau141 asked: so we can help by using it and by givin our feedback! is there any other way to help?16:58
johnoxtonI think it would be really useful for those who are developing an app or have developed an app to write about their experiences16:59
johnoxtonor start writing tutorials and letting us know about them16:59
johnoxtonI think the resources/reference/documentation section would benefit hugely from content like this17:00
johnoxtonand of course when we go live17:00
johnoxtonlook out for bugs and let us know!17: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: Rapid App Development with Quickly - Instructors: mterry
dpmSo if there are no more questions, the last bit is just to thank you for your participation and hope you've enjoyed the session! :-)17:00
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/08/%23ubuntu-classroom.html following the conclusion of the session.17:00
mterryHello, everyone!17:01
mterryThanks to dpm and johnoxton for the awesome session17:01
mterryMine piggybacks on that by giving more information about quickly17:01
mterryI'm a maintainer of quickly and will give a brief overview of what it is, how to use it17:01
mterryPlease ask questions in the chatroom, I'll try to answer them17:02
mterrySo first, here's a link for the wiki page of quickly: https://wiki.ubuntu.com/Quickly17:02
mterryQuickly is at its heart a templating system.  It is designed to give a user a quick start of sample code and allow you to modify it easily and quickly(!) into a full program17:03
mterryIt has a lot of boiler plate code that gets you started, and commands to simplify common application tasks like packaging it up, saving to bzr, publishing to users in a PPA17:04
mterryIt's designed, as is developer.ubuntu.com, to make opinionated choices about technologies (which makes the task of teaching new users a lot easier -- just teach one thing)17:04
mterryBut since new quickly templates can be written, new sets of opinionated choices are easy too17:05
mterryFor example, someone might one day write a Kubuntu template, to make app dev on Kubuntu easier17:05
mterryAnd lastly, quickly is supposed to make app dev on Ubuntu fun, by letting the user focus on the good stuff, not the boring administrative stuff17:06
mterryIn 11.04, we have four templates: ubuntu-application, ubuntu-cli, ubuntu-flash-game, ubuntu-pygame17:06
mterryubuntu-application is PyGTK based to make graphical apps17:06
mterryubuntu-cli is Python based for making command line apps17:06
mterryubuntu-flash-game is like it sounds, you drop a flash file into place and quickly handles the rest17:07
mterryubuntu-pygame is pygame based, which is a Python library for making games easy17:07
mterryThere was a question last session about why PyGTK and not GObject Introspection17:07
mterryWe'd like to use PyGI, but due to technical details (it's difficult to automatically guess dependencies then), we haven't made that jump yet17:08
mterryHopefully we will during the 12.04 cycle17:08
mterryOur goals for 11.10 are rather modest, focusing just on some outstanding bugs17:08
mterryOK, enough intro.  Let's do something!17:09
mterryYou can install it easily enough by running: "sudo apt-get install quickly"17:09
mterryThis will install all sorts of programming goodies17:09
mterryOnce installed, try running "quickly create ubuntu-application test-project"17:10
mterryThe 'create' is the command to quickly to say "start a project", the 'ubuntu-application' tells which kind of project, and the last argument names the project17:10
mterryYou'll now have a folder called "test-project" with a bunch of files17:11
mterryIt will also open a window17:11
mterryThis is what your project looks like already!  It has a window, menubar, etc17:11
mterryThis will all be easy to change, but it's a quick start, something to modify17:12
mterrySo why don't we try doing that17:12
mterryWe'll look into changing the UI a bit17:12
mterryRun "quickly design" to open Glade, which is a graphical UI builder17:12
mterryUsing glade well is a whole 'nother talk, but if you have any questions, I'll be happy to answer them17:13
mterryFor now, just note that you can select things, change properties on the right, and add new widgets from the toolbox on the left17:13
mterryQuickly automatically hooks your Glade UI files together with your code17:14
mterryI'll give a brief overview of what you can do in Glade17:14
mterryLayout in Glade (and in GTK in general) is done via Boxes (like VBox or HBox) that arrange them in rows or columns17:15
mterryYou can change a widget's position in a box in the properties dialog (2nd packing tab)17:15
mterryThe packing tab is where you can adjust a lot of the layout of a widget.  The first tab is where you control specific widget functionality (like the text on a label, etc)17:16
mterryOK, so enough Glade.17:16
mterryI'll briefly mention here, to learn more about quickly, you can also run "quickly help" to get an overview of commands17:16
mterryOr you can run "quickly tutorial" to get a more complete tutorial that you can walk through at your own pace17:17
mterryThat will walk you through creating a full app17:17
mterryBack to my overview, another important command is "quickly add dialog dialog-name"17:18
mterryLet's say you want to add a quit-confirmation dialog or something17:18
mterryBy running the above command, quickly will generate a new Glade file and a new Python file to handle any special code you may want for the dialog17:19
mterryAfter running the command, you may want to close out Glade and reopen it with "quickly design" to open the new Glade file that you just created17:19
mterryNow to use that new dialog from code, open your code with "quickly edit"17:20
mterryThis opens all your Python files in the gedit text editor17:20
mterryYou can open your new dialog from existing code by doing something as simple as "from project_name.DialogName import DialogName"17:21
mterryThen creating new dialogs with DialogName()17:22
mterryAnother thing Quickly makes easy for you is signals17:22
mterryWhenever a user clicks on a button, starts typing in a field, or closes a window, a signal is generated inside GTK17:23
mterryIf you want to run some code in response to an action, you need to add a signal handler in code17:23
mterryNormally, this is a bit tricky to coordinate between Glade's files and Python's files17:23
mterryBut Quickly will automatically join widgets in Glade to Python code if you name your signal handler correctly17:24
mterryLet's say you want to do something in response to a widget you named "button1" being clicked17:24
mterryOpen the widget window's Python file, and add a function called "on_button1_clicked(self, widget, data=None)"17:24
mterryThe trick is to name it on_WIDGETNAME_SIGNALNAME17:25
mterryAnd Quickly will find it and join it up17:25
mterryAnother thing to note about Quickly is how your code is even organized17:25
mterryI've talked about opening a window's Python file, but what does that mean?17:26
mterryYou'll have three subfolders in your project folder17:26
mterryOne is "bin", one is "project_name", and the last is "project_name_lib"17:26
mterryQuickly 'owns' files in bin and project_name_lib17:26
mterry'bin' holds a wrapper that Quickly uses to find the rest of your files once it's installed on disk17:27
mterry'project_name_lib' holds a bunch of convenience boiler plate code that Quickly provides.  But you shouldn't modify it, as Quickly may update that code on you17:27
mterryThe real goods are in the 'project_name' folder17:27
mterryThere you'll find a file with some utility code (like command line argument handling) and a file for each window in your project17:28
mterryAnd a file for your preferences17:28
mterryThe wrapper will create ProjectWindow class, and that's the entry point to your program17:29
mterryIf you wanted to take an existing project and drop it into a Quickly shell project, or even wanted to start with a Quickly project but not really use any of the code, the only actual requirement is that you have a ProjectWindow class17:29
mterryOnce that code runs, you can do whatever you like17:30
mterryAnother thing Quickly does for you is use a logging framework17:30
mterryYou'll see existing code use log calls17:30
mterryRun your project ("quickly run") in verbose mode ("quickly run -- --verbose") to see the log output17:31
mterryWhen debugging, you can add new log calls (or just use plain old print statements)17:31
mterryAnother, more precise, method of debugging is to use the command line python debugger pdb17:32
mterryActs like gdb but for python17:32
mterryI've not used it a bunch (print statements tend to be quicker and easier)17:32
mterryBut if you have a really tough bug, pdb can be a help17:32
mterryOK, so let's say you have your app, version 1.017:33
mterryYou'll want to start being able to release it17:33
mterryIn general, there are three levels of testing a finished program: (1) locally, by the developer, (2) a wider, but still limited, group of testers, and (3) everyone (an actual release)17:34
mterryQuickly will help with all 317:34
mterryBut before we create any packages at all, let's set up a bit of metadata about your project17:35
mterryAdd your name and email to the AUTHORS file that Quickly created for yu17:35
mterryyou17:35
mterryAlso define a license for your project with "quickly license BSD" or similar.17:35
mterryGPL-3 is the default17:35
mterrySo no need to run anything if that suits you fine17:35
mterryOpen the project-name.desktop.in file in your project directory too17:36
mterryIt has a Categories line that you can edit to adjust where in the menu structure it will show up17:36
mterrySee defined categories here: http://standards.freedesktop.org/menu-spec/latest/apa.html17:36
mterryAnd finally, edit setup.py in your project directory17:36
mterryNear the bottom are some metadata bits like description, website, author name again17:37
mterryWith all that in place, let's make a package!17:37
mterryFor local testing by you yourself, "quickly package" will create a package17:37
mterryIt will create it in the directory above your project folder17:37
mterrySo install it with "sudo dpkg -i ../test-project_0.1_all.deb" or some such17:38
mterryThen it should appear in your menu17:38
mterryAnd be runnable from the Terminal with "test-project"17:38
mterryOnce you think it seems alright, you're ready to distribute to the rest of your testers17:38
mterryThis involves a PPA17:38
mterryA Personal Package Archive17:39
mterryIn your Launchpad account, you can create new PPAs17:39
mterryFirst you need SSH and GPG keys, explained in the Launchpad help:17:39
mterryhttps://help.launchpad.net/YourAccount/CreatingAnSSHKeyPair17:39
mterryhttps://help.launchpad.net/YourAccount/ImportingYourPGPKey17:39
mterryAlso set DEBEMAIL and DEBFULLNAME in .bashrc, the same as what was in your GPG key17:40
mterryAnd then run ". ~/.bashrc" to pick up the new settings in your current Terminal17:40
mterry(that's a period as a command)17:41
mterryJust a bash trick to run a script in the current environment17:41
mterryFor instructions on actually creating a PPA: https://help.launchpad.net/Packaging/PPA17:41
mterryPhew17:41
mterryWith that all set up, all you need to do to publish a new testing version of your project is "quickly share"17:42
mterryThis will package up your current code and put it in your PPA17:42
mterryIt will pick its own version (though you can provide one, see "quickly help share")17:42
mterryThe version used will be based on the last release17:43
mterryIt won't increment the actual version number, but just a version suffix17:43
mterrySince it's just a testing package17:43
mterryIf you want to make a full release to the wider public, use "quickly release"17:44
mterryIt helps to have a project created in Launchpad and associated with your quickly project17:44
mterry(use "quickly configure lp-project project-name" for that)17:44
mterryThen Quickly can automatically make project release announcements for you17:45
ClassBotdpm asked: I've been reading the quickly help, and I'm still not sure I get it: what's the difference between the 'quickly share' and 'quickly release' commands?17:45
mterrySo "share" uses a version suffix like -public117:46
mterryIt releases into your PPA, but that's it17:46
mterry"release" will actually increment your main version number to something like 11.0917:46
mterry(These version changes can be overridden on the command line)17:47
mterryRelease will also, if a Launchpad project is associated, make a release announcement and close the milestone17:47
mterrySo there isn't *much* difference, more of a semantic one.  Release just does a few thing extra17:48
mterryI also recommend using different PPAs for "sharing" and "releasing"17:48
mterryYou can specify a ppa with "quickly share --ppa mterry/testing" for example17:48
mterryThat way, you can have a "testing" PPA and a "stable" PPA17:48
mterrySo it's good to get in the mental habit of thinking that there are two types of publishing17:49
mterryOne for testers, one for everyone17:49
mterryI suppose there's one more level of publishing actually17:50
mterryAnd that's to the Software Center17:50
mterryQuickly has a few tools to help you prepare your app for the Software Center (whether it's a free or proprietary one)17:50
mterryThere is the "submitubuntu" command17:50
ClassBotThere are 10 minutes remaining in the current session.17:50
mterryThis will publish to a PPA just as "release" does17:51
mterryBut it will do some of the legwork to prepare the package for the App Review process17:51
mterryNotably, it will install everything into /opt17:51
mterryAnd it will set some bits of packaging metadata up like "where is the app screenshot" and such17:51
mterryYou can prepare a local deb with such changes by using "quickly package --extras"17:52
=== wangerin1 is now known as wangerin
mterrySee https://wiki.ubuntu.com/AppReviews for more information about such requirements17:52
mterryThat's all I had prepared!17:53
mterryI'm happy to answer Quickly questions if ya'll have any17:53
ClassBotThere are 5 minutes remaining in the current session.17:55
ClassBotMDesigner asked: what resources do you recommend for learning Glade and Python, specifically geared toward Ubuntu/Unity development?17:56
mterryHeh, well, the previous session was on developer.ubuntu.com17:56
mterryThat aims to be the answer to that question17:57
mterryIt already has some content, but it's hoped to flesh that out a bit17:57
mterryFor example, I'll be writing a tutorial for it on how to integrate Ubuntu One Files in your app using Python (I also have a talk on that tomorrow)17:57
mterryFor learning Python in general, Dive into Python is a great resource17:58
mterryGoogle that and you'll get results17:58
mterryI'm not sure there are great tutorials out there for Glade specifically17:58
mterryFor Unity integration, http://unity.ubuntu.com/ has some info.  Like http://unity.ubuntu.com/projects/appindicators/ has links for documentation18: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: Developing with Freeform Design Surfaces: GooCanvas and PyGame - Instructors: rickspencer3
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/08/%23ubuntu-classroom.html following the conclusion of the session.18:00
rickspencer3sooo18:02
rickspencer3hi everybody18:02
rickspencer3you just missed my best stff18:02
rickspencer3I was talking in teh wrong channel for the last 2 minutes :)18:03
rickspencer3so, let's try again ...18:03
rickspencer3Hello all. Today I will discuss 2 of the APIs that I have used to have a lot of fun with programming for Ubuntnu.18:03
rickspencer3These APIs are GooCanvas and PyGame. They are both similar in the sense that they provide you with a 2d surface on which you can construct interactive GUIs for your users.18:03
rickspencer3seriously, I have had tons of fun writing apps with thes over the years18:03
rickspencer3However, I fonud them to have different strengths and weaknesses. If you choose the correct API it will be more easy and more fun to write yoru app.18:04
rickspencer3so, why goocanvas or pygame at all?18:04
rickspencer3A typical desktop app is composed of widgets that a user is used to. Like buttons, entry boxes, and such.18:04
rickspencer3For these desktop apps, I strongly recommend sticking with PyGtk for the time being.18:04
rickspencer3like the next year, I think18:04
rickspencer3PyGtk is the way to go for what I call "boxy" apps18:05
rickspencer3I use pygtk all the time18:05
rickspencer3However, sometimes part of an app, or pretty much a whole app, won't need buttons and lists and entry boxes, but will need to display, modify, or animate images, drawings, etc...18:05
rickspencer3Sometimes in response to user input, sometimes not.18:05
rickspencer3My goal for this session is to help you choose the right API for those kinds of apps, and to get you started with them.18:05
rickspencer3please ask questions at any time18:05
rickspencer3I will check for questions often18:05
rickspencer3I'll start with GooCanvas because I already did a session on this last year, so there is lots of material.18:06
rickspencer3https://wiki.ubuntu.com/UbuntuOpportunisticDeveloperWeek/GooCanvas18:06
rickspencer3basically, I shall copy and past from there, answering quetsions as I go18:06
rickspencer3thoguh I may skip some to leave room for pygame18:07
rickspencer3So what is a goocanvas?18:07
rickspencer3A goocanvas is a 2d composing surface18:07
rickspencer3You can use it to make pretty much any kind of image18:07
rickspencer3It's kind of like an api around a drawing program18:08
rickspencer3So you can have a ton of fun using a goocanvas, because you are pretty much freed from the constraints of a widget library in creating your UI18:08
rickspencer3goocanvas is cairo under the covers18:08
rickspencer3and is designed to easily integrate into your gtk app18:08
rickspencer3So let's add a goocanvas to a pygtk app18:08
rickspencer3Add it just like a normal pygtk widget18:09
rickspencer3#set up the goo canvas18:09
rickspencer3self.goo_canvas = goocanvas.Canvas() self.goo_canvas.set_size_request(640, 480) self.goo_canvas.show()18:09
rickspencer3tada!18:09
rickspencer3you have a goocanvas18:09
rickspencer3Be sure to set the size, otherwise it defaults to 1000,1000, it does not default to the size alloted to it in your window.18:09
rickspencer3Handle window resizing to resize your goocanvas as well18:09
rickspencer3!!18:09
rickspencer3the goocanvas won't automatically change size if it's container changes size18:10
rickspencer3For example, if your goocanvas is in a VBox, you can do this:18:10
rickspencer3rect = self.builder.get_object("vbox2").get_allocation() self.goo_canvas.set_bounds(0,0,rect.width,rect.height)18:10
rickspencer3remember the root item for your goocanvas, you'll need it later often self.root = self.goo_canvas.get_root_item()18:10
rickspencer3The "root" is like the root of an item tree in XML18:10
rickspencer3So now that we have a goocanvas, we need to add "Items" to it.18:10
rickspencer3Anything that can be added to a goocanvas is an Item. It get's it's capabilities by inheriting from ItemSimple, and by implementing the Item interface.18:10
rickspencer3Let's add an item to the goocanvas to get a look at how it works in general.18:11
rickspencer3We'll start by adding an image.18:11
rickspencer3First, you need to get a gtk.pixbux for your image:18:11
rickspencer3pb = gtk.gdk.pixbuf_new_from_file(path)18:11
rickspencer3Then you calculate where you want the image to show on the goocanvas. You'll need a top and a left to place most items on a goo canvas.18:11
rickspencer3For example, to center the image, I do this:18:11
rickspencer3cont_left, cont_top, cont_right, cont_bottom = self.goo_canvas.get_bounds() img_w = pb.get_width() img_h = pb.get_height() img_left = (cont_right - img_w)/2 img_top = (cont_bottom - img_h)/218:11
rickspencer3it's a bit hard to read, I guess18:11
rickspencer3but I basically just calculated the pixel center of the goocanvas18:12
rickspencer3and stored the "bounds" that the calculation returned18:12
rickspencer3Now I am ready to create the item.18:12
rickspencer3Note that I create the Item, but there is nothing like goocanvas.add(item) rather, when you create the item, you set it's parent property.18:12
rickspencer3The parent property is the root of the goocanvas18:12
rickspencer3This is why I remember the root18:12
rickspencer3goocanvas.Image(pixbuf=pb,parent=self.root, x=img_left,y=img_top)18:12
rickspencer3This basic pattern is how you add all other types of items.18:13
rickspencer3decide where to put the item, and set it's parent property to the root of the goocanvas.18:13
rickspencer3To remove the item from the goocanvas, you don't tell the goocanvas to remove it18:13
rickspencer3rather you tell the item to remove itself18:13
rickspencer3item.remove()18:13
rickspencer3any questions at all so far?18:13
rickspencer3In a moment, I'll go on to discuss the types of things that you can add to a goocanvas18:14
rickspencer3In my mind, there are really 3 types of items18:14
rickspencer3normal items that you add to draw the stuff you want18:14
rickspencer3this includes:18:14
rickspencer3Ellipse, Image, Path, Polyline, Rect, and Text18:14
rickspencer3the second type is for layout18:15
rickspencer3Layout and gruop items include:18:15
rickspencer3Group, Grid, and Table18:15
rickspencer3then finally,18:15
rickspencer3there is also Widget. Widget is pretty cool.18:15
rickspencer3You can add a gtk widget to your goocanvas, but note that it will live in a world seperate from the goocanvas18:15
rickspencer3In other words, gtk.Widgets won't be rendered if you create images form our goocanvas and such18:15
rickspencer3However, this is a cool way to add in situ editing to your goocanvas18:15
rickspencer3We'll just be talking about normal items for the rest of this class though18:15
rickspencer3So what are some of the things that you do with an item? Well, you compose with it. So you scale it, move it, rotate it, change it's z-order and such18:15
rickspencer3For a lot of things that you want to do with an item, you use set_property and get_property18:16
rickspencer3For example, to set the a might make a Text item like this:18:16
rickspencer3txt = goocanvas.Text(parent=self.root,text="some text", x=100, y=100, fill_color=self.ink_color)18:16
rickspencer3then change the text in it like this:18:16
rickspencer3txt.set_property("text","new text")18:16
rickspencer3Let's look at colors for a moment. There are generally two color properties to work with, stork-color, and fill-color18:16
rickspencer3If you've ever used a tool ink inkscape, this will make sense you to18:16
rickspencer3for something like a rect, stroke-color is the outline of the rectangle, and fill-color is the inside of the rectangle18:16
rickspencer3any questions so far?18:17
rickspencer3okay, moving on18:17
rickspencer3You can move, rotate, resize, and skew items18:17
rickspencer3The APIs for doing this are intuitive, imho18:17
rickspencer3To grow something by 10%18:17
rickspencer3item.scale(1.1,1.1)18:17
rickspencer3And to shrink it a bit:18:17
rickspencer3item.scale(.9,.9)18:17
rickspencer3Note that the items always consider themeselves to be their original size and orientation, so doing this will cause an item to grow twice: item.scale(1.1,1.1) item.scale(1.1,1.1)18:18
rickspencer3Now, when you start rotating and skewing items, some pretty confusing stuff can start happening18:18
rickspencer3Essentially, an item tracks it's own coordinate system, and doesn't much care about the goocanvas's coordinate system18:18
rickspencer3So if you rotate an item, for example, the coordinate systems are totally out of whack18:18
rickspencer3So if you pass the x/ys to an item based on the canvas's coordinate system, it can get waaaay out of whack18:18
rickspencer3Fortunately, goocanvas has some functions on it that just do these transforms for me18:19
rickspencer3let's say I catch a mouse click event on an item18:19
rickspencer3and I want to know where on the item the click happened18:19
rickspencer3well, the click coordinate are reported in the goocanvas's coordinate system, so I need to do a quick calculation to determine where the click happened on the item:18:19
rickspencer3e_x, e_y = self.goo_canvas.convert_to_item_space(self.selected_item,event.x,event.y)18:19
rickspencer3 18:19
rickspencer3so, I used all of these facilities and more to make Photobomb18:19
rickspencer3you can check out Photobomb if you want to see some of the things that you can do with a GooCanvas18:20
rickspencer3Photobomb is essentially an image editor18:20
rickspencer3that made it a good candidate for GooCanvas18:20
rickspencer3however, I've also written games18:20
rickspencer3and PyGame is a better API for that18:20
rickspencer3before I go on to PyGame, any questions on Googcanvas?18:21
rickspencer3GooCanvas*18:21
ClassBotbUbu87 asked: how do you work with svg and gooCanvas? is there a simple way to load an svg to a canvas and keep it scaled all the time?18:21
rickspencer3indeed!18:21
rickspencer3there are shapes and paths that are all described with svg18:21
rickspencer3I've actually exported content from InkScape into a Goocanvas in the past18:22
rickspencer3let's look at paths and clipping for an example18:22
rickspencer3A path is essentially a "squiggle"18:22
rickspencer3It is defiened by a string that gets parsed into x,y coords, and then drawn with a bezier curve formula applied18:22
rickspencer3^for those not totally familiar with svg18:22
rickspencer3here is a string that described a scribble:18:22
rickspencer3line_data = "M 4.0 4.0C4.0 4.0 5.0 4.0 5.0 4.0 5.0 4.0 6.0 4.0 6.0 3.0 10.0 1.0 13.0 2.0 9.0 15.0 6.0 36.0 28.0 11.0 28.0 11.0 29.0 11.0 33.0 12.0 33.0 15.0 32.0 19.0 27.0 51.0 27.0 53.0 27.0 54.0 27.0 54.0 27.0 54.0 36.0 49.0 37.0 49.0"18:22
rickspencer3then I can make a path out of this:18:22
rickspencer3path = goocanvas.Path(data=line_data, parent=self.root, line_width=self.ink_width, stroke_color=self.ink_color)18:22
rickspencer3so this will draw the path in the goocancas18:23
rickspencer3Now, a path is also useful because you can use it to clip another object18:23
rickspencer3You don't use a path object for this, just the string item.set_property("clip-path",line_data)18:23
rickspencer3shall I move on to PyGame?18:23
rickspencer3I put the Pygame notes here:18:24
rickspencer3https://wiki.ubuntu.com/UbuntuOpportunisticDeveloperWeek/PyGame18:24
rickspencer3PyGame is an API that is also for 2d surfaces.18:24
rickspencer3It is best for applications where there is a lot of updating of animation without user input (especially as it uses blitting).18:24
rickspencer3It has a set of baseclasses that make it easier to manage and change teh state of objects.18:24
rickspencer3It also has collision detection routines, which is very useful in game programming.18:24
rickspencer3So, net/net if you are doing something that is a game, or game-like, you're likely to want to use pygame, not GooCanvas18:25
rickspencer3pygame has fairly good reference documentation here: http://pygame.org/docs/ref/index.html18:25
rickspencer3There are also lots of tutorials available on the web. However, it's important to note that I use pygame a bit differently than they do in the typical tutorials.18:25
rickspencer3^^WARNING WARNING^^18:25
rickspencer3Tutorials typically have you create a pygame window to display you game in, and then create a loop with a pygame clock object.18:25
rickspencer3I don't do it this way anymore. Now I prefer to embed a pygame surface into a Gtk app. This has some benefits to me:18:25
rickspencer3 I can use menus for the GUI for things like starting games, pausing etc...18:26
rickspencer3I can use dialog boxes for things like hight scores or collecting information from users18:26
rickspencer3If you try to do these things from within a pygame loop, the gtk.main lool clashes with your pygame loop, and everything is just really hard to use.18:26
rickspencer3So, for the approach I take, I have three samples that you can look at at your leisure:18:26
rickspencer31. sample_game code:18:26
rickspencer3http://bazaar.launchpad.net/~rick-rickspencer3/+junk/pygame-pygtk-example/view/head:/game.py18:26
rickspencer3blog posting:18:26
rickspencer3http://theravingrick.blogspot.com/2011/08/using-pygame-in-pygtk-app.html18:26
rickspencer3This is the simplest code that I could make to demonstrate how to embed pygame and handle input.18:27
rickspencer3 18:27
rickspencer32. jumper:18:27
rickspencer3http://bazaar.launchpad.net/~rick-rickspencer3/+junk/jumper/view/head:/jumper/JumperWindow.py18:27
rickspencer3This is only slightly more complex. It show how animate a sprite by changing the image, and show collision detection and playing a sound.18:27
rickspencer3 18:27
rickspencer33. smashies:18:27
rickspencer3http://bazaar.launchpad.net/~rick-rickspencer3/+junk/smashies/files/head:/smashies/18:27
rickspencer3This is a full blown game which I have almost completed. I'm considering selling it in the software center when I am done. This one handles all the complexity of lives, scores, pausing, etc...18:27
rickspencer3 18:27
rickspencer3smashies is essentially an asteroids clone18:27
rickspencer3I'm stilling thinking of a good name, and I need to replace some artwork18:27
rickspencer3anywho ...18:28
rickspencer3For this tutorial, we'll focus on jumper since it has an animated Sprite.18:28
rickspencer3before I dive in, any general questions about PyGame?18:28
rickspencer3okee let's go18:28
rickspencer3The overall approach is simple18:28
rickspencer31. set up a drawing area in Gtk Window18:28
rickspencer32. add pygame sprites to it18:29
rickspencer33. handle keyboard input from the gtk window18:29
rickspencer34. periodically call an update function to:18:29
rickspencer3a. update the data for the sprites18:29
rickspencer3b. update the view18:29
rickspencer3c. detect collisions and respond to them18:29
rickspencer3A game typically needs a background image. I put a background image and the other images and sounds in the data/media directory. Once you get the background image painting, it means you've got the main part of the game set up. So, we'll go through this part with patience.18:30
rickspencer3^note that jumper is a Quickly app18:30
rickspencer3I put all the code in JumperWindow, so it's easy to see in one place.18:30
rickspencer3let's start making it work18:30
rickspencer3You need to import 3 modules:18:30
rickspencer3import pygame18:30
rickspencer3import os18:30
rickspencer3import gobject18:30
rickspencer3You'll see why you need these each in turn.18:31
rickspencer3First we want to create a a pygame.Image object to hold the background. Once we have that, we can use pygame functions to paint it.18:31
=== Odd-rationale_ is now known as Odd-rationale
rickspencer3Since Jumper is a Quickly app, it I can use "get_media_file" to load it.18:31
rickspencer3I mean load it from the disk18:31
rickspencer3So I make the background in these 2 lines of code in the finish_initializing function:18:31
rickspencer3        bg_image = get_media_file("background.png")18:31
rickspencer3        self.background = pygame.image.load(bg_image)18:31
rickspencer3Before I use it, I have to set up the pygame environment though. I do this by adding a gtk.DrawingArea to the gtk.Window, and telling the os module to use the windows xid as a drawing surface.18:31
rickspencer3You can't just do that in the finish_initializing function, though. This is because drawingarea1 may not actually have an xid yet. This is easy to handle by connecting to the drawing area's "realize" signal. At that point, it will have an xid, and you can set up the environment.18:32
rickspencer3basically, you need to make sure that the drawingarea has been put on the screen, otherwise, it has no xid18:32
rickspencer3So, connect to the signal in finish initalizing:18:32
rickspencer3        self.ui.drawingarea1.connect("realize",self.realized)18:32
rickspencer3and then write the self.realized function:18:32
rickspencer3    def realized(self, widget, data=None):18:32
rickspencer3        os.putenv('SDL_WINDOWID', str(self.ui.drawingarea1.window.xid))18:32
rickspencer3        pygame.init()18:32
rickspencer3        pygame.display.set_mode((300, 300), 0, 0)18:32
rickspencer3        self.screen = pygame.display.get_surface()18:32
rickspencer3This function intializes pygame, and also create a pygame.Screen object that you need for drawing.18:33
rickspencer3so now we have a Gtk.DrawingArea ready to be a PyGame surface18:33
rickspencer3any questions before I show how to put the game background on it?18:33
rickspencer3ok, moving on18:34
rickspencer3So now that the drawing area is set up as a pygame surface, we need to actually draw to it.18:34
rickspencer3Actually, we'll want to periodically update the drawing so that it appears animated. So we want to update it over and over again.18:35
rickspencer3So after setting up pygame in tghe realized function, add a gobject timeout to recurringly call a function to update the game:18:35
rickspencer3        gobject.timeout_add(200, self.update_game)18:35
rickspencer3the funciton update_game will be called every 200 millliseconds. For a real game, you might want to make it update more often.18:35
rickspencer3So, now we need write the udpate_game function. Eventually it will do a lot more, but for now, it will just tell the game to draw. So we need to write the draw_game function as well.18:35
rickspencer3    def update_game(self):18:35
rickspencer3        self.draw_game()18:35
rickspencer3        return True18:35
rickspencer3    def draw_game(self):18:35
rickspencer3        self.screen.blit(self.background, [0,0])18:35
rickspencer3        pygame.display.flip()18:35
rickspencer3Note that update_game returns True. This is important, because if it returns anything else, gobject will stop calling it.18:35
rickspencer3Looking at draw_game a little more, the first line tells the Screen object to "blit" the background. This means to only update the parts that have changed.18:36
rickspencer3 This keeps the game from flickering on slower systems. We also pass in x/y coordinates to tell it to update the whole background.18:36
rickspencer3This doesn't paint to the screen yet, though. It just prepares it in memory.18:36
rickspencer3You can call blit a whole bunch of times for different sprites, but until you call pygame.display.flip() they won't actually be painted to the screen.18:36
rickspencer3In this way, the screen only gets update once, and the animation is smooth.18:36
rickspencer3Now if you run the game, you should see the background painted.18:37
rickspencer3before I go on to animating a sprite, any questions?18:37
* rickspencer3 drums fingers18:37
* rickspencer3 scratches head18:38
* rickspencer3 twiddles thumbs18:38
rickspencer3ok18:38
rickspencer3At this point you have a drawing surface set up, and you are drawing to it in a loop.18:38
rickspencer3Now let's add an animated sprite.18:38
rickspencer3I put 2 png's in the data/media director. One called "guy1.png" and called "guy2.png". We will animate the game by swapping these images back and forth every time the game paints.18:38
rickspencer3WARNING: I am doing something very wrong!18:38
rickspencer3Jumper loads the images as needed from disk. In a real game, this is a bad idea. This is a bad idea because that takes IO time, which can slow the game down.18:38
rickspencer3DON'T DO IT THIS WAY!!!18:39
rickspencer3It's better to load all the images and sounds at once when the game loads. See smashies for how I do that in the __init__.py file.18:39
rickspencer3anyway18:39
rickspencer3I mentioned before that pygame has some useful base classes. One of those base classes is called "Sprite" which is a really old game programming term.18:39
rickspencer3When adding an object to your game, it's best to derive from sprite. It's easier to manage the data for a sprite that way, and also there are useful pygame functions that expect a Sprite object.18:39
rickspencer3So, first create the sprite class and an initialization function:18:39
rickspencer3class Guy(pygame.sprite.Sprite):18:39
rickspencer3    def __init__(self):18:39
rickspencer3        pygame.sprite.Sprite.__init__(self)18:39
rickspencer3        self.animation_stage = 118:39
rickspencer3        self.x = 3518:39
rickspencer3        self.y = 18018:39
rickspencer3        self.direction = 018:39
rickspencer3Next, we'll write a function called "update". You'll see in a bit why it's important to call it "update".18:40
rickspencer3For this function, check which animation stage to use, and then use that image:18:40
rickspencer3    def update(self):18:40
rickspencer3        img = get_media_file("""guy%i.png""" % self.animation_stage)18:40
rickspencer3        self.image = pygame.image.load(img)18:40
rickspencer3^remember don't do it like this18:40
rickspencer3^load the image from disk once at the beginning fo the program18:40
rickspencer3Next, you need to set the "rect" for the Sprite. The rect will be used in any collision detection functions you might use:18:40
rickspencer3        self.rect = self.image.get_rect()18:40
rickspencer3        self.rect.x = self.x18:40
rickspencer3        self.rect.y = self.y18:40
rickspencer3Finally, update the animation stage.18:41
rickspencer3        self.animation_stage += 118:41
rickspencer3        if self.animation_stage > 2:18:41
rickspencer3            self.animation_stage = 118:41
rickspencer3Now you just need to a "Guy" to your background.18:41
rickspencer3First, create a guy in the finish_initializing function.18:41
rickspencer3        self.guy = Guy()18:41
rickspencer3Since a game will have a lot of sprites, it's easiest to manage sprites as a group18:41
rickspencer3There is a pygame class for this called a SpriteGroup, which you create by called RenderUpdates.18:41
rickspencer3So, crate a SpriteGroup and the guy to it:18:41
rickspencer3        self.sprites =pygame.sprite.RenderUpdates()18:41
rickspencer3        self.sprites.add(self.guy)18:41
rickspencer3Remember when we created the update_game function?18:42
rickspencer3Now you can see how useful the SpriteGroup is.18:42
rickspencer3You can call "update" on the sprite group, and it will in turn call update on every sprite in it. So add that call to the update_game function:18:43
rickspencer3        self.sprites.update()18:43
rickspencer3Now, you also need to tell the Guy to draw. That's easy too with the SpriteGroup. Add this line to draw_game function:18:43
rickspencer3        self.sprites.draw(self.screen)18:43
rickspencer3Now when you run the game, each tick the guy will swap images, and it will look like it's moving.18:43
* rickspencer3 phew18:43
rickspencer3ok, almost done18:44
rickspencer3any questions?18:44
rickspencer3WARNING18:44
rickspencer3Note that I handle keyboard and mouse input very differently than they describe in most pygame tutorials18:44
rickspencer3Responding to keyboard input is really easy, because you can just use gtk events.18:44
rickspencer3I have found that you need to attach to the key events for the window, not the drawing area.18:44
rickspencer3So, to make the guy jump when the user clicks the space bar, I make a key_press_event signal handler, that calls "jump()" on the guy:18:45
rickspencer3    def key_pressed(self, widget, event, data=None):18:45
rickspencer3        if event.keyval == 32:18:45
rickspencer3            self.guy.jump()18:45
rickspencer3You can look at the jump and update functions in the Guy class to see how a jump was implemented.18:45
rickspencer3you can track mouse events, key up events, etc.. this way too18:45
rickspencer3Pygame also has functions for joysticks and stuff, but I haven't used that18:46
rickspencer3So, that's the essence of creating an animated sprite, which gets you a lot of the way toward making a game.18:46
rickspencer3We don't have time to delve into everything, but I did want to touch on collisions.18:46
rickspencer3Assuming that you've added another sprite called self.apple that tries to hit the guy, you can use one of the many pygame collision detection functions in every call to update_game to see if the apple hit the guy:18:46
rickspencer3        if pygame.sprite.collide_rect(self.guy,self.apple):18:46
rickspencer3            self.guy.kill()18:46
rickspencer3BELIEVE ME18:46
rickspencer3you don't want to write your own collision detection routines18:46
rickspencer3there are lots of good functions18:47
rickspencer3ones that compare whole groups of sprites, for example18:47
rickspencer3If you set the rect for your Sprite subclass, functions like this work well, and are easy.18:47
rickspencer3I also mentioned sounds.18:47
rickspencer3Pygame has a really rich set of sound functions.18:47
rickspencer3The easiest thing to demo is playing a sound from a file, like this:18:47
rickspencer3            sound_path = get_media_file("beep_1.wav")18:47
rickspencer3            sound = pygame.mixer.Sound(sound_path)18:47
rickspencer3            sound.play()18:47
rickspencer3....18:48
rickspencer3and18:48
rickspencer3that's everything I prepared for this session18:48
rickspencer3I'm happy to take some questions18:48
rickspencer3or maybe everyone is busy playing smashies right now18:48
ClassBotThere are 10 minutes remaining in the current session.18:50
rickspencer3thanks ClassBot18:51
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: Making your app appear in the Indicators - Instructors: tedg
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/08/%23ubuntu-classroom.html following the conclusion of the session.19:00
tedgHowdy folks.19:01
tedgMy name is Ted and I work at the Canonical Desktop Experience team.19:02
tedgSpecifically I work with the various indicators, I like to joke that "I control the upper right corner of your screen" ;-)19:02
tedgBut, that's really not the case.19:02
tedgReally what we do is expose the functionality that is in the system to the user.19:03
tedg*and* probably more importantly, the information that comes from applications.19:03
tedgThis session is about getting that information out of the applications and handing it up to the indicators.19:03
tedgWe're going to cover quickly a few different ways, and then I'll take questions as long as you guys have 'em to go more in depth.19:04
tedgSpecifically, I'm going to cover messaging menu, application indicator and the sound menu.19:04
tedgSo, let's get started.19:04
tedgI'm going to start with the messaging menu because it's the oldest (and I couldn't figure out any other ordering that made sense)19:05
tedgThe spec for the messaging menu is here: https://wiki.ubuntu.com/MessagingMenu19:05
tedgI think what makes the most sense to look there is at the rationale.19:05
tedgIt's a menu that is designed to handle human-to-human communication in an aggregated way.19:05
tedgIt's like you communicate with people in a variety of ways, but not all of those need icons on your panel.19:06
tedgSo if you're looking at an application that does that, how do you integrate?19:06
tedgYou use libindicate, which allows your application to indicate on dbus that you have messages.19:06
tedglibindicate hides all the dbus stuff, so you don't need to worry about that, it's more about representing the info you have.19:07
tedgSo where is it?  The source for the library itself is at http://launchpad.net/libindicate19:07
tedgIt has both the client and the server, but chances are you'll only need one of those.19:07
tedgAnd that's the server.19:07
tedgThe client is used by the menu itself, and put into a single library so they always remain consistent19:08
tedgLet's look at an example in Python: http://bazaar.launchpad.net/~indicator-applet-developers/libindicate/trunk/view/head:/examples/im-client.py#L5819:08
tedgThis is a simple "IM Client"19:08
tedgthought it really only makes a single entry in the messaging menu.19:09
tedgAnd it tells the messaging menu that it's really Empathy.19:09
tedgI don't recommend lying in your code :-)19:09
tedgAs we look at that example you can see that the code grabs the default server and sets some properties on it.19:10
tedgThe most significant here is the desktop file as we use that to get a bunch of information like the icon and name of the application out of there.19:10
tedgYour application probably already has a desktop file, just throw the path to it in there.19:10
tedgThen it creates an indicator.  These are the items under your application in the messaging menu.19:11
tedgThis one is a time based one as you see the time gets set there.19:11
tedgBut there can also be count based for applications like e-mail programs that have mailboxes.19:11
tedgThere are design guide lines for how various applications should integrate.19:12
tedghttps://wiki.ubuntu.com/MessagingMenu#How_applications_should_integrate_with_the_messaging_menu19:12
tedgObviously that doesn't cover all applications, but it should be enough to get you started.19:12
tedgYou can also set properties like whether the envelope changes color or not as well.19:13
tedgAnd sort the various items.19:13
tedgThere is also the ability to put custom menu items on the menu, but I'm not going to go into that today unless there are some questions.19:14
tedgSecond up is application indicators.19:14
tedgYou can find out some about the design of those guys here: https://wiki.ubuntu.com/DesktopExperienceTeam/ApplicationIndicators19:14
tedgAnd a bit about their rationale.19:15
tedgOne of the things that they're targeting is allowing applications that are long running and need to put status of some type on the panel, to do so in a consistent way.19:15
tedgThe way that we've chose is an icon (possibly with a label) and a menu.19:15
tedgThis allows the entire top of the screen to behave like a menu bar.19:16
tedgApplication indicators are based on the KDE Status Notifier Item spec, but to create one you can just use libappindicator.19:16
tedghttp://launchpad.net/libappindicator/19:17
tedgThis is a small library that implements the KSNI spec over dbus and provides an easy way to support it in your application.19:17
tedgIt also provides an internal fallback to using the status area on desktops that don't support KSNI.19:17
tedgSo you don't have to do that fallback in your application manually.19:17
tedgFor those who are already familiar with libappindicator, we've got some new features this cycle.19:18
=== tyler is now known as Guest71989
tedgFirst off, it's now it's own library.  Which will hopefully ease its adoption by other distros.19:18
tedgThere's no need to pull in the entire indicator stack just for providing libappindicator.19:19
tedgWe're also supporting actions on middle click.19:19
tedgThis is a tricky one, as we don't want to create undiscoverable functionality.19:19
tedgSo what we've done is allow for a menu item that's already in the menu to be specified to receive middle click events.19:19
tedgThis way that functionality is always available, and visible, to the user.19:20
tedgBut power users can get some quick access to it if they choose.19:20
tedgWe have some design guidlines for the app indicators.19:20
tedghttps://wiki.ubuntu.com/CustomStatusMenuDesignGuidelines19:20
tedgThe important thing to remember, is that app indicators aren't the end all be all of what you want.19:21
tedgThere's been a long tradition in computing of doing stuff like this for every application, but that doesn't mean it's right :-)19:21
tedgWe'd love it if people would integrate with the other category indicators (messaging, sound, etc.) before building their own.19:21
tedgAlso, for many applications, launcher integration makes more sense.19:21
tedg(I believe Jason just talked about that, no?)19:22
tedgSo remember all of those options before you choose an applicaiton indicator19:22
tedgNow, if you do, it's easy to do :-)19:22
tedgHere's a simple client, that does everything possible (except middle click) http://bazaar.launchpad.net/~indicator-applet-developers/libappindicator/trunk/view/head:/example/simple-client-vala.vala19:23
tedgNow it's a bit more complex than you need really.19:23
tedgAs it has dynamic items and changes status, but it does show you the full spectrum of possibilities.19:23
tedgThere's a C version as well19:24
tedghttp://bazaar.launchpad.net/~indicator-applet-developers/libappindicator/trunk/view/head:/example/simple-client.c19:24
tedgThe most important part is here:19:24
tedghttp://bazaar.launchpad.net/~indicator-applet-developers/libappindicator/trunk/view/head:/example/simple-client.c#L16019:24
tedgWhere it creates the new object.19:24
tedgIt has a name and an icon.19:24
tedgAnd a category.19:25
tedgThen you build up a standard GTK menu, and you set it here: http://bazaar.launchpad.net/~indicator-applet-developers/libappindicator/trunk/view/head:/example/simple-client.c#L22619:25
tedgYour menu doesn't need to be as long.19:25
tedgBut it's neat to see the things you can do there.19:25
tedgAs far as signals go, you can just attach to the standard GTK ones on the menu items.19:25
tedglibappindicator will synthesize them for you.19:26
tedgSo there's nothing to learn other than standard GTK menus.19:26
tedgSo while the example is longer, there's only those two critical spots.19:27
tedgOkay, just checking my notes... think I got everything :-)19:27
tedgLast up is the newest in our bunch, the sound menu.19:28
tedgThe sound menu takes care of all your sound related stuff.19:29
tedgAgain it uses a standard protocol, MPRIS, but we've provided a smaller library that implements the critical functionality.19:29
tedgIn this case, it is a couple of interfaces in libunity.19:29
tedghttp://launchpad.net/libunity19:29
tedgThere's no need for you to learn DBus or MPRIS, you can ust use the MusicPlayer interface there.19:30
tedghttp://bazaar.launchpad.net/~unity-team/libunity/trunk/view/head:/src/unity-sound-menu.vala#L6119:30
tedgIt provides your basic setting of playlists and getting signals for play/pause/next/prev type controls.19:30
tedgSo as soon as you set up one of those objects, your application will get a full music player control in the sound menu.19:31
tedgJust like Rhythmbox or Banshee.19:31
tedgIt doesn't matter if you're getting the sound off the web, or local files, or how you get the music.19:31
tedgThat's up to you :-)19:31
tedgLet's look at an example19:32
tedghere's a "TypicalPlayer" object19:32
tedghttp://bazaar.launchpad.net/~unity-team/libunity/trunk/view/head:/test/vala/test-mpris-backend-server.vala#L2319:32
tedgYou can see how it sets the metadata for the song19:32
tedgAnd even the album art19:33
tedgAnd create a playlist as well.19:33
tedgThe typical player then sets up signals for the various buttons.19:33
tedgThis is part of the test suite, so it doesn't implement all of the backend for this.19:33
tedgBut it provides a good show of how you can connect into the object.19:34
tedgYou'll also see on line 56: http://bazaar.launchpad.net/~unity-team/libunity/trunk/view/head:/test/vala/test-mpris-backend-server.vala#L5619:34
tedgThat it builds a small menu for custom items like setting your preference for the song.19:34
tedgThis can help with something like a Pandora client, where we want more information quickly available to the user.19:34
tedgThese are standard menu items so you can make them check boxes, radio buttons, or what ever you wish.19:35
tedgThere's not a whole lot of magic there, but that's largely because libunity takes care of all of that for you :-)19:35
tedgLastly, I wanted to talk about the TODO list a little if this interested you but you didn't have an application specifically that you wanted to work on.19:36
tedgOne of the big things that we did in this cycle was ensure that we had GObject Introspection bindings for all the indicator libs.19:36
tedgWe'd like to drop all the hand coded ones.19:37
tedgBut to do that we need all the applications currently using them in non-C languages to port over.19:37
tedgSo if you're interested in helping out, we'd love some help there.19:37
tedgAlso, we need to port the various examples over to using the GI bindings.19:37
tedgTo make it easier for new people coming in to using them.19:38
tedgSo, that's the end of my notes on the various ways for applications to integrate with the indicators.19:38
tedgI hope that gives everyone a good introduction to the possibilities19:39
tedgDoes anyone have questions or want me to dive deeper into any of the topics?19:39
tedgGreat!  Thanks everyone.19:41
tedgCome grab me in #ayatana if you think of anything later19:42
ClassBotThere are 10 minutes remaining in the current session.19:50
ClassBotThere are 5 minutes remaining in the current session.19: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: Will it Blend? Python Libraries for Desktop Integration - Instructors: conscioususer
ClassBotLogs for this session will be available at http://irclogs.ubuntu.com/2011/09/08/%23ubuntu-classroom.html following the conclusion of the session.20:00
* conscioususer clears throat20:01
conscioususerHi folks!20:01
conscioususerMy name is Marcelo Hashimoto and I am the developer of Polly, a Twitter client designed for multiple columns of multiple accounts. (https://launchpad.net/polly)20:01
conscioususerPolly is being written in Python, with the GTK+ toolkit for the graphical interface, and uses many libraries commonly present in Ubuntu applications.20:01
conscioususerThis session is not about Polly itself, but about some of those libraries and their underlying concepts.20:02
conscioususerIn particular, libraries that help you to integrate your application with the desktop.20:02
conscioususer=== DESKTOP INTEGRATION20:02
conscioususerSo what exactly do I mean by "desktop integration"?20:02
conscioususerInformally, it is simply the noble attitude of "playing nice with others around you". :)20:03
conscioususerWhen you develop an application, you must always remember that it will not be used in a completely independent way.20:03
conscioususerIt will be used as part of a big ecosystem.20:03
conscioususerSo it is important to blend well inside this ecosystem, to minimize the amount of different behaviors that the end user needs to learn.20:03
conscioususerIn Ubuntu this means striving for two things:20:03
=== bUbu87 is now known as black_puppydog
conscioususer- consistency between different applications in a desktop environment20:04
conscioususer- consistency across different desktop environments20:04
conscioususerUbuntu, by default, uses the GNOME environment with Unity. But alternatives like KDE and XFCE are one click away in the Software Center.20:04
conscioususerSo you should not forget the users who prefer these alternatives.20:04
conscioususerAnd it's important to emphasize that, when I talk about consistency, I'm *not* only talking about visuals! In fact, visuals are only a small part of this presentation.20:04
conscioususerEverything will be clearer when I start giving concrete examples, so let's get on with it. :)20:05
conscioususer=== PRELIMINARIES20:05
conscioususerBefore starting, please download the tarball in http://ubuntuone.com/p/1Gzy/20:05
conscioususer(for those reading the transcript, I'll keep the tarball online, no worries)20:06
conscioususerThis tarball has some images I will reference here, and a text file with references that I will cite with [NUMBER].20:06
conscioususerThose references are not meant to be read now, only later if you are interested in more information.20:06
conscioususerThere are also some Python files that will not be used directly, but are there for you to play and modify as you want after the session.20:06
conscioususerThe hands-on during the session will be on the Python interactive shell (simply execute "python" in the terminal and you will be on it)20:06
conscioususerCommands to be given to the shell will be prefixed by >>>20:07
conscioususer=== OVERVIEW20:07
conscioususerThe session is divided in three parts, each one answering a question that inevitably arises in many applications:20:07
conscioususer1 - "How do I send notifications to the user?"20:07
conscioususer2 - "Where do I place files read or written by my application?"20:07
conscioususer3 - "What do I use to store sensitive information?"20:08
conscioususerand answering, of course, in a way that strives to blend well with the desktop that the user is currently using.20:08
conscioususerLike I mentioned before, some of you might be surprised with those topics, because the word "integration" is usually associated with visuals.20:08
conscioususerBut the truth is, if you use one of the most widely used toolkits, like Qt and GTK, visuals are almost a non-issue nowadays thanks to the efforts of the developers of those toolkits.20:08
conscioususerIf you open the images (warning: shameless self-promotion coming)20:09
conscioususerpolly-ubuntu-unity.png20:09
conscioususerpolly-ubuntu-shell.png20:09
conscioususerpolly-ubuntu-kubuntu.png20:09
conscioususerpolly-ubuntu-xubuntu.png20:09
conscioususeryou will see Polly visually integrated with four different environments (GNOME+Unity, GNOME-Shell, KDE and XFCE)20:09
conscioususerI did not write a single line of code that had the specific goal of reaching this visual integration.20:10
conscioususerThose four environments simply know what to do with GTK applications.20:10
conscioususerSo visuals will not be the main focus.20:10
conscioususerAll that said, the first part does have *some* visual elements involved.20:11
conscioususerAny questions so far?20:11
conscioususerOk, so let's begin!20:12
conscioususer=== PART 1: HOW DO I SEND NOTIFICATIONS TO THE USER?20:12
conscioususerI'm going to start with a quick hands-on example, and explain the concepts involved later.20:13
=== narfnarf is now known as dingens
conscioususerFor this part, you need to have the package gir1.2-notify-0.7 installed.20:13
conscioususerThis package comes in a default Natty/Oneiric install, actually.20:13
conscioususerIf you don't, do "sudo apt-get install gir1.2-notify-0.7"20:13
conscioususerAnd those of you who attended Dmitry Shachnev's session yesterday are already familiar with the Notify library I'm going to use.20:13
conscioususerWith the package installed, please open the Python shell and enter:20:13
conscioususer>>> from gi.repository import Notify20:13
conscioususerThis will load the library we will use, the Python bindings for libnotify.20:14
conscioususerBefore sending a notification, we should identify our application, for logging purposes:20:14
conscioususer>>> Notify.init('test')20:14
conscioususerYou should've received a "True" in response to this command, meaning that the identification was accepted.20:14
conscioususer Now we are ready to build a notification:20:16
conscioususer>>> notification = Notify.Notification.new('Test', 'Hello World!', 'start-here')20:16
conscioususerThe first parameter is the title of the notification, the second is the body text, and the third is the name of the icon you want the notification to use.20:16
conscioususerYou can change them at will.20:16
conscioususerIf I'm going too fast, for example if someone is still downloading a dependency, please let me know.20:16
conscioususerOk, moving on...20:17
conscioususerThe notification is now built, but it was not sent yet. Before sending it, we can set some details.20:17
conscioususerFor example, we can set the urgency level of this notification:20:17
conscioususer>>> notification.set_urgency(Notify.Urgency.LOW)20:17
conscioususerIn Ubuntu, non-urgent notifications are not shown when you are seeing a fullscreen video, among other things.20:17
conscioususerYou could also set an arbitrary image to be an icon.20:18
conscioususerBut let's not waste too much time on details. :) If you are ready, then let's pop the notification already:20:18
conscioususer>>> notification.show()20:18
conscioususerSo, did you see a notification bubble popping up in your desktop?20:18
conscioususerThis notification is completely consistent with other notifications from Ubuntu, like network connection and instant messages.20:18
conscioususerNot only on visuals, but also on behavior.20:19
conscioususerYou didn't have to explicitly code this consistency, all the code did was say "hey, desktop environment, whichever you are, please show this notification here!"20:19
conscioususerAnd the environment took care of the rest.20:19
conscioususerYou can execute this code in other enviornments, and it will work similarly. See the image20:19
conscioususernotify.png20:20
conscioususerIt will obey the guidelines of those environments. For example, in XFCE you can click to close, while in Ubuntu+Unity you can't by design20:20
conscioususerNow that we are warmed up, I will dive a little bit into a very important question that is under the hood of what we just did.20:21
conscioususerWhat exactly this library does? Is it a huge pile of "ifs" and "elses", that does different things for each environment?20:21
conscioususerThank goodness no, because that would mean the library depends on core libraries of all those environments, greatly increasing the dependencies of your app if you wanted to use it.20:21
conscioususerNo, it's actually much more elegant than that, thanks to the concept of20:21
conscioususer=== SPECIFICATIONS20:22
conscioususerA specification is basically a set of idioms and protocols, specifically designed to be environment-independent.20:22
conscioususerIn the case of notifications, this means a "common language" that is the only thing that notification senders and notifications receivers need to know.20:22
conscioususerSpecifications represent the foundation of a lot of integration you currently see in your system.20:22
conscioususerFor example, if you peek /usr/share/applications in your system, you will see a monolothic folder with .desktop files for all the applications installed.20:22
conscioususerHow this monolithic folder becomes neatly categorized menus in GNOME, KDE, XFCE, etc.?20:23
conscioususerIt's thanks to the Desktop Entry Specification [2] and Desktop Menu Specification [3] that specify how .desktop files have to be written, and their contents mean wrt categorization.20:23
conscioususerAnother example20:23
conscioususerThe library libdbusmenu provides a common language through which applications can send menus to each other.20:23
conscioususerThis library is what allows implementing the global menu you see in20:23
conscioususerpolly-ubuntu-unity.png20:23
conscioususerpolly-kubuntu.png20:24
conscioususerwithout the need of Qt-specific code or special conditions inside Polly.20:24
conscioususerA lot of those specifications are written by the community effort in freedesktop.org [1], though other sources exist.20:24
conscioususerIf you are curious on knowing more, the specification for notifications used by libnotify can be seen in [4].20:24
conscioususerlibnotify represents an ideal situation for a specification20:24
conscioususerIt has been adopted by the most popular environments and is so high-level that app developers don't even need to know that the specification exists.20:24
conscioususerthe library API is high-level, I mean20:25
conscioususerIt's like that old cliche from martial arts movies.20:25
conscioususerYou know that an specification has been mastered when you don't have to use it. :)20:25
conscioususerBut sometimes it's not so clean, even when a specification exists.20:25
conscioususerWhich brings us to the next topic.20:25
conscioususer=== PART 2: WHERE DO I PLACE FILES READ OR WRITTEN BY MY APPLICATION?20:26
conscioususerBefore I continue, any questions?20:26
* conscioususer waits a bit...20:26
conscioususerok, let's move on20:27
=== jrgifford_ is now known as jrgifford
conscioususerWhen your application starts to become a little more complex than helloworlding, it is highly possible that at some point you will need to read and write files.20:27
conscioususerThose can usually be categorized in three types: configuration files, data files, and cache files.20:27
conscioususerThe question is, where should you put them?20:27
conscioususerA lot of applications simply create a .APPNAME folder in the user's home, but that's usually considered bad practice.20:27
conscioususerFirst, because it clutters the home folder.20:27
conscioususerSecond, because separating files by type first can be more useful.20:28
conscioususerFor example, if all cache files of all applications are in the same folder, desktop cleaners know they can safely delete this folder for a full app-independent cache cleanup.20:28
conscioususerAlso, file indexers can be programmed to ignore the entire folder if they want.20:28
conscioususerBut of course, you can only avoid this if environments follow the same guidelines for where placing those types.20:28
conscioususerI guess you know the direction I'm going, right? :)20:29
conscioususerBase Directory Specification [5]20:29
conscioususerThis specification establishes the environment variables that define where files of a certain type should be placed.20:29
conscioususerYou can check them right now.20:29
conscioususerIn the Python interpreter enter20:29
conscioususer>>> import os20:29
conscioususer>>> print os.environ['XDG_DATA_DIRS']20:29
conscioususerThis will print the content of the XDG_DATA_DIRS variable, which is a list of paths separated by colons.20:30
conscioususerThis list contains the paths where data files are expected to be, in order of priority.20:30
conscioususeryou can also try 'XDG_DATA_HOME', for example20:31
conscioususerwhich is the path for the specific user20:31
conscioususerNow, parsing this string is not particularly difficult, but it is annoying to reinvent this wheel for every application you write.20:31
conscioususerSo instead, you can use the PyXDG library.20:31
conscioususerIt also comes by default in Natty/Oneiric.20:31
conscioususerIf you don't have it, just do "sudo apt-get install python-xdg"20:31
conscioususerNow, in the Python interpreter, enter20:32
conscioususer>>> from xdg import BaseDirectory20:32
conscioususerThe BaseDirectory class takes care of all reading and parsing of the spec environment variables for you.20:32
conscioususerFor example, all you need to do to access data paths is to use the variable20:32
conscioususer>>> BaseDirectory.xdg_data_dirs20:33
conscioususerwhich has all paths in a neat Python list, ready to be used.20:33
conscioususerIf you want to know more details about using this library, I recommend you to read [5] and also entering in the interpreter20:33
conscioususer>>> help(BaseDirectory)20:33
conscioususer(type 'q' to leave help mode)20:33
conscioususerAs you can see, in this case the app developer is much closer to the metal than on the notifications case. He actually needs to know some details about the specification.20:34
conscioususerThe reason is simple: what is done once you know the paths is highly application-dependent.20:34
conscioususerSome use data folders to store icons, others to store databases.20:34
conscioususerSome applications don't use caching at all.20:34
conscioususerAnd so on.20:34
conscioususerSo higher-level interfaces wouldn't really help much.20:34
conscioususerBut the specification itself is very short and easy to understand.20:34
conscioususerAnd the integration is worth the effort.20:35
conscioususerAre there any questions about the usage of python-xdg?20:35
conscioususerI can wait a bit. :)20:35
conscioususerOk20:36
conscioususerTime to wrap part 220:36
conscioususerThe only storage that the Base Directory specification does not cover is the storage of sensitive information.20:36
conscioususerWhich brings us to the third part.20:37
conscioususer=== WHAT DO I USE TO STORE SENSITIVE INFORMATION?20:37
conscioususerIf you application stores sensitive info like passwords, it is usually considered a security flaw to store them in plain text.20:37
conscioususer(I say "usually" because it's not that much of a big deal if you live alone and use a computer that is never connected to the internet, for example)20:37
conscioususerThat's why desktop environments provide keyrings, which are encrypted storages unlocked by a master password or at login.20:37
conscioususerFor example,20:37
conscioususerGNOME has GNOME-Keyring, while KDE has KWallet.20:37
conscioususerG-K is widely used by GNOME apps, like Empathy, Evolution, networkmanager...20:38
conscioususerBut now here comes the bad news20:38
conscioususerFor the moment, there are no specifications on storage for sensitive information.20:38
conscioususerfreedesktop.org has a draft, but is still in progress [6]20:38
conscioususerSo these two keyrings use different idioms.20:38
conscioususerwhich is a very bad thing for developers who want cross-environment applications.20:38
conscioususerUsually, the only way to ensure cross-environment in this case is implementing directly in your code20:40
conscioususerAnd now here comes the good news: the python-keyring library20:41
conscioususerBasically, an awesome developer has bad that for you!20:41
conscioususer(sudo apt-get install python-keyring)20:41
conscioususer(this one does *not* come in a default Ubuntu install)20:41
conscioususerThis library does all the dirty work of finding out which keyring should be used according to the environment you are on.20:42
conscioususerIt supports GNOME-Keyring, KWallet and also Windows and OSX keyrings (though I never tested it for those last two)20:42
conscioususerAnd wraps this in a surprisingly elegant API.20:42
conscioususerReally20:42
conscioususerLet's go back to the interpreter20:42
conscioususerDid you all install python-keyring already?20:43
conscioususerOps20:45
conscioususerbefore I continue, I should make an observation20:46
conscioususerit seems that XDG_DATA_HOME is not found in os.environ20:46
conscioususerstrangely, its entry works in xdg.BaseDirectory and it is on the spec20:47
conscioususerI'll investigate this later, sorry about that20:47
conscioususerAnyway20:47
conscioususerLet's go back to the interpreter and load the library:20:47
conscioususer>>> import keyring20:47
conscioususerNow let's store a dummy password in the keyring20:48
conscioususer>>> keyring.set_password('appname', 'myusername', 'mypassword')20:48
conscioususer(I think the strings are all self-explanatory)20:48
conscioususerIf you are using GNOME, you can see the password stored in Seahorse, type "seahorse" in the terminal or look in the applications for System > Passwords & Encryption20:48
conscioususerIt is labeled with the generic name of 'network password' (IIRC next installments of python-keyring will try to use a better naming scheme)20:48
conscioususerDid you find it? :)20:49
conscioususerNow let's retrieve it20:49
conscioususer>>> print keyring.get_password('appname', 'myusername')20:50
conscioususerYep.20:50
conscioususerIt's *that* simple.20:50
ClassBotThere are 10 minutes remaining in the current session.20:50
conscioususerThat's not really much to talk about the library really, it is specifically designed to be easy to talk about. :)20:51
conscioususerOf course, you lose some particular flexibility from GNOME-Keyring or KWallet, but for most applications those wouldn't be used.20:51
conscioususerFor simple account storage, python-keyring suffices and only occupies a couple of lines of code in your app.20:52
conscioususerIt's really convenient20:52
conscioususerWell, I think it's time for me to wrap up.20:52
conscioususerHopefully this session was helpful for you to make the first steps into integrating your app in Ubuntu transparently20:52
conscioususerOr, better saying, playing nice with others around you. :)20:52
conscioususerAre there any questions?20:52
conscioususerOn the XDG_DATA_HOME issue20:53
conscioususerI guess this precisely why using python-xdg is convenient. :)20:53
conscioususerIt works around this kind of problem.20:53
conscioususerYou can play with the files I gave in the tarball, and modify them to experiment with the libraries.20:55
conscioususerI purposefully chose some libraries with technically simple APIs, as I wanted to dedicate part of this session to talk about the concept of specifications themselves.20:55
ClassBotThere are 5 minutes remaining in the current session.20:55
conscioususerOk, I guess that's pretty much it. :)20:57
conscioususerThank you very much for listening, and for attending today's sessions.20:57
conscioususerHope we have a nice last appdev day tomorrow. :)20: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 ||
nigelbpleia2: solved the kernel oops? ;)21:10
pleia2heh, no21:10
nigelbwe gave up for the night. Part of the problem was 32-bit binaries on 64-bit machine. BUt still - yay for ruined night's sleep.21:12
nigelb3 AM \o/21:12
=== Guest87485 is now known as gord

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