[Sugar-devel] [PATCH Record (Gtk3)] Use new syntax for Gst.Caps

2013-02-06 Thread Manuel Kaufmann
Using the new syntax for Gst.Caps we avoid Gst's WARNING message in
the log.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 glive.py | 18 +++---
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/glive.py b/glive.py
index 5d78bbe..d39e292 100644
--- a/glive.py
+++ b/glive.py
@@ -102,8 +102,7 @@ class Glive:
 
 pipeline = Gst.Pipeline()
 
-# WARNING **: 0.10-style raw video caps are being created. Should be 
video/x-raw,format=(string)
-caps = Gst.Caps.from_string('video/x-raw-yuv,framerate=10/1')
+caps = Gst.Caps.from_string('video/x-raw, format=(string)yuv, 
framerate=(fraction)10/1')
 camerafilter = Gst.ElementFactory.make(capsfilter, capsfilter)
 camerafilter.set_property(caps, caps)
 
@@ -165,8 +164,7 @@ class Glive:
 if not hwdev_available:
 src.set_property(device, default)
 
-# WARNING **: 0.10-style raw audio caps are being created. Should be 
audio/x-raw,format=(string)
-srccaps = 
Gst.Caps.from_string(audio/x-raw-int,rate=16000,channels=1,depth=16)
+srccaps = Gst.Caps.from_string(audio/x-raw, rate=(int)16000, 
channels=(int)1, depth=(int)16)
 
 # guarantee perfect stream, important for A/V sync
 rate = Gst.ElementFactory.make(audiorate, 'audiorate')
@@ -210,8 +208,7 @@ class Glive:
 
 scale = Gst.ElementFactory.make(videoscale, vbscale)
 
-# WARNING **: 0.10-style raw video caps are being created. Should be 
video/x-raw,format=(string)
-scalecaps = 
Gst.Caps.from_string('video/x-raw-yuv,width=160,height=120')
+scalecaps = Gst.Caps.from_string('video/x-raw, format=(string)yuv, 
width=(int)160, height=(int)120')
 scalecapsfilter = Gst.ElementFactory.make(capsfilter, scalecaps)
 scalecapsfilter.set_property(caps, scalecaps)
 
@@ -273,7 +270,7 @@ class Glive:
 vbenc = self._videobin.get_by_name(vbenc)
 vbenc.set_property(quality, 16)
 #scaps = self._videobin.get_by_name(scalecaps) # FIXME: If these 
elements connect the pipeline does not run.
-#scaps.set_property(caps, 
Gst.Caps.from_string(video/x-raw-yuv,width=%d,height=%d % (width, height)))
+#scaps.set_property(caps, Gst.Caps.from_string(video/x-raw, 
format=(string)yuv, width=(int)%d, height=(int)%d % (width, height)))
 
 def _create_pipeline(self):
 
@@ -287,10 +284,10 @@ class Glive:
 # camera level
 
 if self._can_limit_framerate:
-srccaps = Gst.Caps.from_string('video/x-raw-yuv,framerate=10/1')
+srccaps = Gst.Caps.from_string('video/x-raw, format=(string)yuv, 
framerate=(fraction)10/1')
 
 else:
-srccaps = Gst.Caps.from_string('video/x-raw-yuv')
+srccaps = Gst.Caps.from_string('video/x-raw, format=(string)yuv')
 
 # we attempt to limit the framerate on the v4l2src directly, but we
 # can't trust this: perhaps we are falling behind in our capture,
@@ -299,7 +296,7 @@ class Glive:
 # for A/V sync because OGG does not store timestamps, it just stores
 # the FPS value.
 rate = Gst.ElementFactory.make(videorate, 'videorate')
-ratecaps = Gst.Caps.from_string('video/x-raw-yuv,framerate=10/1')
+ratecaps = Gst.Caps.from_string('video/x-raw, format=(string)yuv, 
framerate=(fraction)10/1')
 
 tee = Gst.ElementFactory.make(tee, tee)
 queue = Gst.ElementFactory.make(queue, dispqueue)
@@ -860,4 +857,3 @@ class Glive:
 
 if os.path.exists(mux_path):
 os.remove(mux_path)
-
\ No newline at end of file
-- 
1.7.11.7

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [RELEASE] sugar-toolkit-gtk3-0.98.2

2012-12-17 Thread Manuel Kaufmann
On Mon, Dec 17, 2012 at 6:49 PM, Simon Schampijer si...@schampijer.de wrote:
 The 2 points for KaufmannQuiñones 1 for Garnacho release.

Yeah! We are closer of getting the ticket to Germany :)

Congratulation to all the team involved on this!

-- 
Kaufmann Manuel
-- http://mkaufmann.com.ar
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [Release] Clock-12

2012-12-16 Thread Manuel Kaufmann
Hi Daniel,

On Sun, Dec 16, 2012 at 3:41 PM, Gary Martin garycmar...@googlemail.com wrote:
 This is a release of Clock-12 to fix #4079 (broken speech) for landing in the 
 13.1.0 release (thanks go to Humitos for the patch).

Can we include this version of Clock?. It solves a really good feature
that it will be a pity if it's not included on the image.

-- 
Kaufmann Manuel
-- http://mkaufmann.com.ar
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [sugar-toolkit-gtk3 PATCH] sl#4276: Writing the icon-files for .xo files on a permanent mount-point, and not /tmp. mount-point.

2012-12-10 Thread Manuel Kaufmann
On Mon, Dec 10, 2012 at 4:09 PM, Ajay Garg a...@activitycentral.com wrote:
 Thus, now as the solution, we write the icon-files (maximum of one file per 
 activity) at ~/.sugar/default/icon_files. Now, the  icons are rendered 
 correctly then.

I didn't check the patch yet, but I don't see anything that collects
the icon garbage at any point. I mean, if you download many activities
from ASLO and go to the Journal, those icons will be copied into
~/.sugar/default/icon_files and displayed properly in the Journal.
Then, you remove the downloaded files but those icons will still be
there at ~/.sugar/default/icon_files.

Am I right?

-- 
Kaufmann Manuel
-- http://mkaufmann.com.ar
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] Automated testing

2012-12-08 Thread Manuel Kaufmann
On Fri, Dec 7, 2012 at 8:48 PM, Daniel Narvaez dwnarv...@gmail.com wrote:
 Link to the test case (tree.py is an helper that I'm trying to integrated in
 toolkit)


Good! This is really useful. I was playing with it yesterday and I found it fun!

Another utility that I found useful is this one:

https://live.gnome.org/Accerciser

It allows us to explore the full structure of our Gtk application that
are running. So, we can explore our Activities to look for the
specific widget. Then use find_child / find_children with the name
and role_name to find them.

I wrote a simple (and awful) test using these utilities to check that
the frame is shown and it works. It uses ImageMagick to call the
compare command.

The idea:

 - preset a language
 - preset a XO color

 - look for the widget
 - run event on them (click, motion, etc)
 - wait some secs so those events take effect
 - take a screenshot
 - crop it (check only the proper section)

 - compare that screenshot with another already taken manually by us

Known issues:

 - we need to hide the mouse cursor
 - sensible to different resolutions
 -  others 

Maybe you can find something interesting here. Good luck with this :P

Cheers,

-- 
Kaufmann Manuel
-- http://mkaufmann.com.ar


test_frame.py
Description: Binary data


my_screenshot.png.bak
Description: Binary data
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] sugar-build make build-sugar-artwork and quad-core compilation

2012-11-27 Thread Manuel Kaufmann
On Mon, Nov 26, 2012 at 6:08 PM, Daniel Narvaez dwnarv...@gmail.com wrote:
 * make build only build the sources

build just builds!

 * make pull only pulls the sources

pull just pulls!

 * make check the system, pull the sources and builds them. (which is
 what make build was doing before)

... make ... just  make? :P

What's up if there are no changes on the source code? make (and make
build) will build it anyway?

I'm happy with this. I think it's clearer now.

PS: make build-* works again! Wiii!

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [RELEASE] sugar-0.97.13

2012-11-27 Thread Manuel Kaufmann
On Tue, Nov 27, 2012 at 4:55 PM, Simon Schampijer si...@schampijer.de wrote:

Meh...

The boring release with no funny summary

;-)


-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] sugar-build make build-sugar-artwork and quad-core compilation

2012-11-26 Thread Manuel Kaufmann
Hi,

Sometime ago I used to run:

  make build-sugar-artwork

to just re-compile sugar-artwork. Nowadays that is not more possible.
Any clue here?

Another issue is that I was able to set -j 8 to make and use more
than one CPU to compile all sources. Is there any way to do that in
the current sugar-build implementation?

Cheers,

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] sugar-build make build-sugar-artwork and quad-core compilation

2012-11-26 Thread Manuel Kaufmann
On Mon, Nov 26, 2012 at 3:06 PM, Daniel Narvaez dwnarv...@gmail.com wrote:
 can you explain how you are using it exactly? I didn't readd it when I
 rewrote things because I was not very clear on the use case (I
 normally just make; make install stuff inside a shell).

$ make build-sugar - just compile and install sugar
$ make build-sugar-artwork - just compile and install sugar-artwork

and so on...

It seems to be a shortcut for do what you described here.

 1. make shell
 2. cd source/sugar
 3. make
 4. make install

 Another issue is that I was able to set -j 8 to make and use more
 than one CPU to compile all sources. Is there any way to do that in
 the current sugar-build implementation?

 That's supposed to just work

Oh! It's automatic! Great!

I can see the make -j8 in the logs ;)

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] sugar-build make build-sugar-artwork and quad-core compilation

2012-11-26 Thread Manuel Kaufmann
On Mon, Nov 26, 2012 at 3:59 PM, Daniel Narvaez dwnarv...@gmail.com wrote:
 But did you use it to build your own changes or changes someone made
 to the repo? Or both?

I'm not sure if I used it for both.

I used it before knowing auto-install. I mean, I made a change on
some .py file and I ran make build-sugar for example.

That's all.

PS: I can live without that option, maybe I'm the only one that want
to use it. So, do not complicate your life. It's not so annoying to
enter to the shell and run make ; make install

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] Shared activity game - Maze

2012-11-24 Thread Manuel Kaufmann
On Sat, Nov 24, 2012 at 6:34 PM, RJV jv.ravichand...@gmail.com wrote:
 It will be great fun if both the mazes were the same and both players could
 play on the same maze, racing against each other, as in the single XO,
 multi-players scenario!

It does really work in that way in Maze-22. I worked on that two weeks ago and I
tested it a lot. I played with up to 3 player per XO ;)

What version of Maze are you using?

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [sugar-build] Recent improvements

2012-11-18 Thread Manuel Kaufmann
On Fri, Nov 16, 2012 at 2:10 PM, Daniel Narvaez dwnarv...@gmail.com wrote:
 in the last couple of weeks I worked a lot on sugar-build and made a
 bunch of improvements:

Well! You are doing a really good work! Congratulations and thanks for that!

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] Activities without summaries

2012-11-14 Thread Manuel Kaufmann
On Wed, Nov 14, 2012 at 9:22 AM, Gonzalo Odiard gonz...@laptop.org wrote:
 -InfoSlicer.activity/activity/activity.info

Done.

http://git.sugarlabs.org/infoslicer/mainline/commit/142d6f43c28e2eb5364c9c93fedd91b15ec0dbad

Thank you for this email.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] Browse activity proxy settings

2012-11-11 Thread Manuel Kaufmann
On Sun, Nov 11, 2012 at 11:41 AM, Ariel Calzada
ar...@activitycentral.com wrote:
 I would like to know if there's a way to make Browse activity use PROXY
 SETTINGS. I tried configuring proxy settings in My settings/Network with
 no luck.

I think we have to modify Browse to make this possible. I didn't find
anything related with proxy on Browse's code.

Do you know what My settings/Network does?

I found there is a simple way (but I didn't try it yet) to make use of
the http_proxy env variable from WebKitGtk:

 http://lists.macosforge.org/pipermail/webkit-help/2009-December/000475.html

If My settings/Network set that environment variable we can use it,
if no, we need to know what it does and read that value.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [RELEASE] sugar-0.97.11

2012-11-10 Thread Manuel Kaufmann
On Sat, Nov 10, 2012 at 7:51 AM, Simon Schampijer si...@schampijer.de wrote:
 The one step closer to collaboration release.

Well! That's really good!

What is missing to say that collaboration is working properly?
Yesterday, I worked on Maze Collaboration[1] on os9 and os10 with the
sugar version compiled from the git repository and I was able to play
with three XO without any problem.

Can I help in some way?

[1] http://bugs.sugarlabs.org/ticket/3747

--
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH sugar-toolkit-gtk3] Sugar scroll bar clicks should invoke page up/page down SL #3859

2012-11-05 Thread Manuel Kaufmann
On Mon, Nov 5, 2012 at 8:55 AM, Daniel Narvaez dwnarv...@gmail.com wrote:
 Also would be nice to update pygobject and others, and use them from
 packages now that there are for both Fedora and Ubuntu.

 Are these packaged for Fedora 17? We don't have support for Fedora 18
 in sugar-build yet but I'm planning to add it next week, when the beta
 is released (assuming it does work in a vm).

That's the problem. I didn't find the latest version of pygobject and
gtk built for Fedora 17. I think we should update the commit hash on
the sugar-build tool to get the latest version and compile it as we
are doing now with an older version.

--
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Read] Show 'No book' message when Read starts from scratch

2012-11-05 Thread Manuel Kaufmann
When the user starts a new instance of Read the 'No book' message is
shown with a button to 'Choose a book' that opens the Object Chooser.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 emptypanel.py   | 45 +
 icons/activity-read.svg | 11 +++
 readactivity.py |  8 ++--
 3 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 emptypanel.py
 create mode 100644 icons/activity-read.svg

diff --git a/emptypanel.py b/emptypanel.py
new file mode 100644
index 000..d8fa042
--- /dev/null
+++ b/emptypanel.py
@@ -0,0 +1,45 @@
+import logging
+
+from gi.repository import Gtk
+
+from sugar3.graphics import style
+from sugar3.graphics.icon import Icon
+
+
+def show(activity, icon_name, message, btn_label, btn_callback):
+empty_widgets = Gtk.EventBox()
+empty_widgets.modify_bg(Gtk.StateType.NORMAL,
+style.COLOR_WHITE.get_gdk_color())
+
+vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+mvbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+vbox.pack_start(mvbox, True, False, 0)
+
+image_icon = Icon(pixel_size=style.LARGE_ICON_SIZE,
+  icon_name=icon_name,
+  stroke_color=style.COLOR_BUTTON_GREY.get_svg(),
+  fill_color=style.COLOR_TRANSPARENT.get_svg())
+mvbox.pack_start(image_icon, False, False, style.DEFAULT_PADDING)
+
+label = Gtk.Label('span foreground=%sb%s/b/span' %
+  (style.COLOR_BUTTON_GREY.get_html(),
+   message))
+label.set_use_markup(True)
+mvbox.pack_start(label, False, False, style.DEFAULT_PADDING)
+
+hbox = Gtk.Box()
+open_image_btn = Gtk.Button()
+open_image_btn.connect('clicked', btn_callback)
+add_image = Gtk.Image.new_from_stock(Gtk.STOCK_ADD,
+ Gtk.IconSize.BUTTON)
+buttonbox = Gtk.Box()
+buttonbox.pack_start(add_image, False, True, 0)
+buttonbox.pack_end(Gtk.Label(btn_label), True, True, 5)
+open_image_btn.add(buttonbox)
+hbox.pack_start(open_image_btn, True, False, 0)
+mvbox.pack_start(hbox, False, False, style.DEFAULT_PADDING)
+
+empty_widgets.add(vbox)
+empty_widgets.show_all()
+logging.error('Showing empty Panel')
+activity.set_canvas(empty_widgets)
diff --git a/icons/activity-read.svg b/icons/activity-read.svg
new file mode 100644
index 000..d0d1804
--- /dev/null
+++ b/icons/activity-read.svg
@@ -0,0 +1,11 @@
+?xml version=1.0 ?!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [
+   !ENTITY stroke_color #010101
+   !ENTITY fill_color #FF
+]svg enable-background=new 0 0 55 55 height=55px version=1.1 
viewBox=0 0 55 55 width=55px x=0px xml:space=preserve 
xmlns=http://www.w3.org/2000/svg; xmlns:xlink=http://www.w3.org/1999/xlink; 
y=0pxg display=block id=activity-read
+   path d=M27.904,11.023h-0.002   
c0-0.002-1.71-2.053-9.376-2.504C10.86,8.07,6.843,10.121,6.84,10.122c-1.898,0.619-3.495,1.735-3.495,3.494v27.702
   
c0,2.025,1.235,3.494,3.495,3.494c0.003,0,4.41-1.35,10.004-1.35c5.589-0.001,11.061,2.253,11.061,2.253
 display=inline fill=fill_color; stroke=stroke_color; 
stroke-linejoin=round stroke-width=3.5/
+   path d=M27.898,11.023   
L27.898,11.023c0-0.002,1.715-2.053,9.377-2.504c7.668-0.449,11.686,1.602,11.688,1.603c1.897,0.619,3.494,1.735,3.494,3.494
   
v27.702c0,2.025-1.233,3.494-3.494,3.494c-0.003,0-4.409-1.35-10.004-1.35c-5.589-0.001-11.062,2.253-11.062,2.253
 display=inline fill=fill_color; stroke=stroke_color; 
stroke-linejoin=round stroke-width=3.5/
+
+   line display=inline fill=none stroke=stroke_color; 
stroke-linecap=round stroke-linejoin=round stroke-width=3.5 x1=27.898 
x2=27.9 y1=11.023 y2=45.717/
+   path d=   
M32.566,44.275c0,0-0.031,2.906-4.666,2.906c-4.632,0-4.663-2.906-4.663-2.906 
display=inline fill=none stroke=stroke_color; stroke-linecap=round 
stroke-linejoin=round stroke-width=3.5/
+/g/svg
+
diff --git a/readactivity.py b/readactivity.py
index 17f8455..846fef9 100644
--- a/readactivity.py
+++ b/readactivity.py
@@ -25,6 +25,7 @@ import re
 import md5
 import StringIO
 import cairo
+import emptypanel
 
 import dbus
 from gi.repository import GObject
@@ -335,7 +336,9 @@ class ReadActivity(activity.Activity):
 self.connect(joined, self._joined_cb)
 elif self._object_id is None:
 # Not joining, not resuming
-self._show_journal_object_picker()
+emptypanel.show(self, 'activity-read',
+_('No book'), _('Choose a book'),
+self._show_journal_object_picker_cb)
 
 def _create_back_button(self):
 back = ToolButton('go-previous-paired')
@@ -612,7 +615,7 @@ class ReadActivity(activity.Activity):
 else:
 logging.debug('link %s not found in the toc model', current_link)
 
-def

[Sugar-devel] [PATCH Jukebox] Show 'No media' message when Jukebox starts from scratch

2012-11-05 Thread Manuel Kaufmann
When the user starts a new instance of Jukebox the 'No media' message
is shown with a button to 'Choose media files' that opens the Object
Chooser.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 emptypanel.py  | 45 +
 icons/activity-jukebox.svg |  7 +++
 jukeboxactivity.py | 35 +++
 3 files changed, 75 insertions(+), 12 deletions(-)
 create mode 100644 emptypanel.py
 create mode 100644 icons/activity-jukebox.svg

diff --git a/emptypanel.py b/emptypanel.py
new file mode 100644
index 000..d8fa042
--- /dev/null
+++ b/emptypanel.py
@@ -0,0 +1,45 @@
+import logging
+
+from gi.repository import Gtk
+
+from sugar3.graphics import style
+from sugar3.graphics.icon import Icon
+
+
+def show(activity, icon_name, message, btn_label, btn_callback):
+empty_widgets = Gtk.EventBox()
+empty_widgets.modify_bg(Gtk.StateType.NORMAL,
+style.COLOR_WHITE.get_gdk_color())
+
+vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+mvbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+vbox.pack_start(mvbox, True, False, 0)
+
+image_icon = Icon(pixel_size=style.LARGE_ICON_SIZE,
+  icon_name=icon_name,
+  stroke_color=style.COLOR_BUTTON_GREY.get_svg(),
+  fill_color=style.COLOR_TRANSPARENT.get_svg())
+mvbox.pack_start(image_icon, False, False, style.DEFAULT_PADDING)
+
+label = Gtk.Label('span foreground=%sb%s/b/span' %
+  (style.COLOR_BUTTON_GREY.get_html(),
+   message))
+label.set_use_markup(True)
+mvbox.pack_start(label, False, False, style.DEFAULT_PADDING)
+
+hbox = Gtk.Box()
+open_image_btn = Gtk.Button()
+open_image_btn.connect('clicked', btn_callback)
+add_image = Gtk.Image.new_from_stock(Gtk.STOCK_ADD,
+ Gtk.IconSize.BUTTON)
+buttonbox = Gtk.Box()
+buttonbox.pack_start(add_image, False, True, 0)
+buttonbox.pack_end(Gtk.Label(btn_label), True, True, 5)
+open_image_btn.add(buttonbox)
+hbox.pack_start(open_image_btn, True, False, 0)
+mvbox.pack_start(hbox, False, False, style.DEFAULT_PADDING)
+
+empty_widgets.add(vbox)
+empty_widgets.show_all()
+logging.error('Showing empty Panel')
+activity.set_canvas(empty_widgets)
diff --git a/icons/activity-jukebox.svg b/icons/activity-jukebox.svg
new file mode 100644
index 000..b921d4f
--- /dev/null
+++ b/icons/activity-jukebox.svg
@@ -0,0 +1,7 @@
+?xml version=1.0 ?!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [
+   !ENTITY stroke_color #010101
+   !ENTITY fill_color #FF
+]svg enable-background=new 0 0 55 55 height=55px version=1.1 
viewBox=0 0 55 55 width=55px x=0px xml:space=preserve 
xmlns=http://www.w3.org/2000/svg; xmlns:xlink=http://www.w3.org/1999/xlink; 
y=0pxg display=block id=activity-jukebox
+   path d=M17.666,7.884v32.841   
c-2.587-0.614-7.914-0.612-10.755,1.764c-5.688,4.76-0.695,10.109,5.815,7.456c3.705-1.512,4.94-3.937,4.94-7.597V25.997
   
l30.952-3.516v12.974c-4.212-0.615-7.915-0.614-10.758,1.764c-5.688,4.76-0.695,10.109,5.815,7.454
   c3.705-1.51,4.942-3.936,4.942-7.596V4.293L17.666,7.884z 
M48.618,15.86l-30.952,4.029l0-5.225l30.953-4.102V15.86z display=inline 
fill=fill_color; stroke=stroke_color; stroke-width=3.5/
+/g/svg
+
diff --git a/jukeboxactivity.py b/jukeboxactivity.py
index 1bc4d4a..bde15a3 100644
--- a/jukeboxactivity.py
+++ b/jukeboxactivity.py
@@ -24,6 +24,7 @@
 import sys
 import logging
 import tempfile
+import emptypanel
 from gettext import gettext as _
 import os
 
@@ -152,31 +153,34 @@ class JukeboxActivity(activity.Activity):
 # self.bin = Gtk.HBox()
 # self.bin.show()
 
-self.canvas = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
+self._video_canvas = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
 self._alert = None
 
 self.playlist_widget = PlayListWidget(self.play)
 self.playlist_widget.update(self.playlist)
 self.playlist_widget.show()
-self.canvas.pack_start(self.playlist_widget, False, True, 0)
+self._video_canvas.pack_start(self.playlist_widget, False, True, 0)
 self._empty_widget = Gtk.Label(label=)
 self._empty_widget.show()
 self.videowidget = VideoWidget()
-self.set_canvas(self.canvas)
+self.set_canvas(self._video_canvas)
 self._init_view_area()
 self.show_all()
-self.canvas.connect('size-allocate', self.__size_allocate_cb)
+self._video_canvas.connect('size-allocate', self.__size_allocate_cb)
 
-#From ImageViewer Activity
 self._want_document = True
 if self._object_id is None:
-self._show_object_picker = GObject.timeout_add(1000, \
-self._show_picker_cb)
+emptypanel.show(self, 'activity

Re: [Sugar-devel] Problem playing videos in jukebox

2012-11-02 Thread Manuel Kaufmann
On Thu, Nov 1, 2012 at 4:43 PM, Ariel Calzada ariel.calz...@gmail.com wrote:
 Image:  http://build.laptop.org/13.1.0/os8/xo-1.75/
 Jukebox Activity Version: 28

I've just test using these versions and I had no problem. The audio is
not so good, but that is a known issue on 1.75.

I downloaded the file from wikipedia with wget and moved it to
~/Documents folder.

What is the error that you are getting?

--
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH sugar-toolkit-gtk3] Sugar scroll bar clicks should invoke page up/page down SL #3859

2012-11-02 Thread Manuel Kaufmann
The default value of 'gtk-primary-button-warps-slider' in Gtk3 is
True[1] and in gtk2 is False[2]. So, this patch sets that property to False
to keep the same behaviour we have before.

[1] 
http://developer.gnome.org/gtk3/stable/GtkSettings.html#GtkSettings--gtk-primary-button-warps-slider
[2] 
http://developer.gnome.org/gtk/2.24/GtkSettings.html#GtkSettings--gtk-primary-button-warps-slider

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 src/sugar3/activity/activity.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/sugar3/activity/activity.py b/src/sugar3/activity/activity.py
index 3325f47..d799aee 100644
--- a/src/sugar3/activity/activity.py
+++ b/src/sugar3/activity/activity.py
@@ -271,6 +271,7 @@ class Activity(Window, Gtk.Container):
 settings.set_property('gtk-icon-theme-name', 'sugar')
 settings.set_property('gtk-font-name',
   '%s %f' % (style.FONT_FACE, style.FONT_SIZE))
+settings.set_property('gtk-primary-button-warps-slider', False)
 
 Window.__init__(self)
 
-- 
1.7.11.7

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH sugar] Invoke page up/page down on scrollbars clicks

2012-11-02 Thread Manuel Kaufmann
The default value of 'gtk-primary-button-warps-slider' in Gtk3 is
True[1] and in gtk2 is False[2]. So, this patch sets that property to False
to keep the same behaviour we had before.

[1] 
http://developer.gnome.org/gtk3/stable/GtkSettings.html#GtkSettings--gtk-primary-button-warps-slider
[2] 
http://developer.gnome.org/gtk/2.24/GtkSettings.html#GtkSettings--gtk-primary-button-warps-slider

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 bin/sugar-session | 4 
 1 file changed, 4 insertions(+)

diff --git a/bin/sugar-session b/bin/sugar-session
index 23f88a1..5911052 100755
--- a/bin/sugar-session
+++ b/bin/sugar-session
@@ -253,6 +253,9 @@ def set_theme():
 settings.set_property('gtk-theme-name', sugar_theme)
 settings.set_property('gtk-icon-theme-name', 'sugar')
 
+def set_warps_slider():
+settings = Gtk.Settings.get_default()
+settings.set_property('gtk-primary-button-warps-slider', False)
 
 def main():
 try:
@@ -291,6 +294,7 @@ def main():
 
 set_fonts()
 set_theme()
+set_warps_slider()
 
 # this must be added early, so that it executes and unfreezes the screen
 # even when we initially get blocked on the intro screen
-- 
1.7.11.7

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH sugar] Invoke page up/page down on scrollbars clicks

2012-11-02 Thread Manuel Kaufmann
On Fri, Nov 2, 2012 at 8:16 PM, Manuel Kaufmann humi...@gmail.com wrote:
 The default value of 'gtk-primary-button-warps-slider' in Gtk3 is
 True[1] and in gtk2 is False[2]. So, this patch sets that property to False
 to keep the same behaviour we had before.

This patch works properly but, please, reconsider changing the way
it's implemented. I didn't know where to put that settings, so I
created a new function that is called immediately after set_theme().
Feel free to move that to the correct place considering the Sugar
Philosophy :D

--
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Reload fixed

2012-10-30 Thread Manuel Kaufmann
Hello,

I'm sending the patch attached because after an update git send-mail
is not more available (now, there is a subcommand called send-bugzilla
:( )

Cheers,

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/


0001-Reload-fixed.patch
Description: Binary data
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Don't show error page when plugin will handle

2012-10-30 Thread Manuel Kaufmann
Hello,

I found this bug while I was testing SL #3934 [1]. The patch that
fixes this is attached.

Cheers,

[1] http://bugs.sugarlabs.org/ticket/3934

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/


0001-Don-t-show-error-page-when-plugin-will-handle.patch
Description: Binary data
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Speak] Use radians instead of degrees

2012-10-29 Thread Manuel Kaufmann
Cairo.Context.arc needs the angle in radians instead of degrees. Give
it as 360 (radians) was taking up to 8 seconds to draw the eyes.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 eye.py | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/eye.py b/eye.py
index 954e68a..e1bf5b8 100644
--- a/eye.py
+++ b/eye.py
@@ -125,18 +125,20 @@ class Eye(gtk.DrawingArea):
 self.context.fill()
 
 # eye ball
-self.context.arc(bounds.width / 2, bounds.height / 2, eyeSize / 2 - 
outlineWidth / 2, 0, 360)
+self.context.arc(bounds.width / 2, bounds.height / 2,
+ eyeSize / 2 - outlineWidth / 2, 0, 2 * math.pi)
 self.context.set_source_rgb(1, 1, 1)
 self.context.fill()
 
 # outline
 self.context.set_line_width(outlineWidth)
-self.context.arc(bounds.width / 2, bounds.height / 2, eyeSize / 2 - 
outlineWidth / 2, 0, 360)
+self.context.arc(bounds.width / 2, bounds.height / 2,
+ eyeSize / 2 - outlineWidth / 2, 0, 2 * math.pi)
 self.context.set_source_rgb(0, 0, 0)
 self.context.stroke()
 
 # pupil
-self.context.arc(pupilX, pupilY, pupilSize, 0, 360)
+self.context.arc(pupilX, pupilY, pupilSize, 0, 2 * math.pi)
 self.context.set_source_rgb(0, 0, 0)
 self.context.fill()
 
-- 
1.7.11.7

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] espeak in gst 0.10 on 13.1.0

2012-10-24 Thread Manuel Kaufmann
Hello,

I took a look at this issue[1] and I found that it's not possible to
get the espeak gstreamer element on 13.1.0 os7 using gst 0.10 but
it's available using Gst 1.0 (from gi.repository import Gst). However,
there is no package called something like gstreamer1-plugins-espeak
installed but there is one called gstreamer-plugins-espeak[2]

So, I'm a little confused:

 * Is espeak available on 13.1.0 for gst 0.10?

 * Is gstreamer-plugins-espeak for gst 0.10 and the version for Gst
1.0 is inside on one of these? (already installed in the build os7):
 * gstreamer1-1.0.1-1.fc18.i686
 * gstreamer1-plugins-base-1.0.1-1.fc18.i686
 * gstreamer1-plugins-good-1.0.1-1.fc18.i686

Anyway, I think this activity should work without espeak gstreamer
element because it has a workaround to use the /usr/bin/espeak
command, save the text into a wav file and finally play it. But for
some reason (that I couldn't find yet) the same version (Speak v42)
works properly on 12.1.0 but it doesn't work on 13.1.0.

[1] http://bugs.sugarlabs.org/ticket/3901
[2] http://build.laptop.org/13.1.0/os7/xo-1.5/31007o1.packages.txt

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] espeak in gst 0.10 on 13.1.0

2012-10-24 Thread Manuel Kaufmann
On Wed, Oct 24, 2012 at 3:28 PM, Peter Robinson pbrobin...@gmail.com wrote:
 the version in 13.1.0 is for gst1 and built against it.

so, there is no way to have both of them, right? I mean, espeak for
0.10 and for 1.0.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] espeak in gst 0.10 on 13.1.0

2012-10-24 Thread Manuel Kaufmann
On Wed, Oct 24, 2012 at 3:46 PM, Peter Robinson pbrobin...@gmail.com wrote:
 Possibly, it was my understanding that we were moving to gst1 for the
 activities that use it.

Yes, we are moving on that way. Actually, Speak is already ported to
Gtk3 and Gst 1.0 but it doesn't work on 13.1.0 (same issue: CPU 100%).
So, I'm starting to think that the problem has nothing to do with
gstreamer.

I asked that because I wanted to test Speak v42 in 13.1.0 with the
correct gst 0.10 plugin.

Thanks, I'll keep researching about this.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] espeak in gst 0.10 on 13.1.0

2012-10-24 Thread Manuel Kaufmann
On Wed, Oct 24, 2012 at 4:01 PM, Peter Robinson pbrobin...@gmail.com wrote:
 use rpm to remove the currently installed one and then grab the old
 one from koji and install it manually.

Great! Thanks

I used (on XO-1.5 13.1.0 os7):

sudo rpm -e --nodeps gstreamer-plugins-espeak
wget 
http://kojipkgs.fedoraproject.org//packages/gstreamer-plugins-espeak/0.3.5/3.fc18/i686/gstreamer-plugins-espeak-0.3.5-3.fc18.i686.rpm
sudo rpm -i gstreamer-plugins-espeak-0.3.5-3.fc18.i686.rpm

After doing that I'm able to create espeak plugin for gst 0.10

 import gst
 gst.element_factory_make('espeak', 'espeak')
__main__.GstEspeak object ... 

I tested Speak-42 and I have the same problem with the CPU
consumption. So, I will change my way of the researching because it
seems that it has nothing to do with gstreamer versions.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH ImageViewer] Rotate, Zoom and center the image

2012-10-23 Thread Manuel Kaufmann
Improves the rotation by centering the image on the screen when it is
smaller than the screen size.

Optimal zoom is calculated for images than are higher in hight when
they are rotated as well.

Fixed rotation (anti)clockwise. X, Y axis + angles in gradians are
handled different by cairo.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 ImageView.py   | 113 ++---
 ImageViewerActivity.py |   4 +-
 2 files changed, 82 insertions(+), 35 deletions(-)

diff --git a/ImageView.py b/ImageView.py
index 30b19ac..cbc5516 100644
--- a/ImageView.py
+++ b/ImageView.py
@@ -27,6 +27,7 @@ import logging
 import cairo
 import random
 import time
+import math
 
 ZOOM_IN_OUT = 0.1
 
@@ -71,6 +72,7 @@ class ImageViewer(Gtk.DrawingArea):
 self._fast = True
 self._redraw_id = None
 self._is_touching = False
+self._switched = False
 
 def do_get_property(self, pspec):
 if pspec.name == 'zoom':
@@ -123,35 +125,64 @@ class ImageViewer(Gtk.DrawingArea):
 h = int(self.surface.get_height() * self.zoom)
 logging.error('W: %s, H: %s', w, h)
 
-ctx.save()
 if self._fast:
 ctx.set_antialias(cairo.ANTIALIAS_NONE)
-if self.angle != 0:
-logging.error('Rotating: %s', self.angle)
-ctx.translate(0.5 * w, 0.5 * h)
-ctx.rotate(self.angle)
-ctx.translate(-0.5 * w, -0.5 * h)
 
 scrolled_window = self.get_parent()
 rect = scrolled_window.get_allocation()
 x = y = 0
-if rect.width = w:
-x = int((rect.width - w) / 2)
-elif self._is_touching:
-hadj = int((w - rect.width) / 2)
-hadjustment = scrolled_window.get_hadjustment()
-hadjustment.set_value(hadj)
-
-if rect.height = h:
-y = int((rect.height - h) / 2)
-elif self._is_touching:
-vadj = int((h - rect.height) / 2)
-vadjustment = scrolled_window.get_vadjustment()
-vadjustment.set_value(vadj)
+if self.angle != 0:
+logging.error('Rotating: %s', self.angle)
+ctx.rotate(self.angle)
+
+if self.angle == math.pi:
+ctx.translate(-w, -h)
+
+if rect.width  w:
+x = -(rect.width - w) / 2
+if rect.height  h:
+y = -(rect.height - h) / 2
+
+elif self.angle == math.pi / 2:
+ctx.translate(0, -h)
+
+# center the image
+if rect.height  w:
+x = (rect.height - w) / 2
+if rect.width  h:
+y = -(rect.width - h) / 2
+
+elif self.angle == math.pi * 3 / 2:
+ctx.translate(-w, 0)
+
+if rect.height  w:
+x = -(rect.height - w) / 2
+if rect.width  h:
+y = (rect.width - h) / 2
+
+else:
+if rect.width  w:
+x = int((rect.width - w) / 2)
+if rect.height  h:
+y = int((rect.height - h) / 2)
+ctx.translate(x, y)
+
+if self._is_touching:
+if self._switched:
+w, h = h, w
+
+if rect.height  h:
+vadj = int((h - rect.height) / 2)
+vadjustment = scrolled_window.get_vadjustment()
+vadjustment.set_value(vadj)
+
+if rect.width  w:
+hadj = int((w - rect.width) / 2)
+hadjustment = scrolled_window.get_hadjustment()
+hadjustment.set_value(hadj)
 
 if self.zoom != 1:
 logging.error('Scaling: %s', self.zoom)
-ctx.translate(x, y)
 ctx.scale(self.zoom, self.zoom)
 
 ctx.set_source_surface(self.surface, 0, 0)
@@ -171,9 +202,23 @@ class ImageViewer(Gtk.DrawingArea):
 def _redraw_high_quality(self):
 self._fast = False
 self._redraw_id = None
-self.queue_draw()
+self._redraw()
 return False
 
+def _redraw(self):
+# README: this is a hack to not raise the 'draw' event (again)
+# when we request more space to show the scroll bars
+w = int(self.surface.get_width() * self.zoom)
+h = int(self.surface.get_height() * self.zoom)
+
+self._switched = False
+if (self.angle / (math.pi / 2)) % 2 == 1:
+# change image dimensions if it's rotated
+w, h = h, w
+self._switched = True
+
+self.set_size_request(w, h)
+
 def set_zoom(self, zoom):
 self._optimal_zoom_flag = False
 self._set_zoom(zoom)
@@ -191,8 +236,8 @@ class ImageViewer(Gtk.DrawingArea):
 def set_angle(self, angle):
 self._optimal_zoom_flag = True
 
-self.angle = angle
-self.queue_draw()
+self.angle = angle % (2 * math.pi)
+self._redraw

Re: [Sugar-devel] [VERY FRUSTRATING] sugar-build requires reboot of the laptop

2012-10-11 Thread Manuel Kaufmann
On Thu, Oct 11, 2012 at 10:46 AM, Ajay Garg a...@activitycentral.com wrote:
 a)
 Is there a way to NOT run sugar-build in fullscreen? If yes, then we could
 simply kill the process by clicking on x icon in the process window of
 sugar-build.

A quick reply. Take a look at this link. That is what I'm using to run
Sugar in a VNC window:

http://wiki.sugarlabs.org/go/User:Humitos/SugarBuild#Fedora_17_64_bits

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH v3 Browse] Remove temporary downloaded (cancelled) files SL #3973

2012-10-09 Thread Manuel Kaufmann
When a download is cancelled for any reason WebKit leaves a temporary
file called .goutputstream-* in the instance directory. This is
because of a bug in GLib:

 * https://bugzilla.gnome.org/show_bug.cgi?id=629301

This patch is a workaround to that behaviour. Every time that Browse
is started it looks for all the .goutputstream files in the
instance directory and checks its mtime. If it greater than 1 day or
it was created before we booted, Browse removes the old temporary
file.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 webactivity.py | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/webactivity.py b/webactivity.py
index dff3a4a..b784476 100644
--- a/webactivity.py
+++ b/webactivity.py
@@ -241,6 +241,44 @@ class WebActivity(activity.Activity):
 else:
 _logger.debug('Created activity')
 
+# README: this is a workaround to remove old temp file
+# http://bugs.sugarlabs.org/ticket/3973
+self._cleanup_temp_files()
+
+def _cleanup_temp_files(self):
+Removes temporary files generated by Download Manager that
+were cancelled by the user or failed for any reason.
+
+There is a bug in GLib that makes this to happen:
+https://bugzilla.gnome.org/show_bug.cgi?id=629301
+
+
+try:
+uptime_proc = open('/proc/uptime', 'r').read()
+uptime = int(float(uptime_proc.split()[0]))
+except EnvironmentError:
+logging.warning('/proc/uptime could not be read')
+uptime = None
+
+temp_path = os.path.join(self.get_activity_root(), 'instance')
+now = int(time.time())
+cutoff = now - 24 * 60 * 60  # yesterday
+if uptime is not None:
+boot_time = now - uptime
+cutoff = max(cutoff, boot_time)
+
+for f in os.listdir(temp_path):
+if f.startswith('.goutputstream-'):
+fpath = os.path.join(temp_path, f)
+mtime = int(os.path.getmtime(fpath))
+if mtime  cutoff:
+logging.warning('Removing old temporary file: %s', fpath)
+try:
+os.remove(fpath)
+except EnvironmentError:
+logging.error('Temporary file could not be '
+  'removed: %s', fpath)
+
 def _on_focus_url_entry(self, gobject):
 self._primary_toolbar.entry.grab_focus()
 
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] Turtle Confusion en Español

2012-10-08 Thread Manuel Kaufmann
On Mon, Oct 8, 2012 at 3:51 AM, Barry Newell barry.new...@anu.edu.au wrote:
 Congratulations to All!

Thanks! I'm very happy that you liked our work. It's mutual, we like yours :)

 The effort that you and your colleagues have put into this project, and the
 high quality of the end result, have prompted me to go ahead and produce the
 guide to the riddles.

That's an excellent news for me!

 I will not be able to do it quickly, but I will keep you updated on my
 progress. I will, unfortunately, have to write it in English.

Well, maybe we can help on the translation of it as well if you give
us permission. I think Melina would like to help on this translation.

 It will help us to make sure that the riddles still work after translation
 into Spanish.

I'm not pretty sure of this because we don't solve all the riddles yet
but it's something that we have in mind and we will do in the near
future. But... Maybe we never get the answers, haha ;)

Cheers,

PD: we are about to start the translation of Turtles Speak
Mathematics on the next week, I guess.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH] Sort the activities in the home in alphabetic order

2012-10-05 Thread Manuel Kaufmann
On Fri, Oct 5, 2012 at 12:41 AM, Gonzalo Odiard godi...@sugarlabs.org wrote:
 The best we can do is provide a coherent order.
 Alphabetical using the localized numbers and the same order than in the list
 view,
 is the best in my opinion.

I was about to suggest that maybe we can sort the activities using the
launch-time proposed by Walter on another email -and already
applied-. This will make easy to find the most used activities by the
kid. I think it's practical but does not freeze the Home View
between XOs at all.

My 5¢

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Jukebox 1/8] Use a notebook in the visualization area

2012-10-04 Thread Manuel Kaufmann
Previously an empty widget and a videowidget were packed and removed
from a container, but there are problems with the video widget not
ready when the player want start at times.

Signed-off-by: Gonzalo Odiard gonz...@laptop.org
Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 jukeboxactivity.py | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/jukeboxactivity.py b/jukeboxactivity.py
index aebbc98..5132c68 100644
--- a/jukeboxactivity.py
+++ b/jukeboxactivity.py
@@ -150,8 +150,8 @@ class JukeboxActivity(activity.Activity):
 self._empty_widget = Gtk.Label(label=)
 self._empty_widget.show()
 self.videowidget = VideoWidget()
-self._switch_canvas(show_video=False)
 self.set_canvas(self.canvas)
+self._init_view_area()
 self.show_all()
 self.canvas.connect('size-allocate', self.__size_allocate_cb)
 
@@ -165,6 +165,18 @@ class JukeboxActivity(activity.Activity):
 self.uri = handle.uri
 GObject.idle_add(self._start, self.uri, handle.title)
 
+def _init_view_area(self):
+
+Use a notebook with two pages, one empty an another
+with the videowidget
+
+self.view_area = Gtk.Notebook()
+self.view_area.set_show_tabs(False)
+self.view_area.append_page(self._empty_widget, None)
+self.view_area.append_page(self.videowidget, None)
+self.canvas.pack_end(self.view_area, expand=True,
+ fill=True, padding=0)
+
 def _switch_canvas(self, show_video):
 Show or hide the video visualization in the canvas.
 
@@ -173,11 +185,9 @@ class JukeboxActivity(activity.Activity):
 
 
 if show_video:
-self.canvas.remove(self._empty_widget)
-self.canvas.pack_end(self.videowidget, True, True, 0)
+self.view_area.set_current_page(1)
 else:
-self.canvas.pack_end(self._empty_widget, True, True, 0)
-self.canvas.remove(self.videowidget)
+self.view_area.set_current_page(0)
 self.canvas.queue_draw()
 
 def __get_tags_cb(self, tags_reader, order, tags):
@@ -288,10 +298,7 @@ class JukeboxActivity(activity.Activity):
 self.player.stop()
 self.player.set_uri(None)
 self.control.set_disabled()
-self.canvas.remove(self.videowidget)
-text = Gtk.Label(Error: %s - %s % (message, detail))
-text.show_all()
-self.canvas.add(text)
+self._show_error_alert(Error: %s - %s % (message, detail))
 
 def _player_new_tag_cb(self, widget, tag, value):
 if not tag in [gst.TAG_TITLE, gst.TAG_ARTIST, gst.TAG_ALBUM]:
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Jukebox 2/8] Remove capsfilter filter because of performance

2012-10-04 Thread Manuel Kaufmann
Without this filter the performance to reproduce videos is great and
in audio files the visualization performance is improved as well. The
only consequense is the text (artist, track, etc) is rendered without
antialiasing.

Signed-off-by: Gonzalo Odiard gonz...@laptop.org
Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 jukeboxactivity.py | 19 +--
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/jukeboxactivity.py b/jukeboxactivity.py
index 5132c68..45bb333 100644
--- a/jukeboxactivity.py
+++ b/jukeboxactivity.py
@@ -754,22 +754,6 @@ class GstPlayer(GObject.GObject):
 self.bin.add_pad(ghostpad)
 videoscale.set_property(method, 0)
 
-caps_string = video/x-raw-yuv, 
-r = self.videowidget.get_allocation()
-if r.width  500 and r.height  500:
-# Sigh... xvimagesink on the XOs will scale the video to fit
-# but ximagesink in Xephyr does not.  So we live with unscaled
-# video in Xephyr so that the XO can work right.
-w = 480
-h = float(w) / float(float(r.width) / float(r.height))
-caps_string += width=%d, height=%d % (w, h)
-else:
-caps_string += width=480, height=360
-caps = gst.Caps(caps_string)
-self.filter = gst.element_factory_make(capsfilter, filter)
-self.bin.add(self.filter)
-self.filter.set_property(caps, caps)
-
 textoverlay = gst.element_factory_make('textoverlay')
 self.overlay = textoverlay
 self.bin.add(textoverlay)
@@ -777,8 +761,7 @@ class GstPlayer(GObject.GObject):
 self.bin.add(conv)
 videosink = gst.element_factory_make('autovideosink')
 self.bin.add(videosink)
-gst.element_link_many(videoscale, self.filter, textoverlay, conv,
-videosink)
+gst.element_link_many(videoscale, textoverlay, conv, videosink)
 self.player.set_property(video-sink, self.bin)
 
 def set_overlay(self, title, artist, album):
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Jukebox 5/8] Use 'playbin2' instead of 'playbin'

2012-10-04 Thread Manuel Kaufmann
'playbin' is obsolete and not should be used. I was told in #gstreamer
(irc.freenode.net) that 'playbin' is no longer supported, that has
some bugs and shouldn't be used anymore. It should be changed by
'playbin2'

I had to set some flags as well to keep showing the 'vis-plugin' with
'playbin2' player.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 jukeboxactivity.py | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/jukeboxactivity.py b/jukeboxactivity.py
index 11e1331..5c02d23 100644
--- a/jukeboxactivity.py
+++ b/jukeboxactivity.py
@@ -698,7 +698,13 @@ class GstPlayer(GObject.GObject):
 self.playing = False
 self.error = False
 
-self.player = gst.element_factory_make(playbin, player)
+self.player = gst.element_factory_make(playbin2, player)
+
+# Set the proper flags to render the vis-plugin
+GST_PLAY_FLAG_VIS = 1  3
+GST_PLAY_FLAG_TEXT = 1  2
+self.player.props.flags |= GST_PLAY_FLAG_VIS
+self.player.props.flags |= GST_PLAY_FLAG_TEXT
 
 r = gst.registry_get_default()
 l = [x for x in r.get_feature_list(gst.ElementFactory)
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Jukebox 3/8] Stop the player when the user is reproducing a video and switch to another activity.

2012-10-04 Thread Manuel Kaufmann

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 jukeboxactivity.py | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/jukeboxactivity.py b/jukeboxactivity.py
index 45bb333..97c2de4 100644
--- a/jukeboxactivity.py
+++ b/jukeboxactivity.py
@@ -101,6 +101,11 @@ class JukeboxActivity(activity.Activity):
 
 self.connect(key_press_event, self._key_press_event_cb)
 
+# We want to be notified when the activity gets the focus or
+# loses it.  When it is not active, we don't need to keep
+# reproducing the video
+self.connect(notify::active, self._notify_active_cb)
+
 # FIXME: this is related with shared activity and it doesn't work
 # if handle.uri:
 # pass
@@ -126,7 +131,6 @@ class JukeboxActivity(activity.Activity):
 self.playflag = False
 self.tags = {}
 self.only_audio = False
-self.got_stream_info = False
 
 self.tag_reader = TagReader()
 self.tag_reader.connect('get-tags', self.__get_tags_cb)
@@ -165,6 +169,17 @@ class JukeboxActivity(activity.Activity):
 self.uri = handle.uri
 GObject.idle_add(self._start, self.uri, handle.title)
 
+def _notify_active_cb(self, widget, event):
+Sugar notify us that the activity is becoming active or inactive.
+When we are inactive, we stop the player if it is reproducing
+a video.
+
+if self.player is not None and not self.only_audio:
+if not self.player.is_playing() and self.props.active:
+self.player.play()
+if self.player.is_playing() and not self.props.active:
+self.player.pause()
+
 def _init_view_area(self):
 
 Use a notebook with two pages, one empty an another
@@ -319,7 +334,7 @@ class JukeboxActivity(activity.Activity):
 self.tags[gst.TAG_ARTIST], album)
 
 def _player_stream_info_cb(self, widget, stream_info):
-if not len(stream_info) or self.got_stream_info:
+if not len(stream_info):
 return
 
 GST_STREAM_TYPE_UNKNOWN = 0
@@ -332,7 +347,6 @@ class JukeboxActivity(activity.Activity):
 if item.props.type == GST_STREAM_TYPE_VIDEO:
 only_audio = False
 self.only_audio = only_audio
-self.got_stream_info = True
 self._update_overlay()
 
 def _joined_cb(self, activity):
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Jukebox 4/8] Create GstPlayer just once

2012-10-04 Thread Manuel Kaufmann
Instanciating GstPlayer when Jukebox is launched and changing its uri
when a new stream is played. This allow us to change between different
streams in the playlist without having many memory issues regarding
video playing in HD.

To change the stream being played in the GstPlayer instance we firstly
set the state of it to STATE_PAUSED, then to STATE_NULL and finally we
change the uri. When this process finishes we change the state again
to STATE_PLAYING.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 jukeboxactivity.py | 31 +--
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/jukeboxactivity.py b/jukeboxactivity.py
index 97c2de4..11e1331 100644
--- a/jukeboxactivity.py
+++ b/jukeboxactivity.py
@@ -169,12 +169,20 @@ class JukeboxActivity(activity.Activity):
 self.uri = handle.uri
 GObject.idle_add(self._start, self.uri, handle.title)
 
+# Create the player just once
+logging.debug('Instantiating GstPlayer')
+self.player = GstPlayer(self.videowidget)
+self.player.connect(eos, self._player_eos_cb)
+self.player.connect(error, self._player_error_cb)
+self.player.connect(tag, self._player_new_tag_cb)
+self.player.connect(stream-info, self._player_stream_info_cb)
+
 def _notify_active_cb(self, widget, event):
 Sugar notify us that the activity is becoming active or inactive.
 When we are inactive, we stop the player if it is reproducing
 a video.
 
-if self.player is not None and not self.only_audio:
+if self.player.player.props.uri is not None and not self.only_audio:
 if not self.player.is_playing() and self.props.active:
 self.player.play()
 if self.player.is_playing() and not self.props.active:
@@ -269,12 +277,6 @@ class JukeboxActivity(activity.Activity):
 def play(self, media_index):
 self._switch_canvas(show_video=True)
 self.currentplaying = media_index
-self.player.stop()
-self.player = GstPlayer(self.videowidget)
-self.player.connect(eos, self._player_eos_cb)
-self.player.connect(error, self._player_error_cb)
-self.player.connect(tag, self._player_new_tag_cb)
-self.player.connect(stream-info, self._player_stream_info_cb)
 url = self.playlist[self.currentplaying]['url']
 error = None
 if url.startswith('journal://'):
@@ -289,7 +291,7 @@ class JukeboxActivity(activity.Activity):
 
 if error is None:
 self.player.set_uri(url)
-self.play_toggled()
+self.player.play()
 else:
 self.control.set_disabled()
 self._show_error_alert(error)
@@ -517,16 +519,6 @@ class JukeboxActivity(activity.Activity):
 if not error:
 self.tag_reader.set_file(url, len(self.playlist) - 1)
 
-if not self.player:
-# lazy init the player so that videowidget is realized
-# and has a valid widget allocation
-self._switch_canvas(show_video=True)
-self.player = GstPlayer(self.videowidget)
-self.player.connect(eos, self._player_eos_cb)
-self.player.connect(error, self._player_error_cb)
-self.player.connect(tag, self._player_new_tag_cb)
-self.player.connect(stream-info, self._player_stream_info_cb)
-
 self.playlist_widget.update(self.playlist)
 
 try:
@@ -538,6 +530,7 @@ class JukeboxActivity(activity.Activity):
 url = 'file://' + jobject.file_path
 
 self.player.set_uri(url)
+self.player.play()
 self.currentplaying = 0
 self.play_toggled()
 self.show_all()
@@ -728,6 +721,8 @@ class GstPlayer(GObject.GObject):
 bus.connect('message', self.on_message)
 
 def set_uri(self, uri):
+self.player.set_state(gst.STATE_PAUSED)
+self.player.set_state(gst.STATE_NULL)
 self.player.set_property('uri', uri)
 
 def on_sync_message(self, bus, message):
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Jukebox 7/8] Do not pause the stream after adding a new one

2012-10-04 Thread Manuel Kaufmann
After the user adds the first stream to the playlist it is played
immediately and when a new stream is added, the first one is kept
playing.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 jukeboxactivity.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jukeboxactivity.py b/jukeboxactivity.py
index ea66d34..1ad5ff1 100644
--- a/jukeboxactivity.py
+++ b/jukeboxactivity.py
@@ -459,7 +459,7 @@ class JukeboxActivity(activity.Activity):
 self.playlist_widget.update(self.playlist)
 
 try:
-if not self.currentplaying:
+if self.currentplaying is None:
 logging.info(Playing:  + self.playlist[0]['url'])
 url = self.playlist[0]['url']
 if url.startswith('journal://'):
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Jukebox 6/8] Tag reader feature removed

2012-10-04 Thread Manuel Kaufmann
I removed it because of performance. Jukebox was working too slow when
it was reproducing a video and it had to read the tag of the media
added to the playlist. So, we decided to remove this feature by the
moment.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 jukeboxactivity.py | 119 +
 1 file changed, 1 insertion(+), 118 deletions(-)

diff --git a/jukeboxactivity.py b/jukeboxactivity.py
index 5c02d23..ea66d34 100644
--- a/jukeboxactivity.py
+++ b/jukeboxactivity.py
@@ -129,11 +129,6 @@ class JukeboxActivity(activity.Activity):
 self.playpath = None
 self.currentplaying = None
 self.playflag = False
-self.tags = {}
-self.only_audio = False
-
-self.tag_reader = TagReader()
-self.tag_reader.connect('get-tags', self.__get_tags_cb)
 
 self.p_position = gst.CLOCK_TIME_NONE
 self.p_duration = gst.CLOCK_TIME_NONE
@@ -174,15 +169,13 @@ class JukeboxActivity(activity.Activity):
 self.player = GstPlayer(self.videowidget)
 self.player.connect(eos, self._player_eos_cb)
 self.player.connect(error, self._player_error_cb)
-self.player.connect(tag, self._player_new_tag_cb)
-self.player.connect(stream-info, self._player_stream_info_cb)
 
 def _notify_active_cb(self, widget, event):
 Sugar notify us that the activity is becoming active or inactive.
 When we are inactive, we stop the player if it is reproducing
 a video.
 
-if self.player.player.props.uri is not None and not self.only_audio:
+if self.player.player.props.uri is not None:
 if not self.player.is_playing() and self.props.active:
 self.player.play()
 if self.player.is_playing() and not self.props.active:
@@ -213,10 +206,6 @@ class JukeboxActivity(activity.Activity):
 self.view_area.set_current_page(0)
 self.canvas.queue_draw()
 
-def __get_tags_cb(self, tags_reader, order, tags):
-self.playlist[order]['title'] = tags['title']
-self.playlist_widget.update(self.playlist)
-
 def __size_allocate_cb(self, widget, allocation):
 canvas_size = self.canvas.get_allocation()
 playlist_width = int(canvas_size.width * PLAYLIST_WIDTH_PROP)
@@ -317,40 +306,6 @@ class JukeboxActivity(activity.Activity):
 self.control.set_disabled()
 self._show_error_alert(Error: %s - %s % (message, detail))
 
-def _player_new_tag_cb(self, widget, tag, value):
-if not tag in [gst.TAG_TITLE, gst.TAG_ARTIST, gst.TAG_ALBUM]:
-return
-self.tags[tag] = value
-self._update_overlay()
-
-def _update_overlay(self):
-if self.only_audio == False:
-return
-if not gst.TAG_TITLE in self.tags or \
-not gst.TAG_ARTIST in self.tags:
-return
-album = None
-if gst.TAG_ALBUM in self.tags:
-album = self.tags[gst.TAG_ALBUM]
-self.player.set_overlay(self.tags[gst.TAG_TITLE],
-self.tags[gst.TAG_ARTIST], album)
-
-def _player_stream_info_cb(self, widget, stream_info):
-if not len(stream_info):
-return
-
-GST_STREAM_TYPE_UNKNOWN = 0
-GST_STREAM_TYPE_AUDIO = 1
-GST_STREAM_TYPE_VIDEO = 2
-GST_STREAM_TYPE_TEXT = 3
-
-only_audio = True
-for item in stream_info:
-if item.props.type == GST_STREAM_TYPE_VIDEO:
-only_audio = False
-self.only_audio = only_audio
-self._update_overlay()
-
 def _joined_cb(self, activity):
 logging.debug(someone joined)
 pass
@@ -500,24 +455,6 @@ class JukeboxActivity(activity.Activity):
 else:
 uri = file:// + urllib.quote(os.path.abspath(uri))
 self.playlist.append({'url': uri, 'title': title})
-if uri.endswith(title) or title is None or title == '' or \
-object_id is not None:
-error = False
-logging.error('Try get a better title reading tags')
-# TODO: unify this code
-url = self.playlist[len(self.playlist) - 1]['url']
-if url.find('home')  0:
-url = url[len(journal://):]
-url = 'file://' + url
-elif url.startswith('journal://'):
-try:
-jobject = datastore.get(url[len(journal://):])
-url = 'file://' + jobject.file_path
-except:
-error = True
-# jobject.destroy() ??
-if not error:
-self.tag_reader.set_file(url, len(self.playlist) - 1)
 
 self.playlist_widget.update(self.playlist)
 
@@ -642,54 +579,11 @@ class JukeboxActivity(activity.Activity):
 self.canvas.queue_draw()
 
 
-class TagReader(GObject.GObject):
-
-__gsignals__ = {
-'get-tags

[Sugar-devel] [PATCH Jukebox 8/8] Port gst 0.10 to Gst 1.0

2012-10-04 Thread Manuel Kaufmann
Useful guide:

 * https://wiki.ubuntu.com/Novacut/GStreamer1.0

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 jukeboxactivity.py | 180 ++---
 1 file changed, 90 insertions(+), 90 deletions(-)

diff --git a/jukeboxactivity.py b/jukeboxactivity.py
index 1ad5ff1..48a5aa8 100644
--- a/jukeboxactivity.py
+++ b/jukeboxactivity.py
@@ -40,15 +40,23 @@ from sugar3.graphics.alert import ErrorAlert
 
 import gi
 gi.require_version('Gtk', '3.0')
+gi.require_version('Gst', '1.0')
 
 from gi.repository import GObject
 from gi.repository import Gdk
-
-import pygst
-pygst.require('0.10')
-import gst
-import gst.interfaces
 from gi.repository import Gtk
+from gi.repository import Gst
+
+# Needed for window.get_xid(), xvimagesink.set_window_handle(),
+# respectively:
+from gi.repository import GdkX11, GstVideo
+
+# Avoid Fatal Python error: GC object already tracked
+# 
http://stackoverflow.com/questions/7496629/gstreamer-appsrc-causes-random-crashes
+GObject.threads_init()
+
+# Initialize GStreamer
+Gst.init(None)
 
 import urllib
 from ControlToolbar import Control, ViewToolbar
@@ -130,9 +138,6 @@ class JukeboxActivity(activity.Activity):
 self.currentplaying = None
 self.playflag = False
 
-self.p_position = gst.CLOCK_TIME_NONE
-self.p_duration = gst.CLOCK_TIME_NONE
-
 # README: I changed this because I was getting an error when I
 # tried to modify self.bin with something different than
 # Gtk.Bin
@@ -169,6 +174,8 @@ class JukeboxActivity(activity.Activity):
 self.player = GstPlayer(self.videowidget)
 self.player.connect(eos, self._player_eos_cb)
 self.player.connect(error, self._player_error_cb)
+self.p_position = Gst.CLOCK_TIME_NONE
+self.p_duration = Gst.CLOCK_TIME_NONE
 
 def _notify_active_cb(self, widget, event):
 Sugar notify us that the activity is becoming active or inactive.
@@ -524,7 +531,7 @@ class JukeboxActivity(activity.Activity):
 real = long(scale.get_value() * self.p_duration / 100)  # in ns
 self.player.seek(real)
 # allow for a preroll
-self.player.get_state(timeout=50 * gst.MSECOND)  # 50 ms
+self.player.get_state(timeout=50 * Gst.MSECOND)  # 50 ms
 
 def scale_button_release_cb(self, widget, event):
 # see seek.cstop_seek
@@ -546,8 +553,13 @@ class JukeboxActivity(activity.Activity):
 self.update_scale_cb)
 
 def update_scale_cb(self):
-self.p_position, self.p_duration = self.player.query_position()
-if self.p_position != gst.CLOCK_TIME_NONE:
+success, self.p_position, self.p_duration = \
+self.player.query_position()
+
+if not success:
+return True
+
+if self.p_position != Gst.CLOCK_TIME_NONE:
 value = self.p_position * 100.0 / self.p_duration
 self.control.adjustment.set_value(value)
 
@@ -558,7 +570,7 @@ class JukeboxActivity(activity.Activity):
 
 # FIXME: this should be updated just once when the file starts
 # the first time
-if self.p_duration != gst.CLOCK_TIME_NONE:
+if self.p_duration != Gst.CLOCK_TIME_NONE:
 seconds = self.p_duration * 10 ** -9
 time = '%2d:%02d' % (int(seconds / 60), int(seconds % 60))
 self.control.total_time_label.set_text(time)
@@ -592,7 +604,22 @@ class GstPlayer(GObject.GObject):
 self.playing = False
 self.error = False
 
-self.player = gst.element_factory_make(playbin2, player)
+# Create GStreamer pipeline
+self.pipeline = Gst.Pipeline()
+# Create bus to get events from GStreamer pipeline
+self.bus = self.pipeline.get_bus()
+self.bus.add_signal_watch()
+
+self.bus.connect('message::eos', self.__on_eos_message)
+self.bus.connect('message::error', self.__on_error_message)
+
+# This is needed to make the video output in our DrawingArea
+self.bus.enable_sync_message_emission()
+self.bus.connect('sync-message::element', self.__on_sync_message)
+
+# Create GStreamer elements
+self.player = Gst.ElementFactory.make('playbin', None)
+self.pipeline.add(self.player)
 
 # Set the proper flags to render the vis-plugin
 GST_PLAY_FLAG_VIS = 1  3
@@ -600,12 +627,12 @@ class GstPlayer(GObject.GObject):
 self.player.props.flags |= GST_PLAY_FLAG_VIS
 self.player.props.flags |= GST_PLAY_FLAG_TEXT
 
-r = gst.registry_get_default()
-l = [x for x in r.get_feature_list(gst.ElementFactory)
-if (gst.ElementFactory.get_klass(x) == Visualization)]
+r = Gst.Registry.get()
+l = [x for x in r.get_feature_list(Gst.ElementFactory)
+ if (x.get_metadata('klass') == Visualization)]
 if len(l):
 e = l.pop()  # take latest plugin in the list
-vis_plug

Re: [Sugar-devel] ImageViewer (gtk3) traceback

2012-10-04 Thread Manuel Kaufmann
On Thu, Oct 4, 2012 at 1:54 PM, Gary Martin garycmar...@googlemail.com wrote:
 /me wonders if he dare mention this to Gonzalo as a solution for the same 
 issue in Read

Maybe we can design a widget for this and include it in
sugar-toolkit-gtk3 so we will have more consistency between
activities. What do you think?

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] Jukebox patches

2012-10-04 Thread Manuel Kaufmann
Hello people,

I've just sent 8 patches to the sugar-devel mailing list for Jukebox.
Seven of them are those ones that were applied to the sugar-0.98
(gtk2) branch that I ported to the master branch. The last one is
the port of gstreamer from 0.10 to 1.0.

Yesterday I was working a lot on Jukebox itself, removing some old
code, rewriting some other functions and doing some bugfixing as well.
I'm preparing some patches that I will be sending later.

Thanks,

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] GStreamer 1.0.0 has been released

2012-10-03 Thread Manuel Kaufmann
On Wed, Oct 3, 2012 at 10:51 AM, Peter Robinson pbrobin...@gmail.com wrote:
 Ultimately I'm sure we'd like to drop 0.10 if at all possible just so
 we don't need to ship two copies and any of the deps that go with it.

I'm working on the port of Jukebox to Gst 1.0 and I have it quite
stable but I'm doing some of my tests on my F17 Desktop with
sugar-build because I'm not sure how to install Gst1.0 with ugly
plugins and video support(*) on XO 1.75 with 13.1.0.

(*) Martin and Jon told me that video support is not available yet for 13.1.0

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH v2 Browse] Remove temporary downloaded (cancelled) files SL #3973

2012-10-03 Thread Manuel Kaufmann
On Wed, Oct 3, 2012 at 12:08 PM, Martin Langhoff
martin.langh...@gmail.com wrote:
 Not at all. Ignoring the computer is not elegance.

OK. I will send a new version of this patch with all the things that
we were discussing.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] Gst1.0 plugins in sugar-build

2012-10-03 Thread Manuel Kaufmann
Hello,

I'd like to comment that there are many Gst 1.0 plugin decoders that
are not built because of missing dependencies. I had to install
libmad-devel.x86_64 (on my F17) to be able to play MP3 files from
Jukebox.

Daniel, can be this package added as a dependency for sugar-build?

Cheers,

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] Gst1.0 plugins in sugar-build

2012-10-03 Thread Manuel Kaufmann
On Wed, Oct 3, 2012 at 6:08 PM, Peter Robinson pbrobin...@gmail.com wrote:
 The advantage of gstreamer is you can add extra codecs easily by just
 installing packages and without recompiling anything and the
 functionality should just work without any changes in the application
 so I'm not sure why it's a needed requirement.

That's why I wasn't sure. This library is not a dependency but
gstreamer 1.0 is not as well and it's inside sugar-build. That's why I
was asking.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] touch_test.py resutls

2012-10-02 Thread Manuel Kaufmann
On Mon, Oct 1, 2012 at 11:59 PM, Agustin Zubiaga Sanchez
a...@sugarlabs.org wrote:
 Would be nice to have a touch example Activity.
 What do you think?

Yes. I started a HelloTouchGestures some time ago when SugarGestures
weren't developed yet and I used a known algorithm to match gestures.

Do you want to migrate this activity to the new way (using from
gi.repository import SugarGestures)? If you say yes, I can add you as
commiter.

This is the repo:

 * http://git.sugarlabs.org/hello-touch-gesture

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Remove temporary downloaded (cancelled) files SL #3973

2012-10-02 Thread Manuel Kaufmann
On Tue, Oct 2, 2012 at 6:40 AM, Martin Langhoff
martin.langh...@gmail.com wrote:
 Good, but not enough. Compare mtime also to our boot time (ie: now -
 uptime). If the file is from before we booted, needs to be nuked.

You say that I should add this test as well, right? I mean, compare if
the file is older than 1 day AND check the mtime with our boot time or
remove my test and use only this one?

I think that comparing just with the boot time is not enough as well.
Think about this scenario: turn on the XO, use Browse for a while,
download and cancel many files, close Brose and close the lid. It will
suspend. So, if you repeat these steps every day and you never power
off / restart the XO, these kind of files won't be removed. Am I
right?

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH v2 Browse] Remove temporary downloaded (cancelled) files SL #3973

2012-10-02 Thread Manuel Kaufmann
When a download is cancelled for any reason WebKit leaves a temporary
file called .goutputstream-* in the instance directory. This is
because of a bug in GLib:

 * https://bugzilla.gnome.org/show_bug.cgi?id=629301

This patch is a workaround to that behaviour. Every time that Browse
is started it looks for all the .goutputstream files in the
instance directory and checks its mtime. If it greater than 1 day or
it was created before we booted, Browse removes the old temporary
file.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 webactivity.py | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/webactivity.py b/webactivity.py
index dff3a4a..8c66ac5 100644
--- a/webactivity.py
+++ b/webactivity.py
@@ -37,6 +37,7 @@ from gi.repository import GConf
 import locale
 import cairo
 import StringIO
+import datetime
 from hashlib import sha1
 
 from sugar3.activity import activity
@@ -241,6 +242,43 @@ class WebActivity(activity.Activity):
 else:
 _logger.debug('Created activity')
 
+# README: this is a workaround to remove old temp file
+# http://bugs.sugarlabs.org/ticket/3973
+self._cleanup_temp_files()
+
+def _cleanup_temp_files(self):
+Removes temporary files generated by Download Manager that
+were cancelled by the user or failed for any reason.
+
+There is a bug in GLib that makes this to happen:
+https://bugzilla.gnome.org/show_bug.cgi?id=629301
+
+
+try:
+uptime_proc = open('/proc/uptime', 'r').read()
+uptime_seconds = float(uptime_proc.split()[0])
+uptime = datetime.timedelta(seconds=uptime_seconds)
+except:
+logging.warning('/proc/uptime could not be read')
+uptime = None
+
+temp_path = os.path.join(self.get_activity_root(), 'instance')
+now = datetime.datetime.now()
+for f in os.listdir(temp_path):
+if f.startswith('.goutputstream-'):
+fpath = os.path.join(temp_path, f)
+mtime = os.path.getmtime(fpath)
+mdate = datetime.datetime.fromtimestamp(mtime)
+delta = now - mdate
+if delta.days  0 or \
+(uptime is not None and (now - uptime)  mdate):
+logging.warning('Removing old temporary file: %s', fpath)
+try:
+os.remove(fpath)
+except OSError:
+logging.error('Temporary file could not be '
+  'removed: %s', fpath)
+
 def _on_focus_url_entry(self, gobject):
 self._primary_toolbar.entry.grab_focus()
 
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] touch_test.py resutls

2012-10-02 Thread Manuel Kaufmann
On Tue, Oct 2, 2012 at 10:32 AM, Agustin Zubiaga Sanchez
a...@sugarlabs.org wrote:
 Yes, I can help you but I don't have a touch XO, so I can't test it.
 However, I could program it hypothetically, if you want (and you can), to
 test my changes.

I can test your changes if you want but I think it's really boring to
develop in blind-mode :D

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH v2 Browse] Remove temporary downloaded (cancelled) files SL #3973

2012-10-02 Thread Manuel Kaufmann
On Tue, Oct 2, 2012 at 1:43 PM, Martin Langhoff
martin.langh...@gmail.com wrote:
 +except:
 +logging.warning('/proc/uptime could not be read')
 +uptime = None

Should I use EnvironmentError[1] here too?

 Tiny optimization and elegance improvement: just calculate your cutoff
 here. The cutoff is the largest of
  - yesterday (now - 1 day)
  - boottime  (now - uptime) -- if you managed to read uptime

What do you think about this?

cutoff = now - datetime.timedelta(days=1)
if uptime is not None:
boot_time = now - uptime
cutoff = max(yesterday, boot_time)

 Should catch both OSError _and_ IOError. Or perhaps EnvironmentError
 which, strange as the name might sound, is the granddaddy of both.

Yes, you are right

[1] http://docs.python.org/library/exceptions.html#exceptions.EnvironmentError

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH 4/7] metadatareader: ignore .hidden files

2012-10-01 Thread Manuel Kaufmann
On Fri, Sep 21, 2012 at 12:55 AM, Martin Langhoff mar...@laptop.org wrote:
 Ignore any file with a filename starting with a '.' -- metadatastore
 writes its tempfiles prefixed with a '.' .

This patch is OK for me.

Just a comment: this patch removes the possibility to have a property
named ..property, right? is this OK?

Is any activity setting a property that its name starts with .? We
should check that and change its name.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Remove temporary downloaded (cancelled) files SL #3973

2012-10-01 Thread Manuel Kaufmann
When a download is cancelled for any reason WebKit leaves a temporary
file called .goutputstream-* in the instance directory. This is
because of a bug in GLib:

 * https://bugzilla.gnome.org/show_bug.cgi?id=629301

This patch is a workaround to that behaviour. Every time that Browse
is started it looks for all the .goutputstream files in the
instance directory and checks its mtime. If it greater than 1 day it
removes the old temporary file.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 webactivity.py | 29 +
 1 file changed, 29 insertions(+)

diff --git a/webactivity.py b/webactivity.py
index dff3a4a..6ba1099 100644
--- a/webactivity.py
+++ b/webactivity.py
@@ -37,6 +37,7 @@ from gi.repository import GConf
 import locale
 import cairo
 import StringIO
+import datetime
 from hashlib import sha1
 
 from sugar3.activity import activity
@@ -241,6 +242,34 @@ class WebActivity(activity.Activity):
 else:
 _logger.debug('Created activity')
 
+# README: this is a workaround to remove old temp file
+# http://bugs.sugarlabs.org/ticket/3973
+self._cleanup_temp_files()
+
+def _cleanup_temp_files(self):
+Removes temporary files generated by Download Manager that
+were cancelled by the user or failed for any reason.
+
+There is a bug in GLib that makes this to happen:
+https://bugzilla.gnome.org/show_bug.cgi?id=629301
+
+
+temp_path = os.path.join(self.get_activity_root(), 'instance')
+for f in os.listdir(temp_path):
+if f.startswith('.goutputstream-'):
+fpath = os.path.join(temp_path, f)
+mdate = datetime.datetime.fromtimestamp(
+os.path.getmtime(fpath))
+now = datetime.datetime.now()
+delta = now - mdate
+if delta.days  0:
+logging.warning('Removing old temporary file: %s', fpath)
+try:
+os.remove(fpath)
+except OSError:
+logging.error('Temporary file could not be '
+  'removed: %s', fpath)
+
 def _on_focus_url_entry(self, gobject):
 self._primary_toolbar.entry.grab_focus()
 
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Handle LoadInterruptedByPolicyChange SL #3972

2012-10-01 Thread Manuel Kaufmann
This error is raised when the mimetype policy suffers a change. When
this happens __load_error_cb is called and we were showing the error
page in any case.

With this patch that case is properly handled in __load_error_cb and
the error page is not shown on the current tab. In fact, we keep the
same page where the user clicked the link in the tab.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 browser.py | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/browser.py b/browser.py
index fb8a985..ccdf78c 100644
--- a/browser.py
+++ b/browser.py
@@ -653,6 +653,12 @@ class Browser(WebKit.WebView):
 'url': uri,
 }
 
+# Don't show error page if the load was interrupted by policy
+# change. For example, if a file was requested for download
+if web_error.code == WebKit.PolicyError.\
+FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE:
+return True
+
 html = open(DEFAULT_ERROR_PAGE, 'r').read() % data
 web_frame.load_alternate_string(html, '', uri)
 
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [DESIGN] List View of Activities (hovering stars)

2012-09-30 Thread Manuel Kaufmann
On Sat, Sep 29, 2012 at 6:00 PM, Gary Martin garycmar...@googlemail.com wrote:
 So if the star is currently enabled (colorized) and you hover over it, you'll 
 first see the grey rounded rectangle outline, then if you click/press it you 
 will still see the grey rectangle outline and the star will change 
 immediately to disabled (uncolorized star), as you release and move the mouse 
 away the grey rounded rectangle outline will disappear.

 If the star is currently disabled (uncolorized) and you hover over it, you'll 
 first see the grey rounded rectangle outline, then if you click/press it you 
 will still see the grey rectangle outline and the star will change 
 immediately to enabled (colorized star), as you release and move the mouse 
 away the grey rounded rectangle outline will disappear.

Cool! This is exactly what I tried to write. Thanks to clarify it.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH 1/7] Add ds_clean flag to trigger index rebuilds #2095, #2317

2012-09-30 Thread Manuel Kaufmann
On Fri, Sep 21, 2012 at 12:55 AM, Martin Langhoff mar...@laptop.org wrote:
 This gives us more complete coverage of cases where ENOSPC or
 other errors are hit when creating/updating datastore entries.

I reviewed this patch and I think it's OK. I didn't test it because
I'm not sure how to simulate that scenario.

Just a comment: why you didn't add a callback function
(_delete_completion_cb) to the delete method and make create /
update / delete consistent between them? In that method we can add
self._mark_clean

Thought: we are dealing near ENOSPC, right? So, maybe the clean_flag
will not be created (this is already handled in the patch) and this
patch will not take effect the next time the XO restarts and we will
be in the same situation again.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH 2/7] Remove invalid/corrupt on-disk entries #2317

2012-09-30 Thread Manuel Kaufmann
On Fri, Sep 21, 2012 at 12:55 AM, Martin Langhoff mar...@laptop.org wrote:
 When operating close to ENOSPC, we sometimes end up with
 incomplete or invalid on-disk entries. So we prune these
 during index rebuild.

I took a look at this patch and it seems to be OK.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH 3/7] metadatastore: store/change files on disk defensively #2317

2012-09-30 Thread Manuel Kaufmann
Hi,

I reviewed this patch and it seems to be OK for me.

The only thing that I do not understand well is this comment /
section. Can you explain to me this a bit more? Thanks

On Fri, Sep 21, 2012 at 12:55 AM, Martin Langhoff mar...@laptop.org wrote:
 +# FIXME: this codepath handles raw image data
 +# str() is 8-bit clean right now, but
 +# this won't last. We will need more explicit
 +# handling of strings, int/floats vs raw data
 +if isinstance(value, unicode):
 +value = value.encode('utf-8')
 +elif not isinstance(value, basestring):
 +value = str(value)


-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [sugar-toolkit-gtk2] Add management of summary property to the activity.info file - v2

2012-09-29 Thread Manuel Kaufmann
On Thu, Sep 20, 2012 at 12:34 PM,  godi...@sugarlabs.org wrote:
 +self._summary = None
 +self._local_summary = None

Sorry to bother you, I have two questions:

 * What each of these variable mean?
 * What are the difference between them?

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [DESIGN] List View of Activities (hovering stars)

2012-09-29 Thread Manuel Kaufmann
Hello,

I've just realize that there is no feedback on clicking on the star in
the List View to make it Favorite.

 1. Go to Home View
 2. Click on List View
 3. Hover one the star of one no-favorite Activity
 4. The star gets colorized
 5. Click on it
 6. Did I click?

Maybe we can use a 0.5 alpha star when the user is hovering the star
of a no-favorite Activity to highlight it but showing that it's not
activated and 1.0 after a click.

Wikipedia on its rating feature uses a circle to show what star you
are hovering. Here is an example at the bottom of the page:

 * http://es.wikipedia.org/wiki/New_X-Men

What do you think?

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [DESIGN] List View of Activities (hovering stars)

2012-09-29 Thread Manuel Kaufmann
On Sat, Sep 29, 2012 at 3:52 PM, Gary Martin garycmar...@googlemail.com wrote:
 I think my last suggestion was that we should be using the round grey 
 rectangle outline to show hover, press visual feedback (as we do in the Home 
 view for Activity icons, though this is currently broken after the GTK3 shell 
 port and theming), this sounds like a similar fix as to the UI you linked to 
 in wikipedia.

So, we will have 4 states:

 1. Pressed and un hovered: colorized star without grey rectangle
 2. Pressed and hovered: colorized star with grey rectangle
 3. Unpressed and un hovered: uncolorized star without grey rectangle
 4. Unpressed and hovered: uncolorized star withtout grey rectangle

So, if I click on the star in the 4) state I will get 2) immediately, right?

I like this way.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] scale-changed and angle-changed events

2012-09-28 Thread Manuel Kaufmann
Hello,

I'm working on ImageViewer using SugarGestures.ZoomController and
SugarGestures.RotateController with the signals: angle-changed and
scale-changed.

I realized that those signals are trigged without a change on those
values. For example, if I simply touch the screen with two fingers and
do not move them (just keep them frozen into the screen) I receive a
lot of calls to the callback function associated to those events with
the same scale, angle and diff values.

I think it's a bug upstream but maybe I'm confused about how it should work.

Thanks,

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [RELEASE] Browse-141

2012-09-28 Thread Manuel Kaufmann
On Fri, Sep 28, 2012 at 11:37 AM, Manuel Quiñones ma...@laptop.org wrote:
 The Palettes are back, nice page for errors, and many more fixes release.

I'm very happy with this release. Thanks to manuq and gary for they help!

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] last-minute feature proposal for 0.98

2012-09-28 Thread Manuel Kaufmann
On Fri, Sep 28, 2012 at 11:19 AM, Walter Bender walter.ben...@gmail.com wrote:
 +self._jobject.metadata['launch-times'] = '%s, %d' % (
 +self._jobject.metadata['launch-times'],
 +int(time.time()))

Another approach for this portion. Maybe more readable... or not :)

self._jobject.metadata['launch-times'] += ', %d' % int(time.time())

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Display only the URL in the URL entry SL #3553

2012-09-27 Thread Manuel Kaufmann
On Thu, Sep 27, 2012 at 11:25 AM, Martin Langhoff
martin.langh...@gmail.com wrote:
  - The tabs are often too small to show the title.

This behaviour is going to change because we are going to use the same
version of the tabs that is on the Gtk3 port of Terminal. They use all
the available space to be expanded.

  - The title is more important for the user than the URL. No?

I think it's a good idea to show both of them.

Personally, I agreed with this feature. It's the way that many browsers work.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] Performace in os3

2012-09-27 Thread Manuel Kaufmann
Hello,

I'm working on my 1.75 XO with os3 and I feel it really slow. There
are some examples:

 - Hover in Favourite and List view

1. Hover in Favourite view
2. Move the mouse directly to List view and hover it
3. It shows the palette after the timeout but the palette square
appears first and then the text

(test this many times because sometimes does not happen)


 - Show and Hide the frame

1. Go to the edge of the screen
2. The frame appears
3. Go again to the edge of the screen (to make the frame hides) --
comment: this works different than before, it was no needed to go
again to the edge of the screen to make it disappears.
4. The frame disappears but it leaves the same frame (width and hight)
in gray color for a while

Besides, I noticed that when you hover on Home Icons they are no
longer highlighted as it was gtk2 version of Sugar. Is this a desired
behaviour?

See you,


-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Error page SL #3500

2012-09-25 Thread Manuel Kaufmann
On Fri, Sep 21, 2012 at 8:32 PM, Martin Langhoff
martin.langh...@gmail.com wrote:
 So just put img src=file:///path/to/file . That saves a some of
 pointless CPU cycles, some RAM.
 This old man doesn't like inefficient code, even in small details.

I agree with you in this point but I would like to mention that this
feature (reading from file:// uri) has to be enabled because it is
not enabled by default[1] and this is because it was marked as a
security issue[2].

** Message: console message:  @0: Not allowed to load local resource:
file:///home/humitos/src/browse/browse.png

What do you think? Should I go for the file:// approach anyway?

[1] 
http://webkitgtk.org/reference/webkitgtk/stable/WebKitWebSettings.html#WebKitWebSettings--enable-file-access-from-file-uris
[2] http://en.wikipedia.org/wiki/File_URI_scheme

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Undo close tab SL #3534

2012-09-24 Thread Manuel Kaufmann
Browse manages a list of 10 recently closed tab to be able to re-open
them (the most recently closed is opened firstly) by pressing
Ctrl+Shift+T.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 browser.py | 13 +
 webactivity.py | 11 +--
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/browser.py b/browser.py
index de546f2..8f960cc 100644
--- a/browser.py
+++ b/browser.py
@@ -19,6 +19,7 @@
 import os
 import time
 import re
+import collections
 from gettext import gettext as _
 
 from gi.repository import GObject
@@ -99,6 +100,16 @@ class TabbedView(BrowserNotebook):
 self._update_closing_buttons()
 self._update_tab_sizes()
 
+# LIFO queue of closed tabs (10 tabs max)
+self.closed_tabs = collections.deque(maxlen=10)
+
+def get_last_closed_tab(self):
+try:
+uri = self.closed_tabs.pop()
+except IndexError:
+uri = None
+return uri
+
 def normalize_or_autosearch_url(self, url):
 Normalize the url input or return a url for search.
 
@@ -164,6 +175,8 @@ class TabbedView(BrowserNotebook):
 self._update_tab_sizes()
 
 def __page_removed_cb(self, notebook, child, pagenum):
+self.closed_tabs.append(child._browser.props.uri)
+
 if self.get_n_pages():
 self._update_closing_buttons()
 self._update_tab_sizes()
diff --git a/webactivity.py b/webactivity.py
index 24f3b44..2559fa7 100644
--- a/webactivity.py
+++ b/webactivity.py
@@ -428,8 +428,15 @@ class WebActivity(activity.Activity):
 def _key_press_cb(self, widget, event):
 key_name = Gdk.keyval_name(event.keyval)
 browser = self._tabbed_view.props.current_browser
-
-if event.get_state()  Gdk.ModifierType.CONTROL_MASK:
+state = event.get_state()
+
+if state  Gdk.ModifierType.CONTROL_MASK:
+if state  Gdk.ModifierType.SHIFT_MASK:
+if key_name == 'T':
+uri = self._tabbed_view.get_last_closed_tab()
+if uri is not None:
+self._tabbed_view.current_browser.emit('new-tab', uri)
+return True
 
 if key_name == 'd':
 self._add_link()
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Show Bookmark toolbar when a bookmark is added SL #3868

2012-09-24 Thread Manuel Kaufmann
The Bookmark toolbar is shown when the first bookmark is added by the
user.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 webactivity.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/webactivity.py b/webactivity.py
index 24f3b44..f9497db 100644
--- a/webactivity.py
+++ b/webactivity.py
@@ -172,7 +172,6 @@ class WebActivity(activity.Activity):
 
 self._tray = HTray()
 self.set_tray(self._tray, Gtk.PositionType.BOTTOM)
-self._tray.show()
 
 self._primary_toolbar = PrimaryToolbar(self._tabbed_view, self)
 self._edit_toolbar = EditToolbar(self)
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Display only the URL in the URL entry SL #3553

2012-09-24 Thread Manuel Kaufmann
The Title of the current page is no longer shown in the URL
entry. Now, it's only shown in the tab and the current URL is visible
all the time in the URL entry.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 browser.py| 13 +
 webtoolbar.py | 53 +
 2 files changed, 18 insertions(+), 48 deletions(-)

diff --git a/browser.py b/browser.py
index de546f2..1c67beb 100644
--- a/browser.py
+++ b/browser.py
@@ -453,6 +453,10 @@ class Browser(WebKit.WebView):
 # Scale text and graphics:
 self.set_full_content_zoom(True)
 
+# This property is used to set the title immediatly the user
+# presses Enter on the URL Entry
+self._loading_uri = None
+
 # Reference to the global history and callbacks to handle it:
 self._global_history = globalhistory.get_global_history()
 self.connect('notify::load-status', self.__load_status_changed_cb)
@@ -542,6 +546,15 @@ class Browser(WebKit.WebView):
 def open_new_tab(self, url):
 self.emit('new-tab', url)
 
+def _set_loading_uri(self, uri):
+self._loading_uri = uri
+
+def _get_loading_uri(self):
+return self._loading_uri
+
+loading_uri = GObject.property(type=str, setter=_set_loading_uri,
+   getter=_get_loading_uri)
+
 def __run_file_chooser(self, browser, request):
 picker = FilePicker(self)
 chosen = picker.run()
diff --git a/webtoolbar.py b/webtoolbar.py
index 28bc015..1d531bc 100644
--- a/webtoolbar.py
+++ b/webtoolbar.py
@@ -47,7 +47,6 @@ class WebEntry(iconentry.IconEntry):
 GObject.GObject.__init__(self)
 
 self._address = None
-self._title = None
 self._search_view = self._search_create_view()
 
 self._search_window = Gtk.Window(type=Gtk.WindowType.POPUP)
@@ -57,8 +56,6 @@ class WebEntry(iconentry.IconEntry):
 self.connect('focus-in-event', self.__focus_in_event_cb)
 self.connect('populate-popup', self.__populate_popup_cb)
 self.connect('key-press-event', self.__key_press_event_cb)
-self.connect('enter-notify-event', self.__enter_notify_event_cb)
-self.connect('leave-notify-event', self.__leave_notify_event_cb)
 self._focus_out_hid = self.connect(
 'focus-out-event', self.__focus_out_event_cb)
 self._change_hid = self.connect('changed', self.__changed_cb)
@@ -79,18 +76,11 @@ class WebEntry(iconentry.IconEntry):
 
 def _set_address(self, address):
 self._address = address
-if address is not None and self.props.has_focus:
+if address is not None:
 self._set_text(address)
 
 address = GObject.property(type=str, setter=_set_address)
 
-def _set_title(self, title):
-self._title = title
-if title is not None and not self.props.has_focus:
-self._set_text(title)
-
-title = GObject.property(type=str, setter=_set_title)
-
 def _search_create_view(self):
 view = Gtk.TreeView()
 view.props.headers_visible = False
@@ -146,21 +136,11 @@ class WebEntry(iconentry.IconEntry):
 self._search_window.hide()
 
 def __focus_in_event_cb(self, entry, event):
-self._set_text(self._address)
 self._search_popdown()
 
 def __focus_out_event_cb(self, entry, event):
-self._set_text(self._title)
 self._search_popdown()
 
-def __enter_notify_event_cb(self, entry, event):
-if not entry.props.has_focus:
-self._set_text(self._address)
-
-def __leave_notify_event_cb(self, entry, event):
-if not entry.props.has_focus:
-self._set_text(self._title)
-
 def __view_button_press_event_cb(self, view, event):
 model = view.get_model()
 
@@ -241,7 +221,6 @@ class PrimaryToolbar(ToolbarBase):
 self._tabbed_view = tabbed_view
 
 self._loading = False
-self._title = _('Untitled')
 
 toolbar = self.toolbar
 activity_button = ActivityToolbarButton(self._activity)
@@ -310,7 +289,6 @@ class PrimaryToolbar(ToolbarBase):
 self._loading_changed_hid = None
 self._progress_changed_hid = None
 self._session_history_changed_hid = None
-self._title_changed_hid = None
 self._uri_changed_hid = None
 
 if tabbed_view.get_n_pages():
@@ -324,25 +302,19 @@ class PrimaryToolbar(ToolbarBase):
 
 def _connect_to_browser(self, browser):
 if self._browser is not None:
-self._browser.disconnect(self._title_changed_hid)
 self._browser.disconnect(self._uri_changed_hid)
 self._browser.disconnect(self._progress_changed_hid)
 self._browser.disconnect(self._loading_changed_hid)
 
 self._browser = browser
-if self._browser.props.title:
-self._set_title(self._browser.props.title)
-else:
-self._set_title(_('Untitled

[Sugar-devel] [PATCH v2 Browse] Busy indication SL #851

2012-09-21 Thread Manuel Kaufmann
Show WATCH Cursor when the page is loading and LEFT_PTR when the load
finishes.

This changes take in consideration the tab that the user is watching,
so the cursor refers to the state of the current browser / tab.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 browser.py | 21 +
 webactivity.py | 16 
 2 files changed, 37 insertions(+)

diff --git a/browser.py b/browser.py
index de546f2..99b05d4 100644
--- a/browser.py
+++ b/browser.py
@@ -39,6 +39,8 @@ import globalhistory
 import downloadmanager
 from pdfviewer import PDFTabPage
 
+from webactivity import NORMAL_CURSOR, WATCH_CURSOR
+
 ZOOM_ORIGINAL = 1.0
 _ZOOM_AMOUNT = 0.1
 _LIBRARY_PATH = '/usr/share/library-common/index.html'
@@ -188,10 +190,26 @@ class TabbedView(BrowserNotebook):
 self.set_current_page(next_index)
 tab_page.setup(url)
 
+def __load_status_changed_cb(self, widget, param):
+# Do not change the cursor if the load-status changed is not
+# on the current browser
+if self.props.current_browser != widget:
+return
+
+status = widget.get_load_status()
+if status in (WebKit.LoadStatus.PROVISIONAL,
+  WebKit.LoadStatus.COMMITTED,
+  WebKit.LoadStatus.FIRST_VISUALLY_NON_EMPTY_LAYOUT):
+self.get_window().set_cursor(WATCH_CURSOR)
+elif status in (WebKit.LoadStatus.FAILED,
+WebKit.LoadStatus.FINISHED):
+self.get_window().set_cursor(NORMAL_CURSOR)
+
 def add_tab(self, next_to_current=False):
 browser = Browser()
 browser.connect('new-tab', self.__new_tab_cb)
 browser.connect('open-pdf', self.__open_pdf_in_new_tab_cb)
+browser.connect('notify::load-status', self.__load_status_changed_cb)
 
 if next_to_current:
 self._insert_tab_next(browser)
@@ -318,6 +336,8 @@ class TabbedView(BrowserNotebook):
 browser = Browser()
 browser.connect('new-tab', self.__new_tab_cb)
 browser.connect('open-pdf', self.__open_pdf_in_new_tab_cb)
+browser.connect('notify::load-status',
+self.__load_status_changed_cb)
 self._append_tab(browser)
 browser.set_history(tab_history)
 
@@ -404,6 +424,7 @@ class TabLabel(Gtk.HBox):
 
 def __load_status_changed_cb(self, widget, param):
 status = widget.get_load_status()
+
 if status == WebKit.LoadStatus.FAILED:
 self._label.set_text(self._title)
 elif WebKit.LoadStatus.PROVISIONAL = status \
diff --git a/webactivity.py b/webactivity.py
index 24f3b44..88555e6 100644
--- a/webactivity.py
+++ b/webactivity.py
@@ -54,6 +54,9 @@ from sugar3.graphics.toolbarbox import ToolbarButton
 
 PROFILE_VERSION = 2
 
+NORMAL_CURSOR = Gdk.Cursor(Gdk.CursorType.LEFT_PTR)
+WATCH_CURSOR = Gdk.Cursor(Gdk.CursorType.WATCH)
+
 _profile_version = 0
 _profile_path = os.path.join(activity.get_activity_root(), 'data/gecko')
 _version_file = os.path.join(_profile_path, 'version')
@@ -169,6 +172,7 @@ class WebActivity(activity.Activity):
 self._force_close = False
 self._tabbed_view = TabbedView()
 self._tabbed_view.connect('focus-url-entry', self._on_focus_url_entry)
+self._tabbed_view.connect('switch-page', self.__switch_page_cb)
 
 self._tray = HTray()
 self.set_tray(self._tray, Gtk.PositionType.BOTTOM)
@@ -596,6 +600,18 @@ class WebActivity(activity.Activity):
 downloadmanager.remove_all_downloads()
 self.close()
 
+def __switch_page_cb(self, tabbed_view, page, page_num):
+browser = page._browser
+status = browser.get_load_status()
+
+if status in (WebKit.LoadStatus.COMMITTED,
+  WebKit.LoadStatus.FIRST_VISUALLY_NON_EMPTY_LAYOUT):
+self.get_window().set_cursor(WATCH_CURSOR)
+elif status in (WebKit.LoadStatus.PROVISIONAL,
+WebKit.LoadStatus.FAILED,
+WebKit.LoadStatus.FINISHED):
+self.get_window().set_cursor(NORMAL_CURSOR)
+
 def get_document_path(self, async_cb, async_err_cb):
 browser = self._tabbed_view.props.current_browser
 browser.get_source(async_cb, async_err_cb)
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Error page SL #3500

2012-09-21 Thread Manuel Kaufmann
On Wed, Sep 19, 2012 at 10:56 PM, Martin Langhoff
martin.langh...@gmail.com wrote:
 You have the file on-disk. It is inefficient to base64-encode it.

I'm not sure to understand what you are saying here. I'm not doing
this each time the function is called. Here, I just showed what I did
to get the base64 file encoded. I mean, I did this just once and I put
the result inside the HTML file. Epiphany does the same: it has
hardcoded the image inside the html. Is that a bad idea?


-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Change back/forward navigation shortcut to Alt modifier SL #3536

2012-09-21 Thread Manuel Kaufmann
Signed-off-by: Manuel Quiñones ma...@laptop.org
Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 webactivity.py | 14 --
 webtoolbar.py  |  2 ++
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/webactivity.py b/webactivity.py
index 24f3b44..e911337 100644
--- a/webactivity.py
+++ b/webactivity.py
@@ -449,12 +449,6 @@ class WebActivity(activity.Activity):
 elif key_name == '0':
 _logger.debug('keyboard: Actual size')
 browser.set_zoom_level(ZOOM_ORIGINAL)
-elif key_name == 'Left':
-_logger.debug('keyboard: Go back')
-browser.go_back()
-elif key_name == 'Right':
-_logger.debug('keyboard: Go forward')
-browser.go_forward()
 elif key_name == 'r':
 _logger.debug('keyboard: Reload')
 browser.reload()
@@ -465,6 +459,14 @@ class WebActivity(activity.Activity):
 
 return True
 
+elif event.get_state()  Gdk.ModifierType.MOD1_MASK:
+if key_name == 'Left':
+_logger.debug('keyboard: Go back')
+browser.go_back()
+elif key_name == 'Right':
+_logger.debug('keyboard: Go forward')
+browser.go_forward()
+
 elif key_name in ('KP_Up', 'KP_Down', 'KP_Left', 'KP_Right'):
 scrolled_window = browser.get_parent()
 
diff --git a/webtoolbar.py b/webtoolbar.py
index 28bc015..5193d89 100644
--- a/webtoolbar.py
+++ b/webtoolbar.py
@@ -269,6 +269,7 @@ class PrimaryToolbar(ToolbarBase):
 
 self._back = ToolButton('go-previous-paired')
 self._back.set_tooltip(_('Back'))
+self._back.props.accelerator = 'AltLeft'
 self._back.props.sensitive = False
 self._back.connect('clicked', self._go_back_cb)
 toolbar.insert(self._back, -1)
@@ -283,6 +284,7 @@ class PrimaryToolbar(ToolbarBase):
 
 self._forward = ToolButton('go-next-paired')
 self._forward.set_tooltip(_('Forward'))
+self._forward.props.accelerator = 'AltRight'
 self._forward.props.sensitive = False
 self._forward.connect('clicked', self._go_forward_cb)
 toolbar.insert(self._forward, -1)
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Error page SL #3500

2012-09-19 Thread Manuel Kaufmann
On Tue, Sep 18, 2012 at 10:58 PM, James Cameron qu...@laptop.org wrote:
 Neat.  What method did you use to convert the image?

Python... It is my best friend :)

 import base64
 base64.b64encode(open('browse-logo.png', 'r').read())

See you,

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Error page SL #3500

2012-09-19 Thread Manuel Kaufmann
On Wed, Sep 19, 2012 at 8:38 AM, Manuel Kaufmann humi...@gmail.com wrote:
 Added an Error page with Sugar style that informs the users about
 the the page could not be loaded for any reason.

I had to add --no-validate to the git send-email command because
this patch has a line longer than 998 chars and it's not valid due a
SMTP limitation. I'm not sure if this patch will apply properly, if
not, please download it from SugarLabs' Trac:

 * 
http://bugs.sugarlabs.org/attachment/ticket/3500/0001-Error-page-SL-3500.2.patch

Thanks,

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Cancel a download if space is very tight SL #394

2012-09-18 Thread Manuel Kaufmann
On Mon, Sep 17, 2012 at 7:40 PM, James Cameron qu...@laptop.org wrote:
 I've no other comments about the patch.

Thanks for your comments. I'm about to send a new patch.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH sugar-toolkit-gtk3 2/2] Signal to check free available space

2012-09-18 Thread Manuel Kaufmann
Datastore will emit the 'datastore.error' signal when the free
available space will be under SPACE_THRESHOLD. This will allow
activities to handle this situation properly. For example, Browse
could cancel a download in progress.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 src/sugar3/datastore/datastore.py | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/src/sugar3/datastore/datastore.py 
b/src/sugar3/datastore/datastore.py
index 33100e8..6a39b4e 100644
--- a/src/sugar3/datastore/datastore.py
+++ b/src/sugar3/datastore/datastore.py
@@ -39,6 +39,11 @@ DS_DBUS_SERVICE = 'org.laptop.sugar.DataStore'
 DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore'
 DS_DBUS_PATH = '/org/laptop/sugar/DataStore'
 
+SPACE_THRESHOLD = 52428800  # 50Mb
+
+# Error codes
+LOW_SPACE = 1
+
 _data_store = None
 
 
@@ -57,14 +62,25 @@ def _get_data_store():
 return _data_store
 
 
+def free_available_space(path='/'):
+s = os.statvfs(path)
+return s.f_bavail * s.f_frsize
+
+
 def __datastore_created_cb(object_id):
 metadata = _get_data_store().get_properties(object_id, byte_arrays=True)
 updated.send(None, object_id=object_id, metadata=metadata)
+if free_available_space()  SPACE_THRESHOLD:
+error.send(None, errno=LOW_SPACE)
 
 
 def __datastore_updated_cb(object_id):
 metadata = _get_data_store().get_properties(object_id, byte_arrays=True)
 updated.send(None, object_id=object_id, metadata=metadata)
+if free_available_space()  SPACE_THRESHOLD:
+logging.warning('Free space below SPACE_THRESHOLD: %s Kb',
+SPACE_THRESHOLD)
+error.send(None, errno=LOW_SPACE)
 
 
 def __datastore_deleted_cb(object_id):
@@ -74,6 +90,8 @@ created = dispatch.Signal()
 deleted = dispatch.Signal()
 updated = dispatch.Signal()
 
+error = dispatch.Signal()
+
 _get_data_store()
 
 
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse 1/2] Cancel a download if space is very tight SL #394

2012-09-18 Thread Manuel Kaufmann
It checks for enough space (using Activity.enough_space) before
downloading the file. If not, Browse will cancel the download process
before starting it and an Alert will be shown to the user to inform
this situation.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 downloadmanager.py | 63 +-
 1 file changed, 48 insertions(+), 15 deletions(-)

diff --git a/downloadmanager.py b/downloadmanager.py
index 9950c16..5ad1a6f 100644
--- a/downloadmanager.py
+++ b/downloadmanager.py
@@ -74,16 +74,18 @@ class Download(object):
 self._stop_alert = None
 
 # figure out download URI
-temp_path = os.path.join(activity.get_activity_root(), 'instance')
-if not os.path.exists(temp_path):
-os.makedirs(temp_path)
+self.temp_path = os.path.join(activity.get_activity_root(), 'instance')
+if not os.path.exists(self.temp_path):
+os.makedirs(self.temp_path)
 
-fd, self._dest_path = tempfile.mkstemp(dir=temp_path,
+fd, self._dest_path = tempfile.mkstemp(dir=self.temp_path,
 suffix=download.get_suggested_filename(),
 prefix='tmp')
 os.close(fd)
 logging.debug('Download destination path: %s' % self._dest_path)
 
+# We have to start the download to get 'total-size'
+# property. It not, 0 is returned
 self._download.set_destination_uri('file://' + self._dest_path)
 self._download.start()
 
@@ -95,17 +97,48 @@ class Download(object):
 def __state_change_cb(self, download, gparamspec):
 state = self._download.get_status()
 if state == WebKit.DownloadStatus.STARTED:
-self._create_journal_object()
-self._object_id = self.dl_jobject.object_id
-
-alert = TimeoutAlert(9)
-alert.props.title = _('Download started')
-alert.props.msg = _('%s' % self._download.get_suggested_filename())
-self._activity.add_alert(alert)
-alert.connect('response', self.__start_response_cb)
-alert.show()
-global _active_downloads
-_active_downloads.append(self)
+# Check free space and cancel the download if there is not enough.
+total_size = self._download.get_total_size()
+logging.debug('Total size of the file: %s', total_size)
+enough_space = self._activity.enough_space(
+total_size, path=self.temp_path)
+if not enough_space:
+logging.debug('Download canceled because of Disk Space')
+self.cancel()
+
+self._canceled_alert = Alert()
+self._canceled_alert.props.title = _('Not enough space '
+ 'to download')
+
+total_size_mb = total_size / 1024.0 ** 2
+free_space_mb = datastore.free_available_space(
+path=self.temp_path) - datastore.SPACE_THRESHOLD \
+/ 1024.0 ** 2
+filename = self._download.get_suggested_filename()
+self._canceled_alert.props.msg = \
+_('Download %s requires %.2f MB of free space, only '
+  '%.2f MB is available' % (filename, total_size_mb,
+  free_space_mb))
+ok_icon = Icon(icon_name='dialog-ok')
+self._canceled_alert.add_button(Gtk.ResponseType.OK,
+_('Ok'), ok_icon)
+ok_icon.show()
+self._canceled_alert.connect('response',
+ self.__stop_response_cb)
+self._activity.add_alert(self._canceled_alert)
+else:
+self._create_journal_object()
+self._object_id = self.dl_jobject.object_id
+
+alert = TimeoutAlert(9)
+alert.props.title = _('Download started')
+alert.props.msg = _('%s' %
+self._download.get_suggested_filename())
+self._activity.add_alert(alert)
+alert.connect('response', self.__start_response_cb)
+alert.show()
+global _active_downloads
+_active_downloads.append(self)
 
 elif state == WebKit.DownloadStatus.FINISHED:
 self._stop_alert = Alert()
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse 2/2] Handle datastore.error signal

2012-09-18 Thread Manuel Kaufmann
Stop the downloading process when this signal is received with the
datastore.LOW_SPACE error code.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 downloadmanager.py | 8 
 1 file changed, 8 insertions(+)

diff --git a/downloadmanager.py b/downloadmanager.py
index 5ad1a6f..bd8386d 100644
--- a/downloadmanager.py
+++ b/downloadmanager.py
@@ -65,6 +65,9 @@ class Download(object):
 self._download.connect('notify::status', self.__state_change_cb)
 self._download.connect('error', self.__error_cb)
 
+# connect the error datastore signal to manage LOW_SPACE
+datastore.error.connect(self.__datastore_error_cb)
+
 self.datastore_deleted_handler = None
 
 self.dl_jobject = None
@@ -89,6 +92,11 @@ class Download(object):
 self._download.set_destination_uri('file://' + self._dest_path)
 self._download.start()
 
+def __datastore_error_cb(self, sender, **kwargs):
+logging.debug('__datastore_error_cb')
+if kwargs.get('errno', -1) == datastore.LOW_SPACE:
+self._download.cancel()
+
 def __progress_change_cb(self, download, something):
 progress = self._download.get_progress()
 self.dl_jobject.metadata['progress'] = str(int(progress * 100))
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] Not enough space adventure

2012-09-18 Thread Manuel Kaufmann
Hello people,

I'd like to comment what I've been doing these days regarding
Downloading a file with Browse without having enough space to keep
it.

 * http://bugs.sugarlabs.org/ticket/394

We where discussing about this last week[1] and we found the root
issue of this problem: Sugar is not handling ENOSPC error. This could
cause some problems at boot time when the XO is restarted, but as we
discussed[2], Linux has made some improvement on this side and it
seems that it recovers without problem (we need more testing here, I
think).

So, there are different problems to manage here:
 1. What are we going to do when ENOSPC is reached?

I'm not sure about this point and I think we have to discuss what to
do here and how implement this. There is an important ticket for this

 * http://bugs.sugarlabs.org/ticket/2317

 2. How are we going to avoid ENOSCP?

Well, this is the topic where I focused my work. Trying to avoid
reaching ENOSCP. A good place to do some work is Browse (but this work
include some extra modifications in other components as well) because
it's the main activity that generate big files by downloading them
from the internet. So, Gonzalo and I were discussing about a good
implementation regarding this and we found, at least, an alternative.
It consists in:

 - remove the annoying check of free space
(sugar3.datastore.datastore.SPACE_THRESHOLD = 50Mb at the moment) from
the Journal Activity that shows all the time the ModalAlert saying
Your Journal is full. Please remove some entries every time and it
doesn't allow you to do another things.

 - create a signal inside sugar-toolkit-gtk3 datastore that is emitted
when free space is behind
sugar3.datastore.datastore.SPACE_THRESHOLD. This check is done every
time a model is updated or created by the datastore.

 - this signal can be connected from every activity that wants to
handle this situation. For example in Browse we are cancelling the
download in progress when we get that signal

 - the same signal is captured in Journal Activity to show the
ModalAlert saying Your Journal is full that was shown before

 - create a helper function in sugar-toolkit-gtk3 activity Activity
class to check if there is enough space to keep a new file (Browse
uses this before downloading a file from the internet). I decided to
put this helper inside Activity class because I think it could be
useful for many activities.

 - compare (in Browse) the Content-Length with the free space
available + SPACE_THRESHOLD (this is done by the helper function) and
decide if the download is going to take place or not

These are all the patches involved on this change:

 * http://patchwork.sugarlabs.org/patch/1749/
 * http://patchwork.sugarlabs.org/patch/1750/
 * http://patchwork.sugarlabs.org/patch/1751/
 * http://patchwork.sugarlabs.org/patch/1752/
 * http://patchwork.sugarlabs.org/patch/1753/

Thanks, comments and suggestions are welcomed.

[1] http://lists.sugarlabs.org/archive/sugar-devel/2012-September/039516.html
[2] http://lists.sugarlabs.org/archive/sugar-devel/2012-September/039576.html

PD: Gonzalo, please, add whatever thing that I missed.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Error page SL #3500

2012-09-18 Thread Manuel Kaufmann
Added an Error page with Sugar style that informs the users about
they are not connected to the internet when the page can not reached
for any reason.

This patch contains a HTML template (error_page.tmpl) that is used to
generate the error page with the correct language.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 browser.py   |  31 +
 data/activity-web.png| Bin 0 - 6064 bytes
 data/browse-view-refresh.png | Bin 0 - 481 bytes
 data/error_page.tmpl |  53 +++
 4 files changed, 84 insertions(+)
 create mode 100644 data/activity-web.png
 create mode 100644 data/browse-view-refresh.png
 create mode 100644 data/error_page.tmpl

diff --git a/browser.py b/browser.py
index de546f2..c9bcc1c 100644
--- a/browser.py
+++ b/browser.py
@@ -58,6 +58,9 @@ _NON_SEARCH_REGEX = re.compile('''
 ^file:.*$)
 ''', re.VERBOSE)
 
+DEFAULT_ERROR_PAGE = os.path.join(activity.get_bundle_path(),
+  'data/error_page.html')
+
 
 class CommandListener(object):
 def __init__(self, window):
@@ -462,6 +465,7 @@ class Browser(WebKit.WebView):
  self.__mime_type_policy_cb)
 self.connect('new-window-policy-decision-requested',
  self.__new_window_policy_cb)
+self.connect('load-error', self.__load_error_cb)
 
 try:
 self.connect('run-file-chooser', self.__run_file_chooser)
@@ -603,6 +607,33 @@ class Browser(WebKit.WebView):
 downloadmanager.add_download(download, browser)
 return True
 
+def __create_error_page(self, url):
+Create the error page in the correct language
+
+data = {
+'page_title': _('You are not connected to the internet'),
+'title': _('You are not connected to the internet'),
+'message': _('You will need to connect using the '
+ 'Neighborhoodbr /view in order '
+ 'to continue browsing'),
+'btn_value': _('Try again'),
+'url': url,
+}
+filepath = os.path.join(activity.get_bundle_path(),
+'data/error_page.tmpl')
+html = open(filepath, 'r').read() % data
+
+f = open(DEFAULT_ERROR_PAGE, 'w')
+f.write(html)
+f.close()
+
+def __load_error_cb(self, web_view, web_frame, uri, web_error):
+Show Sugar's error page
+
+self.__create_error_page(uri)
+self.load_uri('file://' + DEFAULT_ERROR_PAGE)
+return True
+
 
 class PopupDialog(Gtk.Window):
 def __init__(self):
diff --git a/data/activity-web.png b/data/activity-web.png
new file mode 100644
index 
..d27964350a22e13fef454fb1923a722b5d64a921
GIT binary patch
literal 6064
zcmXw71yoe;)22Zhln{_cQX1*br9)t8kZxEIess5jbVw-OCE(Jrgn-1--7DQK^BY
ze0$E_d+zT0O38wo@XLPQ(X}cn*tjN2?-CRBQABL!U1!4B$H!mGA+$p?S!FK41YK
ze=MtL;Q57{l7R;j5^LP^h0MNGPXqk;+EX6vspD$n1_eAM)LOd=CpTl^suyWv*vV#
z*nT?_qd-C;dk2z}{_tP+VUCfi@$7VPXEPFv9QXZPUw6C(Q~;x-zuU{n(rUooLD=PN
zN?EsX(kvimYPOUEq7AlL%^4mD7~}9e5G9-%HdDb{0(zodl5F22W~usvM6Ue{IM)
zVfO^vxYXR~?N^x=7(ENbekSm^ByxF58G!A{halMsBG9jX49tl3u*nwP?;9eI3x
zi=?U$K)oob7()G;fx2@^1scFzW((E{#=xzxZpoZlprtOgGs=;x6PWtcD$$cQ}
zVzHAy-+xvs!z#A_7m^GP4I(K;TY9lKiZYJkA6Z0x8EK))RLZsBL?O?uHi#qe#3O~
z_G|7Ob=466iT)bi3W^Y=EYG0F{lQRK#hjG_Rd@*w3We{@CJ(;4+c%$8LgDpW(2?
z;#|X9Gg-3ZGFjJjoOLXhW_r(SA{=jW)@@+%*_9US)JNWBe;-bQfW$Nf1%ik#5
zHVd%NlwPAsPgsG6Uv*eB$YgScZnDEpat)njR`m?WcELzDp9gA`#a$fWnxUfY
z5rAJxu8FiiIP;y!m25PCyI~!P7_cqds{*Bh+juOOtyq){{jO0EM4N;pqYjoQEWY
z=ulpbj|}Rrkwsegw`vhAal2;QXKmLl)${10qz}t0DD?j$ks+!M-}4X;okgFqCN-3
z@X))7u6LO}qc}6PF)%QSd=wo5fncGbI4w4PX=xE5B_;kz%+AGC($!}vSRA%q|}@
zZ?DRRdr$P=EcfST@cXuG=~a|3)Touw}j`8Z5I?4hD*^(FJSLT3Xe90%EYdA%nc
zanvy}QKKb9GIw(NoSRGC($a#35mx8ho8C2s2ir-|4I7U62B_hK1VuUUSVtvem-(y
zLR*ZQ0IA#ju@?3pRn+5gU`T!V$^|W$$4MDeQUjG)nt*gwPij$JXBTdW5k#y$mYY{
z^x~i}Qa66p%|G(8tE5Yv`OwPBNfWq+TESUvMv+mF3k2C?Ag0gZ`+~izhZtm!Q
zO=tY-vDw*OLD+EYpcDZV_d{UJdgUZb7%b~Ku;vtr1OLgVrH#l^+i1_mH|``y@=
zbx-%(lK$r-f*W4vXJ_OT6xuB_`J|uTpl-wtu42srDpjG5;Y;J;-5d0)6zwWas3
zxZMXq48t*HfW%wHQBC;MFmI@8#v#d1Jpeo*I1;43SfF4w=FL4P7CgJcOogpX
zbl1nL+oziY`P;8ZNg;bvdpHH=+)9~4C3PA`CjQf1Z_a{mK=atNlq!Xd=FUp~m!k
zXlSEx*0i9d#aEXJV2GMocB)pRuv=5iVXR@U}!ucEN9F#2f!@DMRmHO(+8k(aQy
z=V0o0C{SNtFXybdj{a!Xd7eS|Qoc4SjNsET7d!iAPXx{u0#W5Vaf_L=6@OiJxod
zW@BS(_?McRDzB#YWlm#!VPPl?)6p*$cq34^brfss_WFB3$%w@g{3bk1)OeenW
zQUrJ2Xl2K1JibU`})hnM949wqw+$f%Ef20+NzuqcAKqZdy5n-{W#PzyGorD
zOJLL5rNe7u9KK|sER_`Xnrv_tQ0R{2M11^#!x9~F$=m1d8qBmJ^rN`aL63dNC
zAauxUY7Fm@JQ?EBu_M=qoW%`-9msZIYjPc?R93Pwauwr~uv}nKUBgFmfxzlP#
zz_O#FqN2Tv3u$85FYbCZTmLw45=go{bTZ^BI4umF)%SxtCu?hM7PKCY!vkMV1#|
z7}r_nN2Jluxom2TyOENRkhuT-^O{MA96JK)d0WtM6mU^q@-_BU$$6rDh9CX
zVt2BzWcagLKtTH$1ipU0k*`(#(K6u2^=%VCjw34PDJ^a`T=3tVm{jQ#=jaGPIeNV
zhP%piN`4QjHO|8u8w8$+0NvQ$?*vY^j+@Hrq*~j8$Yl14!z?|bLx#I5h+XXJ|hz
zN;f4|YXLNG4lw$w7O);cHur0+PSH;dU;|;VgNVA0G3C~t;{XkC+o1biwTu{Kc^LV
zjA87n?onoFGPf

Re: [Sugar-devel] [PATCH Browse] Error page SL #3500

2012-09-18 Thread Manuel Kaufmann
On Tue, Sep 18, 2012 at 1:55 PM, Manuel Kaufmann humi...@gmail.com wrote:
 This patch contains a HTML template (error_page.tmpl) that is used to
 generate the error page with the correct language.

Please, comments and suggestions are welcomed here. I didn't find an
existent way (inside Sugar) to translate html content, so I decide to
make it by myself.

I created a file called error_page.tmpl that contains the html
structure of the page with some placeholders to put the translated
strings (those placeholders are substituted with the % operator) and a
new html file is create: error_page.html with the correct strings
and url to try again. Then, this file is used to tell WekKit to load
that file as an uri:

  self.load_uri('file://' + DEFAULT_ERROR_PAGE)

That file is generated every time that the web page can't be reached
for any reason.

See you,

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Error page SL #3500

2012-09-18 Thread Manuel Kaufmann
On Tue, Sep 18, 2012 at 2:54 PM, Daniel Narvaez dwnarv...@gmail.com wrote:
 Oh cool, load_alternate_string definitely looks like the way to go.
 (it doesn't break history etc).

Yeah!

http://webkitgtk.org/reference/webkitgtk/stable/webkitgtk-webkitwebview.html#WebKitWebView--load-status

Thanks, I will patch my patch :) , I will send it again :)

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Error page SL #3500

2012-09-18 Thread Manuel Kaufmann
On Tue, Sep 18, 2012 at 2:21 PM, Daniel Narvaez dwnarv...@gmail.com wrote:
 Perhaps you could use the data protocol to avoid the temporary file

 http://www.ietf.org/rfc/rfc2397.txt

I used this to put the images inside the html-string.

img id=browse-logo src=data:image/png;base64,iVBO (...) /img

Thanks!

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Cancel a download if space is very tight SL #394

2012-09-17 Thread Manuel Kaufmann
It checks if there will be more than MIN_DISKFREE_AFTER_DOWNLOAD (20Mb)
after downloading the file. If not, Browse will cancel the download
process before starting it and an Alert will be shown to the user to
inform this situation.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 downloadmanager.py | 29 +++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/downloadmanager.py b/downloadmanager.py
index 9950c16..b3d4feb 100644
--- a/downloadmanager.py
+++ b/downloadmanager.py
@@ -35,6 +35,8 @@ DS_DBUS_SERVICE = 'org.laptop.sugar.DataStore'
 DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore'
 DS_DBUS_PATH = '/org/laptop/sugar/DataStore'
 
+MIN_DISKFREE_AFTER_DOWNLOAD = 20 * 1024 * 1024
+
 _active_downloads = []
 _dest_to_window = {}
 
@@ -55,6 +57,11 @@ def remove_all_downloads():
 download.cleanup()
 
 
+def free_space(path):
+s = os.statvfs(path)
+return s.f_bavail * s.f_frsize
+
+
 class Download(object):
 def __init__(self, download, browser):
 self._download = download
@@ -84,8 +91,26 @@ class Download(object):
 os.close(fd)
 logging.debug('Download destination path: %s' % self._dest_path)
 
-self._download.set_destination_uri('file://' + self._dest_path)
-self._download.start()
+# Check free space and if the downloaded file plus an extra
+# space will fit on the disk. If not, cancel the download.
+total_size = self._download.get_total_size()
+logging.debug('Total size of the file: %s', total_size)
+if free_space('/') - total_size  MIN_DISKFREE_AFTER_DOWNLOAD:
+logging.debug('Download canceled because of Disk Space')
+self._canceled_alert = Alert()
+self._canceled_alert.props.title = _('Download canceled '
+  'because of Disk Space')
+self._canceled_alert.props.msg = \
+_('%s' % self._download.get_suggested_filename())
+ok_icon = Icon(icon_name='dialog-ok')
+self._canceled_alert.add_button(Gtk.ResponseType.OK,
+ _('Ok'), ok_icon)
+ok_icon.show()
+self._canceled_alert.connect('response', self.__stop_response_cb)
+self._activity.add_alert(self._canceled_alert)
+else:
+self._download.set_destination_uri('file://' + self._dest_path)
+self._download.start()
 
 def __progress_change_cb(self, download, something):
 progress = self._download.get_progress()
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH sugar 1/2] ModalAlert ported to Gtk3

2012-09-17 Thread Manuel Kaufmann
Gtk.VBox.pack_start() and Gtk.Alignment.new() fixed to run over Gtk3

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 src/jarabe/journal/modalalert.py | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/jarabe/journal/modalalert.py b/src/jarabe/journal/modalalert.py
index 36f076e..186fd1a 100644
--- a/src/jarabe/journal/modalalert.py
+++ b/src/jarabe/journal/modalalert.py
@@ -56,25 +56,27 @@ class ModalAlert(Gtk.Window):
 icon = Icon(icon_name='activity-journal',
 pixel_size=style.XLARGE_ICON_SIZE,
 xo_color=color)
-self._vbox.pack_start(icon, False)
+self._vbox.pack_start(icon, expand=False, fill=False, padding=0)
 icon.show()
 
 self._title = Gtk.Label()
 self._title.modify_fg(Gtk.StateType.NORMAL,
   style.COLOR_WHITE.get_gdk_color())
 self._title.set_markup('b%s/b' % _('Your Journal is full'))
-self._vbox.pack_start(self._title, False)
+self._vbox.pack_start(self._title, expand=False, fill=False, padding=0)
 self._title.show()
 
 self._message = Gtk.Label(label=_('Please delete some old Journal'
 ' entries to make space for new ones.'))
 self._message.modify_fg(Gtk.StateType.NORMAL,
   style.COLOR_WHITE.get_gdk_color())
-self._vbox.pack_start(self._message, False)
+self._vbox.pack_start(self._message, expand=False,
+  fill=False, padding=0)
 self._message.show()
 
-alignment = Gtk.Alignment.new(xalign=0.5, yalign=0.5)
-self._vbox.pack_start(alignment, False, True, 0)
+alignment = Gtk.Alignment.new(xalign=0.5, yalign=0.5,
+  xscale=0.0, yscale=0.0)
+self._vbox.pack_start(alignment, expand=False, fill=True, padding=0)
 alignment.show()
 
 self._show_journal = Gtk.Button()
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] Adventures in the land of ENOSPC

2012-09-13 Thread Manuel Kaufmann
On Thu, Sep 13, 2012 at 4:47 PM, Martin Langhoff
martin.langh...@gmail.com wrote:
 Manuel Kaufmann has been looking at SL#394, and looking at the bug
 report, it struck me that it was reported backwards. I would have
 written: I filled up my disk and it knocked the system out, Sugar
 would not start again, etc. Oh, btw, it was with Browse.

There is a ticket already reported (that I found today) mentioning
this situation:

 * http://dev.laptop.org/ticket/10481

In fact, it seems that you passed over it some months ago. We were
discussing about it with Gonzalo today in the morning.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Cancel a download if space is very tight SL #394

2012-09-12 Thread Manuel Kaufmann
On Tue, Sep 11, 2012 at 10:27 PM, Martin Langhoff
martin.langh...@gmail.com wrote:
  - During the webkit download -- most probable stage where you'll hit
 it. How does Webkit behave? Does Browse need to do anything?

I'm attaching an example that downloads a file with WebKit.

I tried it setting up a tmpfs with 1Mb as you suggested and aftert
that, I ran this script. WebKit tells us about the insufficient space
on the disk by raising the error signal. I catched it and I printed
the arguments of the signal:

'Error downloading URI code %s, detail %s: %s' % (err_code, err_detail, reason)

===  Error downloading URI code 0, detail 1: Error writing to file:
No space left on device

err_detail: 
http://webkitgtk.org/reference/webkitgtk/stable/webkitgtk-webkitdownload.html#WebKitDownloadError

 * WEBKIT_DOWNLOAD_ERROR_DESTINATION - The download failed due to
disk write failure

I will keep taking a look at the other possibilities.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/


download_file_with_webkit.py
Description: Binary data
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Cancel a download if space is very tight SL #394

2012-09-12 Thread Manuel Kaufmann
On Tue, Sep 11, 2012 at 10:27 PM, Martin Langhoff
martin.langh...@gmail.com wrote:
  - During datastore.write() -- I truly believe that the
 datastore.write() call doesn't literally make a copy of the file --
 should just create/update the hardlink and associated metadata
 (including progress bar). It is not very likely that we'll run out of
 space during this call, but it should be handled, I believe.

OK. I was taking a look at the datastore source code and I understood
that the file is copied, using the traditional way and when the copy
finishes the source file is unlinked.

Here are the source files that I took a look and how I found this:

sugar-toolkit-gtk3/src/sugar3/datastore/datastore.py L340 (def write)
   --- L316 (def _update_ds_entry)
   --- L45 (def _get_data_store)

sugar-datastore/src/carquinyol/datastore.py L242 (def update)

src/carquinyol/filestore.py L34 (def store)
   --- L215 (def start)
   --- L181 (def _copy_block)

Please, let me know if I am wrong.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Cancel a download if space is very tight SL #394

2012-09-12 Thread Manuel Kaufmann
On Wed, Sep 12, 2012 at 9:21 AM, Martin Langhoff
martin.langh...@gmail.com wrote:
 That's very good handling on webkit's side. And does it remove the
 file? IOWs, when you get the signal, what do you see in the tmpfs? Is
 there a file filling it, or has the file been removed?

Oh, sorry. I forgot to mention this. The file is still there with the
size that webkit could get (in my case 904kb). Webkit didn't remove
it.

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Cancel a download if space is very tight SL #394

2012-09-11 Thread Manuel Kaufmann
On Mon, Sep 10, 2012 at 9:49 PM, Martin Langhoff
martin.langh...@gmail.com wrote:
 Here, get the content-length... and compare with the free bytes (plus
 some padding, say, 15%). Maybe we still want to preserve a minimum
 disk space. For example: don't let a download put you below 50MB or
 10MB free -- in that case do the multiplication in a constant
 definition.

 MIN_DISKFREE_AFTER_DOWNLOAD = 50 * 1024 * 1024

If we are going to use this approach, I have to change the logic about
where I should check this. Now, I'm checking this every time that
the progress[1] changes but I think we should use total-size[2] to
get the Content-Length in Download.__init__() and decide there what
to do. I mean, decide whether cancel or not before starting the
download.

What do you say?

[1] 
http://webkitgtk.org/reference/webkitgtk/stable/webkitgtk-webkitdownload.html#WebKitDownload--progress
[2] 
http://webkitgtk.org/reference/webkitgtk/stable/webkitgtk-webkitdownload.html#WebKitDownload--total-size

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Cancel a download if space is very tight SL #394

2012-09-11 Thread Manuel Kaufmann
It checks if there will be more than MIN_DISKFREE_AFTER_DOWNLOAD (50Mb)
after downloading the file. If not, Browse will cancel the download
process before starting it and an Alert will be shown to the user to
inform this situation.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 downloadmanager.py | 28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/downloadmanager.py b/downloadmanager.py
index 9950c16..0240941 100644
--- a/downloadmanager.py
+++ b/downloadmanager.py
@@ -35,6 +35,8 @@ DS_DBUS_SERVICE = 'org.laptop.sugar.DataStore'
 DS_DBUS_INTERFACE = 'org.laptop.sugar.DataStore'
 DS_DBUS_PATH = '/org/laptop/sugar/DataStore'
 
+MIN_DISKFREE_AFTER_DOWNLOAD = 50 * 1024 * 1024
+
 _active_downloads = []
 _dest_to_window = {}
 
@@ -55,6 +57,11 @@ def remove_all_downloads():
 download.cleanup()
 
 
+def free_space(path):
+s = os.statvfs(path)
+return s.f_bavail * s.f_frsize
+
+
 class Download(object):
 def __init__(self, download, browser):
 self._download = download
@@ -84,8 +91,25 @@ class Download(object):
 os.close(fd)
 logging.debug('Download destination path: %s' % self._dest_path)
 
-self._download.set_destination_uri('file://' + self._dest_path)
-self._download.start()
+# Check free space and if the downloaded file plus an extra
+# space will fit on the disk. If not, cancel the download.
+total_size = self._download.get_total_size()
+logging.debug('Total size of the file: %s', total_size)
+if free_space('/') - total_size  MIN_DISKFREE_AFTER_DOWNLOAD:
+logging.debug('Download canceled because of Disk Space')
+self._canceled_alert = Alert()
+self._canceled_alert.props.title = _('Download canceled '
+  'because of Disk Space')
+self._canceled_alert.props.msg = \
+_('%s' % self._download.get_suggested_filename())
+ok_icon = Icon(icon_name='dialog-ok')
+self._canceled_alert.add_button(Gtk.ResponseType.OK,
+ _('Ok'), ok_icon)
+ok_icon.show()
+self._canceled_alert.connect('response', self.__stop_response_cb)
+self._activity.add_alert(self._canceled_alert)
+else:
+self._download.set_destination_uri('file://' + self._dest_path)
 
 def __progress_change_cb(self, download, something):
 progress = self._download.get_progress()
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Cancel a download if space is very tight SL #394

2012-09-11 Thread Manuel Kaufmann
On Tue, Sep 11, 2012 at 8:03 PM, Gonzalo Odiard gonz...@laptop.org wrote:

 Can you try almost fill the xo and copy a big file with the journal from a
 pendrive?
 I remember a big message in the screen when this happen, and will point you
 to the code.

Yes, I've already try that and I commented what I get here:

 * http://bugs.sugarlabs.org/ticket/394#comment:7

I didn't find an exception raised by Sugar when this happens. The
check is done[1] when a new Model is created[2] or updated[3] inside
the Journal, and if there are less than 50Mb a ModelAlert is shown but
no exception is raised. Maybe we can write the portion of code here to
raise that exception before show the ModelAlert and if it's not
managed we can call the ModelAlert.

[1] sugar/src/jarabe/journal/journalactivity.py L336
[2] sugar/src/jarabe/journal/journalactivity.py L274
[3] sugar/src/jarabe/journal/journalactivity.py L265

 The browser is downloading the file in a temporary place and later moving to
 the journal or
 is creating a object in the journal while downloading?

The file is downloaded in a temporary directory and then copied to the Journal:

 temp_path = os.path.join(activity.get_activity_root(), 'instance')
 fd, self._dest_path = tempfile.mkstemp(dir=temp_path,
suffix=download.get_suggested_filename(),
prefix='tmp')

That is something like (I guess):
~/.sugar/default/org.laptop.WebActivity/instance

When the download finishes:

(...)
self.dl_jobject = datastore.create()
(...)
datastore.write(self.dl_jobject,
transfer_ownership=True,
reply_handler=self.__internal_save_cb,
error_handler=self.__internal_error_cb,
timeout=360)
(...)

 Is important to know if the control in the journal will work or not.

but, we are updating a Journal entry every time that the progress of
the download changes to show the progress bar in the Journal:
browse/downloadmanager.py L90

def __progress_change_cb(self, download, something):
progress = self._download.get_progress()
self.dl_jobject.metadata['progress'] = str(int(progress * 100))
datastore.write(self.dl_jobject)

so, we are updating a model inside the datastore... If we had the
ENOSPC exception we could manage it there. I insist this goes in a
different ticket and a different patch.

See you,

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


Re: [Sugar-devel] [PATCH Browse] Cancel a download if space is very tight SL #394

2012-09-11 Thread Manuel Kaufmann
On Tue, Sep 11, 2012 at 8:50 PM, Martin Langhoff
martin.langh...@gmail.com wrote:
 mkdir /tmp/foo
 sudo mount -t tmpfs -o size=1M none /tmp/foo

 Now write there to a file in /tmp/foo to see what happens, exactly.

This is what I got:

[olpc@xo-07-30-50 ~]$ mkdir /tmp/foo
[olpc@xo-07-30-50 ~]$ sudo mount -t tmpfs -o size=1M none /tmp/foo
[olpc@xo-07-30-50 ~]$ python
Python 2.7.3 (default, Apr 30 2012, 23:07:00)
[GCC 4.7.0 20120416 (Red Hat 4.7.0-2)] on linux2
Type help, copyright, credits or license for more information.
 f = open('/tmp/foo/cl.txt', 'w')
 f.write('w' * 200 ** 2)
(...)
 f.write('w' * 2000)
Traceback (most recent call last):
  File stdin, line 1, in module
IOError: [Errno 28] No space left on device


So, we should handle this exception inside the Journal Activity, when
an object is created or updated. How is the correct way that I have to
follow to inform about this exception to the other activities?

-- 
Kaufmann Manuel
Blog: http://humitos.wordpress.com/
Porfolio: http://fotos.mkaufmann.com.ar/
PyAr: http://www.python.com.ar/
___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Busy indication SL #851

2012-09-10 Thread Manuel Kaufmann
Show WATCH Cursor when the page is loading and LEFT_PTR when the
load finishes.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 browser.py | 4 
 1 file changed, 4 insertions(+)

diff --git a/browser.py b/browser.py
index 7379d2b..90378cb 100644
--- a/browser.py
+++ b/browser.py
@@ -404,14 +404,18 @@ class TabLabel(Gtk.HBox):
 def __load_status_changed_cb(self, widget, param):
 status = widget.get_load_status()
 if status == WebKit.LoadStatus.FAILED:
+self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.LEFT_PTR))
 self._label.set_text(self._title)
 elif WebKit.LoadStatus.PROVISIONAL = status \
  WebKit.LoadStatus.FINISHED:
+self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
 self._label.set_text(_('Loading...'))
 elif status == WebKit.LoadStatus.FINISHED:
 if widget.props.title == None:
 self._label.set_text(_('Untitled'))
 self._title = _('Untitled')
+self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.LEFT_PTR))
+
 
 
 class Browser(WebKit.WebView):
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Don't call .start after .set_destination_uri SL #3878

2012-09-10 Thread Manuel Kaufmann
Do not call WebKitDownload.start after .set_destination_uri because it
is no needed. The download will start automatically after
.set_destination_uri.

http://webkitgtk.org/reference/webkitgtk/stable/webkitgtk-webkitwebview.html#WebKitWebView-download-requested

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 downloadmanager.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/downloadmanager.py b/downloadmanager.py
index 9950c16..ab9fec2 100644
--- a/downloadmanager.py
+++ b/downloadmanager.py
@@ -85,7 +85,6 @@ class Download(object):
 logging.debug('Download destination path: %s' % self._dest_path)
 
 self._download.set_destination_uri('file://' + self._dest_path)
-self._download.start()
 
 def __progress_change_cb(self, download, something):
 progress = self._download.get_progress()
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH Browse] Cancel a download if space is very tight SL #394

2012-09-10 Thread Manuel Kaufmann
If there are less than 50Mb free on the Hard Disk the downloading
process is canceled and this is informed to the user via an Alert.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 downloadmanager.py | 29 +++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/downloadmanager.py b/downloadmanager.py
index ab9fec2..749eb38 100644
--- a/downloadmanager.py
+++ b/downloadmanager.py
@@ -55,6 +55,13 @@ def remove_all_downloads():
 download.cleanup()
 
 
+# 
http://stackoverflow.com/questions/787776/find-free-disk-space-in-python-on-os-x
+def free_space(path):
+global k
+s = os.statvfs(path)
+return (s.f_bavail * s.f_frsize) / 1024 / 1024
+
+
 class Download(object):
 def __init__(self, download, browser):
 self._download = download
@@ -88,8 +95,26 @@ class Download(object):
 
 def __progress_change_cb(self, download, something):
 progress = self._download.get_progress()
-self.dl_jobject.metadata['progress'] = str(int(progress * 100))
-datastore.write(self.dl_jobject)
+
+# Check free space and if there is less than 50Mb, then cancel
+# the download
+if free_space('/')  50:
+self.cancel()
+
+self._canceled_alert = Alert()
+self._canceled_alert.props.title = _('Download canceled '
+  'because of Disk Space')
+self._canceled_alert.props.msg = \
+_('%s' % self._download.get_suggested_filename())
+ok_icon = Icon(icon_name='dialog-ok')
+self._canceled_alert.add_button(Gtk.ResponseType.OK,
+ _('Ok'), ok_icon)
+ok_icon.show()
+self._canceled_alert.connect('response', self.__stop_response_cb)
+self._activity.add_alert(self._canceled_alert)
+else:
+self.dl_jobject.metadata['progress'] = str(int(progress * 100))
+datastore.write(self.dl_jobject)
 
 def __state_change_cb(self, download, gparamspec):
 state = self._download.get_status()
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


[Sugar-devel] [PATCH [v2] Browse] Cancel a download if space is very tight SL #394

2012-09-10 Thread Manuel Kaufmann
If there are less than 50Mb free on the Hard Disk the downloading
process is canceled and this is informed to the user via an Alert.

Signed-off-by: Manuel Kaufmann humi...@gmail.com
---
 downloadmanager.py | 28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/downloadmanager.py b/downloadmanager.py
index ab9fec2..b63f0fe 100644
--- a/downloadmanager.py
+++ b/downloadmanager.py
@@ -55,6 +55,12 @@ def remove_all_downloads():
 download.cleanup()
 
 
+# 
http://stackoverflow.com/questions/787776/find-free-disk-space-in-python-on-os-x
+def free_space(path):
+s = os.statvfs(path)
+return (s.f_bavail * s.f_frsize) / 1024 / 1024
+
+
 class Download(object):
 def __init__(self, download, browser):
 self._download = download
@@ -88,8 +94,26 @@ class Download(object):
 
 def __progress_change_cb(self, download, something):
 progress = self._download.get_progress()
-self.dl_jobject.metadata['progress'] = str(int(progress * 100))
-datastore.write(self.dl_jobject)
+
+# Check free space and if there is less than 50Mb, then cancel
+# the download
+if free_space('/')  50:
+self.cancel()
+
+self._canceled_alert = Alert()
+self._canceled_alert.props.title = _('Download canceled '
+  'because of Disk Space')
+self._canceled_alert.props.msg = \
+_('%s' % self._download.get_suggested_filename())
+ok_icon = Icon(icon_name='dialog-ok')
+self._canceled_alert.add_button(Gtk.ResponseType.OK,
+ _('Ok'), ok_icon)
+ok_icon.show()
+self._canceled_alert.connect('response', self.__stop_response_cb)
+self._activity.add_alert(self._canceled_alert)
+else:
+self.dl_jobject.metadata['progress'] = str(int(progress * 100))
+datastore.write(self.dl_jobject)
 
 def __state_change_cb(self, download, gparamspec):
 state = self._download.get_status()
-- 
1.7.11.4

___
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel


  1   2   3   4   5   >