diff options
Diffstat (limited to 'pysamples')
-rw-r--r-- | pysamples/COPYING | 21 | ||||
-rw-r--r-- | pysamples/copy_from_heap.py | 37 | ||||
-rw-r--r-- | pysamples/dotted_line.py | 136 | ||||
-rw-r--r-- | pysamples/grecord.py | 227 | ||||
-rw-r--r-- | pysamples/load_block.py | 78 | ||||
-rw-r--r-- | pysamples/load_journal_entry_to_heap.py | 39 | ||||
-rw-r--r-- | pysamples/paste_to_heap.py | 36 | ||||
-rw-r--r-- | pysamples/push_mouse_event.py | 50 | ||||
-rw-r--r-- | pysamples/push_time.py | 40 | ||||
-rw-r--r-- | pysamples/save_heap_to_journal_entry.py | 44 | ||||
-rw-r--r-- | pysamples/set_rgb.py | 61 | ||||
-rw-r--r-- | pysamples/sinewave.py | 36 | ||||
-rw-r--r-- | pysamples/speak.py | 57 | ||||
-rw-r--r-- | pysamples/svg_end_group.py | 17 | ||||
-rw-r--r-- | pysamples/svg_start_group.py | 17 | ||||
-rw-r--r-- | pysamples/uturn.py | 35 |
16 files changed, 608 insertions, 323 deletions
diff --git a/pysamples/COPYING b/pysamples/COPYING new file mode 100644 index 0000000..9cdf1e6 --- /dev/null +++ b/pysamples/COPYING @@ -0,0 +1,21 @@ +Copyright (c) 2008-11, Walter Bender +Copyright (c) 2008-11, TOny Forster + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/pysamples/copy_from_heap.py b/pysamples/copy_from_heap.py index 8483fde..fbca999 100644 --- a/pysamples/copy_from_heap.py +++ b/pysamples/copy_from_heap.py @@ -1,35 +1,16 @@ -#Copyright (c) 2010, Walter Bender, Tony Forster +#Copyright (c) 2010-11, Walter Bender, Tony Forster -#Permission is hereby granted, free of charge, to any person obtaining a copy -#of this software and associated documentation files (the "Software"), to deal -#in the Software without restriction, including without limitation the rights -#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#copies of the Software, and to permit persons to whom the Software is -#furnished to do so, subject to the following conditions: +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected. -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. +# Usage: Import this code into a Python (user-definable) block; when +# this code is run, the FILO heap will be copied to the clipboard. -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#THE SOFTWARE. -# This procedure is invoked when the user-definable block on the "extras" -# palette is selected. - -def myblock(lc, x): - - ########################################################################### - # - # Copy heap to clipboard - # - ########################################################################### +def myblock(tw, x): # second argument is ignored + ''' Copy heap to clipboard ''' from gtk import Clipboard - from tautils import data_to_string + from TurtleArt.tautils import data_to_string - Clipboard().set_text(data_to_string(lc.heap)) + Clipboard().set_text(data_to_string(tw.lc.heap)) diff --git a/pysamples/dotted_line.py b/pysamples/dotted_line.py index 9db7f9d..febd409 100644 --- a/pysamples/dotted_line.py +++ b/pysamples/dotted_line.py @@ -1,42 +1,23 @@ -#Copyright (c) 2009-10, Walter Bender +#Copyright (c) 2009-11, Walter Bender -#Permission is hereby granted, free of charge, to any person obtaining a copy -#of this software and associated documentation files (the "Software"), to deal -#in the Software without restriction, including without limitation the rights -#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#copies of the Software, and to permit persons to whom the Software is -#furnished to do so, subject to the following conditions: - -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. - -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#THE SOFTWARE. - -# # This procedure is invoked when the user-definable block on the "extras" # palette is selected. Some examples of how to use this block are included # below. Try uncommenting an example or write your own Python code. -# +# # To uncomment code, remove the '# ' in the Python code. Take care to preserve # the proper indentations. # -# +# # NOTES: -# +# # Turtle Art is created in object oriented Python code. This is based # around the definition of classes and the creation of object(s) which # are instance(s) of that class. These objects then have properties and # methods which are defined by their class. -# +# # See http://docs.python.org/tutorial/classes.html for a description of # classes in Python. -# +# # Class Defined in Instance Created in # TurtleArtWindow tawindow.py tw TurtleArtActivity.py # LogoCode talogo.py lc tawindow.py @@ -44,72 +25,72 @@ # Turtles, Turtle taturtle.py turtles tawindow.py, # tacanvas.py # Blocks, Block tablock.py block_list tawindow.py -# -# +# +# # Class TurtleArtWindow -- useful properties and methods (from within -# tamyblock.py, lc.tw is the class instance) -# +# tamyblock.py, tw is the class instance) +# # Methods and data attributes Example -# set_fullscreen(self) lc.tw.set_fullscreen() +# set_fullscreen(self) tw.set_fullscreen() # Note: Hides the Sugar toolbar -# set_cartesian(self, flag) lc.tw.set_cartesian(True) +# set_cartesian(self, flag) tw.set_cartesian(True) # Note: True will make the overlay visible; # False will make it invisible -# set_polar(self, flag) lc.tw.set_polar(True) +# set_polar(self, flag) tw.set_polar(True) # Note: True will make the overlay visible; # False will make it invisible -# hideshow_button(self, flag) lc.tw.hideshow_button() +# hideshow_button(self, flag) tw.hideshow_button() # Note: Toggles visibility of blocks and palettes -# self.active_turtle lc.tw.active_turtle +# self.active_turtle tw.active_turtle # Note: The active turtle instance -# -# +# +# # Class TurtleGraphics -- useful properties and methods (from within -# tamyblock.py, lc.tw.canvas is the class instance) -# +# tamyblock.py, tw.canvas is the class instance) +# # Methods and data attributes Example -# clearscreen(self) lc.tw.canvas.clearscreen() +# clearscreen(self) tw.canvas.clearscreen() # Note: Clears the screen and resets all turtle and # pen attributes to default values -# setpen(self, flag) lc.tw.canvas.setpen(True) +# setpen(self, flag) tw.canvas.setpen(True) # Note: True will set the pen "down", enabling drawing; # False will set the pen "up" -# forward(self, n) lc.tw.canvas.forward(100) +# forward(self, n) tw.canvas.forward(100) # Note: Move the turtle forward 100 units -# arc(self, a, r) lc.tw.canvas.arc(120, 50) +# arc(self, a, r) tw.canvas.arc(120, 50) # Note: Move the turtle along an arc of 120 degrees # (clockwise) and radius of 50 units -# setheading(self, a) lc.tw.canvas.setheading(180) +# setheading(self, a) tw.canvas.setheading(180) # Note: Set the turtle heading to 180 # (towards the bottom of the screen) -# self.heading lc.tw.canvas.heading +# self.heading tw.canvas.heading # Note: The current heading -# setpensize(self, n) lc.tw.canvas.setpensize(25) +# setpensize(self, n) tw.canvas.setpensize(25) # Note: Set the turtle pensize to 25 units -# self.pensize lc.tw.canvas.pensize +# self.pensize tw.canvas.pensize # Note: The current pensize -# setcolor(self, c) lc.tw.canvas.color(70) +# setcolor(self, c) tw.canvas.color(70) # Note: Set the pen color to 70 (blue) -# self.color lc.tw.canvas.color +# self.color tw.canvas.color # Note: The current pen color -# setshade(self, s) lc.tw.canvas.shade(50) +# setshade(self, s) tw.canvas.shade(50) # Note: Set the pen shade to 50 -# self.shade lc.tw.canvas.shade +# self.shade tw.canvas.shade # Note: The current pen shade -# fillscreen(self, c, s) lc.tw.canvas.fillscreen(70, 90) +# fillscreen(self, c, s) tw.canvas.fillscreen(70, 90) # Note: Fill the screen with color 70, shade 90 (light blue) -# setxy(self, x, y) lc.tw.canvas.setxy(100,100) +# setxy(self, x, y) tw.canvas.setxy(100,100) # Note: Move the turtle to position (100, 100) -# self.xcor lc.tw.canvas.xcor +# self.xcor tw.canvas.xcor # Note: The current x coordinate of the turtle # (scaled to current units) -# self.ycor lc.tw.canvas.ycor +# self.ycor tw.canvas.ycor # Note: The current y coordinate of the turtle # (scaled to current units) -# self.set_turtle(name) lc.tw.canvas.set_turtle(1) +# self.set_turtle(name) tw.canvas.set_turtle(1) # Note: Set the current turtle to turtle '1' -# -# +# +# # Other useful Python functions # Module Example # from math import pow pow(2,3) returns 2 to the 3rd power @@ -118,34 +99,35 @@ # Note: See http://docs.python.org/library/math.html # from time import localtime localtime().tm_hour returns the current hour # Note: See http://docs.python.org/library/time.html -# lc.heap.append(data) adds data to the heap +# tw.lc.heap.append(data) adds data to the heap # Note: See http://docs.python.org/tutorial/datastructures.html -# data = lc.heap.pop(-1) pops data off the heap +# data = tw.lc.heap.pop(-1) pops data off the heap # Note: See http://docs.python.org/tutorial/datastructures.html # -def myblock(lc, x): +# Usage: Import this code into a Python (user-definable) block; when +# this code is run, the turtle will draw a dotted line of the length +# of the numeric argument block docked to the Python block. + - ########################################################################### - # - # Draw a dotted line of length x. - # - ########################################################################### +def myblock(tw, line_length): + ''' Draw a dotted line of length line_length. ''' - try: # make sure x is a number - x = float(x) + try: # make sure line_length is a number + line_length = float(line_length) except ValueError: return - if lc.tw.canvas.pendown: + if tw.canvas.pendown: dist = 0 - while dist+lc.tw.canvas.pensize < x: # repeat drawing dots - lc.tw.canvas.setpen(True) - lc.tw.canvas.forward(1) - lc.tw.canvas.setpen(False) - lc.tw.canvas.forward((lc.tw.canvas.pensize*2)-1) - dist += (lc.tw.canvas.pensize*2) - lc.tw.canvas.forward(x-dist) # make sure we have moved exactly x - lc.tw.canvas.setpen(True) + while dist + tw.canvas.pensize < line_length: # repeat drawing dots + tw.canvas.setpen(True) + tw.canvas.forward(1) + tw.canvas.setpen(False) + tw.canvas.forward((tw.canvas.pensize * 2) - 1) + dist += (tw.canvas.pensize * 2) + # make sure we have moved exactly line_length + tw.canvas.forward(line_length - dist) + tw.canvas.setpen(True) else: - lc.tw.canvas.forward(x) + tw.canvas.forward(line_length) return diff --git a/pysamples/grecord.py b/pysamples/grecord.py new file mode 100644 index 0000000..84b1a5c --- /dev/null +++ b/pysamples/grecord.py @@ -0,0 +1,227 @@ +#Copyright (c) 2008, Media Modifications Ltd. +#Copyright (c) 2011, Walter Bender + +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected. + +# Usage: Import this code into a Python (user-definable) block; Pass +# it 'start' to start recording; 'stop' to stop recording; 'play' to +# play back your recording; or 'save' to save your recording to the +# Sugar Journal. + + +def myblock(tw, arg): + ''' Record and playback a sound (Sugar only) ''' + import os + import time + + import gtk + import gst + + import gobject + gobject.threads_init() + + from TurtleArt.tautils import get_path + from TurtleArt.tagplay import play_audio_from_file + from sugar.datastore import datastore + from sugar import profile + + from gettext import gettext as _ + + class Grecord: + ''' A class for creating a gstreamer session for recording audio. ''' + + def __init__(self, tw): + ''' Set up the stream. We save to a raw .wav file and then + convert the sound to .ogg for saving. ''' + datapath = get_path(tw.parent, 'instance') + self.capture_file = os.path.join(datapath, 'output.wav') + self.save_file = os.path.join(datapath, 'output.ogg') + self._eos_cb = None + + self._can_limit_framerate = False + self._recording = False + + self._audio_transcode_handler = None + self._transcode_id = None + + self._pipeline = gst.Pipeline("Record") + self._create_audiobin() + self._pipeline.add(self._audiobin) + + bus = self._pipeline.get_bus() + bus.add_signal_watch() + bus.connect('message', self._bus_message_handler) + + def _create_audiobin(self): + ''' Assemble all the pieces we need. ''' + src = gst.element_factory_make("alsasrc", "absrc") + + # attempt to use direct access to the 0,0 device, solving some A/V + # sync issues + src.set_property("device", "plughw:0,0") + hwdev_available = src.set_state(gst.STATE_PAUSED) != \ + gst.STATE_CHANGE_FAILURE + src.set_state(gst.STATE_NULL) + if not hwdev_available: + src.set_property("device", "default") + + srccaps = gst.Caps("audio/x-raw-int,rate=16000,channels=1,depth=16") + + # guarantee perfect stream, important for A/V sync + rate = gst.element_factory_make("audiorate") + + # without a buffer here, gstreamer struggles at the start of the + # recording and then the A/V sync is bad for the whole video + # (possibly a gstreamer/ALSA bug -- even if it gets caught up, it + # should be able to resync without problem) + queue = gst.element_factory_make("queue", "audioqueue") + queue.set_property("leaky", True) # prefer fresh data + queue.set_property("max-size-time", 5000000000) # 5 seconds + queue.set_property("max-size-buffers", 500) + queue.connect("overrun", self._log_queue_overrun) + + enc = gst.element_factory_make("wavenc", "abenc") + + sink = gst.element_factory_make("filesink", "absink") + sink.set_property("location", self.capture_file) + + self._audiobin = gst.Bin("audiobin") + self._audiobin.add(src, rate, queue, enc, sink) + + src.link(rate, srccaps) + gst.element_link_many(rate, queue, enc, sink) + + def _log_queue_overrun(self, queue): + ''' We use a buffer, which may overflow. ''' + cbuffers = queue.get_property("current-level-buffers") + cbytes = queue.get_property("current-level-bytes") + ctime = queue.get_property("current-level-time") + + def is_recording(self): + ''' Are we recording? ''' + return self._recording + + def _get_state(self): + ''' What is the state of our gstreamer pipeline? ''' + return self._pipeline.get_state()[1] + + def start_recording_audio(self): + ''' Start the stream in order to start recording. ''' + if self._get_state() == gst.STATE_PLAYING: + return + self._pipeline.set_state(gst.STATE_PLAYING) + self._recording = True + + def stop_recording_audio(self): + ''' Stop recording and then convert the results into a + .ogg file using a new stream. ''' + self._pipeline.set_state(gst.STATE_NULL) + self._recording = False + + if not os.path.exists(self.capture_file) or \ + os.path.getsize(self.capture_file) <= 0: + return + + # Remove previous transcoding results. + if os.path.exists(self.save_file): + os.remove(self.save_file) + + line = 'filesrc location=' + self.capture_file + ' name=audioFilesrc ! wavparse name=audioWavparse ! audioconvert name=audioAudioconvert ! vorbisenc name=audioVorbisenc ! oggmux name=audioOggmux ! filesink name=audioFilesink' + audioline = gst.parse_launch(line) + + vorbis_enc = audioline.get_by_name('audioVorbisenc') + + audioFilesink = audioline.get_by_name('audioFilesink') + audioFilesink.set_property("location", self.save_file) + + audioBus = audioline.get_bus() + audioBus.add_signal_watch() + self._audio_transcode_handler = audioBus.connect( + 'message', self._onMuxedAudioMessageCb, audioline) + self._transcode_id = gobject.timeout_add( + 200, self._transcodeUpdateCb, audioline) + audioline.set_state(gst.STATE_PLAYING) + + def _transcodeUpdateCb(self, pipe): + ''' Where are we in the transcoding process? ''' + position, duration = self._query_position(pipe) + if position != gst.CLOCK_TIME_NONE: + value = position * 100.0 / duration + value = value/100.0 + return True + + def _query_position(self, pipe): + ''' Where are we in the stream? ''' + try: + position, format = pipe.query_position(gst.FORMAT_TIME) + except: + position = gst.CLOCK_TIME_NONE + + try: + duration, format = pipe.query_duration(gst.FORMAT_TIME) + except: + duration = gst.CLOCK_TIME_NONE + + return (position, duration) + + def _onMuxedAudioMessageCb(self, bus, message, pipe): + ''' Clean up at end of stream.''' + if message.type != gst.MESSAGE_EOS: + return True + + gobject.source_remove(self._audio_transcode_handler) + self._audio_transcode_handler = None + gobject.source_remove(self._transcode_id) + self._transcode_id = None + pipe.set_state(gst.STATE_NULL) + pipe.get_bus().remove_signal_watch() + pipe.get_bus().disable_sync_message_emission() + + os.remove(self.capture_file) + return False + + def _bus_message_handler(self, bus, message): + ''' Handle any messages associated with the stream. ''' + t = message.type + if t == gst.MESSAGE_EOS: + if self._eos_cb: + cb = self._eos_cb + self._eos_cb = None + cb() + elif t == gst.MESSAGE_ERROR: + # TODO: if we come out of suspend/resume with errors, then + # get us back up and running... TODO: handle "No space + # left on the resource.gstfilesink.c" err, debug = + # message.parse_error() + pass + + # We store the audio-record stream instance as tw.grecord so that + # we can use it repeatedly. + if not hasattr(tw, 'grecord'): + tw.grecord = Grecord(tw) + + # Sometime we need to parse multiple arguments, e.g., save, savename + save_name = _('Turtle Art') + ' ' + _('sound') + if type(arg) == type([]): + cmd = arg[0].lower() + if len(arg) > 1: + save_name = str(arg[1]) + else: + cmd = arg.lower() + + if cmd == 'start' or cmd == _('start').lower(): + tw.grecord.start_recording_audio() + elif cmd == 'stop' or cmd == _('stop').lower(): + tw.grecord.stop_recording_audio() + elif cmd == 'play' or cmd == _('play').lower(): + play_audio_from_file(tw.lc, tw.grecord.save_file) + elif cmd == 'save' or cmd == _('save').lower(): + if os.path.exists(tw.grecord.save_file) and tw.running_sugar: + dsobject = datastore.create() + dsobject.metadata['title'] = save_name + dsobject.metadata['icon-color'] = profile.get_color().to_string() + dsobject.metadata['mime_type'] = 'audio/ogg' + dsobject.set_file_path(tw.grecord.save_file) + datastore.write(dsobject) + dsobject.destroy() diff --git a/pysamples/load_block.py b/pysamples/load_block.py new file mode 100644 index 0000000..a457504 --- /dev/null +++ b/pysamples/load_block.py @@ -0,0 +1,78 @@ +#Copyright (c) 2011, Walter Bender + +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected. + +# Usage: Import this code into a Python (user-definable) block; when +# this code is run, the turtle will create a block at the current +# location of the turtle. The first argument to the Python block +# should be a string containing the name of the desired +# block. Arguments to the block can be passed by expanding the Python +# block to include up to two additional arguments. Note that the +# turtle is moved to the bottom of the block after it is loaded in +# order position another block to the bottom of the stack. + +# For example, try the following to place forward 100, right 90 on the canvas: +# start +# Python(forward, 100) <-- Python load_block.py expanded to two arguments +# Python(right, 90) <-- Python load_block.py expanded to two arguments + + +def myblock(tw, blkname): + ''' Load a block on to the canvas ''' + + from TurtleArt.tapalette import block_names, block_primitives, \ + special_names, content_blocks + from TurtleArt.tautils import find_group + + def make_block(tw, name, x, y, defaults): + x_pos = x + 20 + y_pos = y + 20 + tw._new_block(name, x_pos, y_pos, defaults) + + # Find the block we just created and attach it to a stack. + tw.drag_group = None + spr = tw.sprite_list.find_sprite((x_pos, y_pos)) + if spr is not None: + blk = tw.block_list.spr_to_block(spr) + if blk is not None: + tw.drag_group = find_group(blk) + tw._snap_to_dock() + + # Disassociate new block from mouse. + tw.drag_group = None + return blk.height + + def find_block(tw, blkname, x, y, defaults=None): + """ Create a new block. It is a bit more work than just calling + _new_block(). We need to: + (1) translate the label name into the internal block name; + (2) 'dock' the block onto a stack where appropriate; and + (3) disassociate the new block from the mouse. """ + + print blkname + for name in block_names: + # Translate label name into block/prim name. + if blkname in block_names[name]: + if (name in block_primitives and \ + block_primitives[name] == name) or \ + name in content_blocks: + return make_block(tw, name, x, y, defaults) + for name in special_names: + # Translate label name into block/prim name. + if blkname in special_names[name]: + return make_block(tw, name, x, y, defaults) + return -1 + + # Place the block at the active turtle (x, y) and move the turtle + # into position to place the next block in the stack. + x, y = tw.active_turtle.get_xy() + if type(blkname) == type([]): + name = blkname[0] + value = blkname[1:] + dy = int(find_block(tw, name, x, y, value)) + else: + name = blkname + dy = int(find_block(tw, name, x, y)) + + tw.active_turtle.move((x, y - dy)) diff --git a/pysamples/load_journal_entry_to_heap.py b/pysamples/load_journal_entry_to_heap.py index 7416554..3dd3bb5 100644 --- a/pysamples/load_journal_entry_to_heap.py +++ b/pysamples/load_journal_entry_to_heap.py @@ -1,35 +1,18 @@ -#Copyright (c) 2010, Walter Bender, Tony Forster +#Copyright (c) 2010-11, Walter Bender, Tony Forster -#Permission is hereby granted, free of charge, to any person obtaining a copy -#of this software and associated documentation files (the "Software"), to deal -#in the Software without restriction, including without limitation the rights -#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#copies of the Software, and to permit persons to whom the Software is -#furnished to do so, subject to the following conditions: +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected. -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. +# Usage: Import this code into a Python (user-definable) block; when +# this code is run, the chooser will be opened for selecting a file +# from the Journal. The contents of that file will be loaded onto the +# FILO heap. -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#THE SOFTWARE. -# This procedure is invoked when the user-definable block on the "extras" -# palette is selected. +def myblock(tw, x): # ignore second argument + ''' Load heap from journal (Sugar only) ''' -def myblock(lc, x): - - ########################################################################### - # - # Load heap from journal - # - ########################################################################### - - from tautils import chooser + from TurtleArt.tautils import chooser # Choose a datastore object and push data to heap (Sugar only) - chooser(lc.tw.parent, '', lc.push_file_data_to_heap) + chooser(tw.parent, '', tw.lc.push_file_data_to_heap) diff --git a/pysamples/paste_to_heap.py b/pysamples/paste_to_heap.py index 9255a93..0371078 100644 --- a/pysamples/paste_to_heap.py +++ b/pysamples/paste_to_heap.py @@ -1,33 +1,15 @@ -#Copyright (c) 2010, Walter Bender, Tony Forster - -#Permission is hereby granted, free of charge, to any person obtaining a copy -#of this software and associated documentation files (the "Software"), to deal -#in the Software without restriction, including without limitation the rights -#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#copies of the Software, and to permit persons to whom the Software is -#furnished to do so, subject to the following conditions: - -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. - -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#THE SOFTWARE. +#Copyright (c) 2010-11, Walter Bender, Tony Forster # This procedure is invoked when the user-definable block on the "extras" # palette is selected. -def myblock(lc, x): +# Usage: Import this code into a Python (user-definable) block; when +# this code is run, the contents of the clipboard will be appended to +# the FILO heap. + - ########################################################################### - # - # Paste from clipboard to heap - # - ########################################################################### +def myblock(tw, x): # ignore second argument + ''' Paste from clipboard to heap ''' from gtk import Clipboard from tautils import data_from_string @@ -35,5 +17,5 @@ def myblock(lc, x): text = Clipboard().wait_for_text() if text is not None: for val in data_from_string(text): - lc.heap.append(val) - lc.update_label_value('pop', val) + tw.lc.heap.append(val) + tw.lc.update_label_value('pop', val) diff --git a/pysamples/push_mouse_event.py b/pysamples/push_mouse_event.py index 485061f..b14315c 100644 --- a/pysamples/push_mouse_event.py +++ b/pysamples/push_mouse_event.py @@ -1,40 +1,26 @@ -#Copyright (c) 2009-10, Walter Bender, Tony Forster +#Copyright (c) 2009-11, Walter Bender, Tony Forster -#Permission is hereby granted, free of charge, to any person obtaining a copy -#of this software and associated documentation files (the "Software"), to deal -#in the Software without restriction, including without limitation the rights -#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#copies of the Software, and to permit persons to whom the Software is -#furnished to do so, subject to the following conditions: +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected. -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. +# Usage: Import this code into a Python (user-definable) block; when +# this code is run, the current mouse status will be pushed to the +# FILO heap. If a mouse button event occurs, a y, x, and 1 are pushed +# to the heap. If no button is pressed, 0 is pushed to the heap. -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#THE SOFTWARE. +# To use these data, pop the heap in a compare block to determine if a +# button has been pushed. If a 1 was popped from the heap, pop the x +# and y coordinates. -# -# This procedure is invoked when the user-definable block on the "extras" -# palette is selected. -def myblock(lc, x): +def myblock(tw, x): # ignore second argument + ''' Push mouse event to stack ''' - ########################################################################### - # - # Push mouse event to stack - # - ########################################################################### - - if lc.tw.mouse_flag == 1: + if tw.mouse_flag == 1: # push y first so x will be popped first - lc.heap.append((lc.tw.canvas.height / 2) - lc.tw.mouse_y) - lc.heap.append(lc.tw.mouse_x - (lc.tw.canvas.width / 2)) - lc.heap.append(1) # mouse event - lc.tw.mouse_flag = 0 + tw.lc.heap.append((tw.canvas.height / 2) - tw.mouse_y) + tw.lc.heap.append(tw.mouse_x - (tw.canvas.width / 2)) + tw.lc.heap.append(1) # mouse event + tw.mouse_flag = 0 else: - lc.heap.append(0) # no mouse event + tw.lc.heap.append(0) # no mouse event diff --git a/pysamples/push_time.py b/pysamples/push_time.py index ae22684..5f86be4 100644 --- a/pysamples/push_time.py +++ b/pysamples/push_time.py @@ -1,37 +1,21 @@ -#Copyright (c) 2009-10, Walter Bender +#Copyright (c) 2009-11, Walter Bender -#Permission is hereby granted, free of charge, to any person obtaining a copy -#of this software and associated documentation files (the "Software"), to deal -#in the Software without restriction, including without limitation the rights -#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#copies of the Software, and to permit persons to whom the Software is -#furnished to do so, subject to the following conditions: +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected. -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. +# Usage: Import this code into a Python (user-definable) block; when +# this code is run, the current hour, minute, and second are pushed to +# the FILO heap. To use these values, pop second, then minute, then +# hour from the FILO. -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#THE SOFTWARE. -# This procedure is invoked when the user-definable block on the "extras" -# palette is selected. +def myblock(tw, x): # ignore second argument + ''' Push hours, minutes, seconds onto the FILO. ''' -def myblock(lc, x): - - ########################################################################### - # - # Push hours, minutes, seconds onto the FILO. # Use three 'pop' blocks to retrieve these values. # Note: because we use a FILO (first in, last out heap), # the first value you pop off of the FILO will be seconds. - # - ########################################################################### - lc.heap.append(localtime().tm_hour) - lc.heap.append(localtime().tm_min) - lc.heap.append(localtime().tm_sec) + tw.lc.heap.append(localtime().tm_hour) + tw.lc.heap.append(localtime().tm_min) + tw.lc.heap.append(localtime().tm_sec) diff --git a/pysamples/save_heap_to_journal_entry.py b/pysamples/save_heap_to_journal_entry.py index c4f2d50..a06d4d0 100644 --- a/pysamples/save_heap_to_journal_entry.py +++ b/pysamples/save_heap_to_journal_entry.py @@ -1,33 +1,16 @@ -#Copyright (c) 2010, Walter Bender, Tony Forster +#Copyright (c) 2010-11, Walter Bender, Tony Forster -#Permission is hereby granted, free of charge, to any person obtaining a copy -#of this software and associated documentation files (the "Software"), to deal -#in the Software without restriction, including without limitation the rights -#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#copies of the Software, and to permit persons to whom the Software is -#furnished to do so, subject to the following conditions: +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected. -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. +# Usage: Import this code into a Python (user-definable) block; when +# this code is run, the contents of the FILO heap are saved to a +# Journal entry named by the value of the argument to the Python +# block. -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#THE SOFTWARE. -# This procedure is invoked when the user-definable block on the "extras" -# palette is selected. - -def myblock(lc, x): - - ########################################################################### - # - # Save heap to journal (Sugar only) - # - ########################################################################### +def myblock(tw, title): + ''' Save heap to journal (Sugar only) ''' import os.path from gettext import gettext as _ @@ -36,18 +19,19 @@ def myblock(lc, x): from sugar.datastore import datastore from sugar import profile - from tautils import get_path, data_to_file + from TurtleArt.tautils import get_path, data_to_file # Save JSON-encoded heap to temporary file - heap_file = os.path.join(get_path(activity, 'instance'), str(x) + '.txt') - data_to_file(lc.heap, heap_file) + heap_file = os.path.join(get_path(activity, 'instance'), + str(title) + '.txt') + data_to_file(tw.lc.heap, heap_file) # Create a datastore object dsobject = datastore.create() # Write any metadata (specifically set the title of the file # and specify that this is a plain text file). - dsobject.metadata['title'] = str(x) + dsobject.metadata['title'] = str(title) dsobject.metadata['icon-color'] = profile.get_color().to_string() dsobject.metadata['mime_type'] = 'text/plain' dsobject.set_file_path(heap_file) diff --git a/pysamples/set_rgb.py b/pysamples/set_rgb.py index f524ec6..d4baa48 100644 --- a/pysamples/set_rgb.py +++ b/pysamples/set_rgb.py @@ -1,50 +1,19 @@ -#Copyright (c) 2009-10, Walter Bender +#Copyright (c) 2009-11, Walter Bender -#Permission is hereby granted, free of charge, to any person obtaining a copy -#of this software and associated documentation files (the "Software"), to deal -#in the Software without restriction, including without limitation the rights -#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#copies of the Software, and to permit persons to whom the Software is -#furnished to do so, subject to the following conditions: +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected and expanded to 3 arguments. -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. +# Usage: Import this code into a Python (user-definable) block. +# First, expand the Python block to reveal three numerics arguments. +# Set these values to the desired red, green, and blue. When the code +# is run, the red, green, and blue values are used to set the pen +# color. -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#THE SOFTWARE. -# -# This procedure is invoked when the user-definable block on the "extras" -# palette is selected and expanded to 3 arguments. - -def myblock(lc, x): - - ########################################################################### - # - # Set rgb color from values - # - ########################################################################### - - # assuming x is an array [r, g, b] - b = int(x[2]) - while b < 0: - b += 256 - while b > 255: - b -= 256 - g = int(x[1]) - while g < 0: - g += 256 - while g > 255: - g -= 256 - r = int(x[0]) - while r < 0: - r += 256 - while r > 255: - r -= 256 - rgb = "#%02x%02x%02x" % (r,g,b) - lc.tw.canvas.fgcolor = lc.tw.canvas.cm.alloc_color(rgb) +def myblock(tw, rgb_array): + ''' Set rgb color from values ''' + + rgb = "#%02x%02x%02x" % ((int(rgb_array[0]) % 256), + (int(rgb_array[1]) % 256), + (int(rgb_array[2]) % 256)) + tw.canvas.fgcolor = tw.canvas.cm.alloc_color(rgb) diff --git a/pysamples/sinewave.py b/pysamples/sinewave.py index eea975d..4f14c4c 100644 --- a/pysamples/sinewave.py +++ b/pysamples/sinewave.py @@ -1,33 +1,15 @@ -#Copyright (c) 2010, Tony Forster +#Copyright (c) 2010-11, Tony Forster -#Permission is hereby granted, free of charge, to any person obtaining a copy -#of this software and associated documentation files (the "Software"), to deal -#in the Software without restriction, including without limitation the rights -#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#copies of the Software, and to permit persons to whom the Software is -#furnished to do so, subject to the following conditions: +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected. -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. +# Usage: Import this code into a Python (user-definable) block and +# pass a frequency in Hertz to the Python block. A tone will play over +# the speaker at the specified frequency. -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#THE SOFTWARE. -# This procedure is invoked when the user-definable block on the "extras" -# palette is selected. - -def myblock(lc, x): - - ########################################################################### - # - # Plays a sound at frequency x - # - ########################################################################### +def myblock(tw, frequency): + ''' Plays a sound at frequency frequency ''' import os - os.system('speaker-test -t sine -l 1 -f %d' % (int(x))) + os.system('speaker-test -t sine -l 1 -f %d' % (int(frequency))) diff --git a/pysamples/speak.py b/pysamples/speak.py new file mode 100644 index 0000000..30762a9 --- /dev/null +++ b/pysamples/speak.py @@ -0,0 +1,57 @@ +#Copyright (c) 2009-11, Walter Bender, Tony Forster + +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected. + +# Usage: Import this code into a Python (user-definable) block and +# pass a string to be read by the voice synthesizer. If a second +# argument is passed, by expanding the Python block, it is used to specify +# the pitch level of the speaker. Valid range is 0 to 99. + + +def myblock(tw, arg): + ''' Text to speech ''' + + TABLE = {'af': 'afrikaans', 'cy': 'welsh-test', 'el': 'greek', + 'es': 'spanish', 'hi': 'hindi-test', 'hy': 'armenian', + 'ku': 'kurdish', 'mk': 'macedonian-test', 'pt': 'brazil', + 'sk': 'slovak', 'sw': 'swahili', 'bs': 'bosnian', 'da': 'danish', + 'en': 'english', 'fi': 'finnish', 'hr': 'croatian', + 'id': 'indonesian-test', 'la': 'latin', 'nl': 'dutch-test', + 'sq': 'albanian', 'ta': 'tamil', 'vi': 'vietnam-test', + 'ca': 'catalan', 'de': 'german', 'eo': 'esperanto', + 'fr': 'french', 'hu': 'hungarian', 'is': 'icelandic-test', + 'lv': 'latvian', 'no': 'norwegian', 'ro': 'romanian', + 'sr': 'serbian', 'zh': 'Mandarin', 'cs': 'czech', 'it': 'italian', + 'pl': 'polish', 'ru': 'russian_test', 'sv': 'swedish', + 'tr': 'turkish'} + import os + + pitch = None + if type(arg) == type([]): + text = arg[0] + if len(arg) > 1: + pitch = int(arg[1]) + if pitch > 99: + pitch = 99 + elif pitch < 0: + pitch = 0 + else: + text = arg + + # Turtle Art numbers are passed as float, + # but they may be integer values. + if type(text) == float and int(text) == text: + text = int(text) + + lang = os.environ['LANG'][0:2] + if lang in TABLE: + language_option = '-v ' + TABLE[lang] + else: + language_option = '' + if pitch is None: + os.system('espeak %s "%s" --stdout | aplay' % (language_option, + text)) + else: + os.system('espeak %s "%s" -p "%s" --stdout | aplay' % ( + language_option, text, pitch)) diff --git a/pysamples/svg_end_group.py b/pysamples/svg_end_group.py new file mode 100644 index 0000000..e4682b3 --- /dev/null +++ b/pysamples/svg_end_group.py @@ -0,0 +1,17 @@ +#Copyright (c) 2009-11, Walter Bender + +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected and expanded to 3 arguments. + +# Usage: Import this code into a Python (user-definable) block. +# First, expand the Python block to reveal three numerics arguments. +# Set these values to the desired red, green, and blue. When the code +# is run, the red, green, and blue values are used to set the pen +# color. + + +def myblock(tw, x): + ''' Add end group to SVG output ''' + + tw.svg_string += '</g>' + diff --git a/pysamples/svg_start_group.py b/pysamples/svg_start_group.py new file mode 100644 index 0000000..57500bc --- /dev/null +++ b/pysamples/svg_start_group.py @@ -0,0 +1,17 @@ +#Copyright (c) 2009-11, Walter Bender + +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected and expanded to 3 arguments. + +# Usage: Import this code into a Python (user-definable) block. +# First, expand the Python block to reveal three numerics arguments. +# Set these values to the desired red, green, and blue. When the code +# is run, the red, green, and blue values are used to set the pen +# color. + + +def myblock(tw, x): + ''' Add start group to SVG output ''' + + tw.svg_string += '<g>' + diff --git a/pysamples/uturn.py b/pysamples/uturn.py new file mode 100644 index 0000000..0b164a0 --- /dev/null +++ b/pysamples/uturn.py @@ -0,0 +1,35 @@ +#Copyright (c) 2011, Walter Bender + +# This procedure is invoked when the user-definable block on the +# "extras" palette is selected. + +# Usage: Import this code into a Python (user-definable) block; when +# it is run, a u-turn block will be added to the Turtle Palette. You +# can use the u-turn block as you would any other block. + + +def myblock(tw, arg): + ''' Add a uturn block to the 'turtle' palette ''' + + from TurtleArt.tapalette import make_palette, palette_name_to_index + from TurtleArt.talogo import primitive_dictionary + from gettext import gettext as _ + + # Choose a palette for the new block. + palette = make_palette('turtle') + + # Create a new block prototype. + palette.add_block('uturn', + style='basic-style-extended-vertical', + label=_('uturn'), + prim_name='uturn', + help_string=_('make a uturn')) + + # Add its primitive to the LogoCode dictionary. + tw.lc.def_prim('uturn', 0, + lambda self: primitive_dictionary['set']( + 'heading', tw.canvas.seth, tw.canvas.heading + 180)) + + # Regenerate the palette, which will now include the new block. + tw.show_toolbar_palette(palette_name_to_index('turtle'), + regenerate=True) |