vnc2flv

vnc2flv – Desktop Screen Recorder:

Desktop Screen Recorder for UNIX, Linux, Windows or Mac.

Homepage   Recent Changes

Last Modified: Sun Feb 7 19:27:39 JST 2010

Download:
http://pypi.python.org/pypi/vnc2flv/

Discussion: (for questions and comments, post here)
http://groups.google.com/group/vnc2flv-users/

View the source:
http://code.google.com/p/vnc2flv/source/browse/trunk/vnc2flv


What’s It?

Vnc2flv is a cross-platform screen recording tool for UNIX, Windows or Mac. It captures a VNC desktop session (either your own screen or a remote computer) and saves as a Flash Video (FLV) file.

(Vnc2flv is a rewrite of its predecessor, vnc2swf. As FLV format is more prevalent today, vnc2flv is specialized for FLV format and aims at a simpler and more lightweight functionality.)

Demo: (created with vnc2flv itself)


How to Install

  1. First of all, you have to have the x11vnc server running on your screen. This program captures the screen sends it to other processes. See also a list of other VNC servers.
  2. Install Python 2.4 or newer.
  3. Download and extract the vnc2flv source distribution.
  4. Run setup.py to install:
    # python setup.py install
    
  5. Done!



Installing for Windows

Here is an additional instruction for Windows:

  1. Install TightVNC 1.3.10 or newer.
  2. Install MinGW 5.1.4 or newer.
  3. Do the following instead:
    > python setup.py build -c mingw32 install
    



How to Use

vnc2flv comes with several programs:



flvrec.py

flvrec.py is the main recording program. It connects to a specified VNC server and immediately starts recording. It stops when it receives a SIGINT (or Ctrl-C is pressed). You need to have a VNC server running on the target machine in advance.

The generated file is playable via either desktop programs like ffmpeg, VLC or mplayer, or other online Flash-based players.

Syntax:

flvrec.py [options] [host[:display]]

   or

flvrec.py [options] [host [port]]

Examples:

$ x11vnc -quiet -localhost -viewonly -nopw -bg
(start up a vnc server)

The VNC desktop is:      localhost:0
PORT=5900

******************************************************************************
Have you tried the x11vnc '-ncache' VNC client-side pixel caching feature yet?

The scheme stores pixel data offscreen on the VNC viewer side for faster
retrieval.  It should work with any VNC viewer.  Try it by running:

    x11vnc -ncache 10 ...

more info: http://www.karlrunge.com/x11vnc/#faq-client-caching

$ flvrec.py localhost:0
(Record a local desktop)

$ flvrec.py -C 640x480+0-0 remotehost:0
(Record a remote desktop with a 640x480 window at the bottom left of the screen.)

$ flvrec.py -S 'arecord sample.wav'
(Record a local desktop and capture audio input simultaneously using the ALSA recording utility)

Options:

-o filename
Specifies the output file name. By default, the output file is given with a unique name.
-r fps
Specifies the number of frames per second. (default: 15)
-K keyframe
Specifies the rate of key frames that is inserted in every this number of frames. (default: every 150 frames)
-P pwdfile
Specifies the password file for a vnc session.
-N
Suppress the appearance of mouse pointer in the video.
-e encoding,encoding,...
Specifies the vnc encoding methods. (default: raw)
-B blocksize
Specifies the block size. (default: 32)
-C wxh{+|-}x{+|-}y
Specifies the clipping. (default: entire screen)
-S commandline
Starts a child process immediately after the recording is started. This process runs parallely with flvrec.py and can be used for recording audio. When the recording is stopped, a SIGINT is sent to the subprocess.
-d
Increases the debug level.



flvcat.py

flvcat.py is a simplistic editing program for a FLV movie. It supports concatenating multiple movies, clipping a movie’s frame size, re-sampling a movie into a smaller size with auto-panning, etc.

Syntax:

flvcat.py [options] src1[:ranges1] src2[:ranges2] ... output

For each movie file, you can clip the parts of the movie to add by specifying its ranges. Ranges is comma-separated, hyphenated list of milliseconds. For example,

out.flv:10000-20000

means a 10-second clip from movie out.flv (0:10-0:20). Specifying only one end of the range is also supported:

out.flv:10000-

means the entire movie except the first 10 seconds. When ranges are omitted, the whole movie is used.

Examples:

$ flvcat.py movie1.flv movie2.flv output.flv
(Concatenate movie1.flv and movie2.flv and save it as output.flv)

$ flvcat.py -W 640x480 movie1.flv output.flv
(Resize the movie1.flv with auto-panning with its window size 640x480 and save it as output.flv)

$ flvcat.py movie1.flv:15000-30000 output.flv
(Clip the part of movie1.flv from 0:15 to 0:30 and save it as output.flv)

$ flvcat.py movie1.flv:2500- output.flv
(Chop the first 2.5 seconds off and save it as output.flv)

Options:

-r fps
Specifies the number of frames per second. (default: 15)
-K keyframe
Specifies the rate of key frames that is inserted in every this number of frames. (default: every 150 frames)
-B blocksize
Specifies the block size. (default: 32)
-C wxh{+|-}x{+|-}y
Specifies the clipping. (default: entire frame)
-W wxh
Specifies the window size for auto panning. Auto panning tracks the changes in the screen and tries to focus on the active part of the screen. This helps reducing the movie screen size. (default: no auto panning)
-S speed
Specifies the speed of auto panning. (default: 60 frames)
-f
Forces overwriting the output file.



flvaddmp3.py

Add mp3 audio files to a movie.

Syntax:

flvaddmp3.py [options] src mp3file1[:ranges] mp3file2[:ranges] ... output

Options:

-f
Forces overwriting the output file.



flvsplit.py

Split a movie file into shorter clips. This can be used to chop movies into several chunks in order to fit each of them within the length limitation in several movie sites (e.g. YouTube).

Syntax:

flvsplit.py [options] src dstbase

Options:

-f
Forces overwriting the output file.
-r fps
Specifies the number of frames per second. (default: 15)
-K keyframe
Specifies the rate of key frames that is inserted in every this number of frames. (default: every 150 frames)
-B blocksize
Specifies the block size. (default: 32)
-D duration
Specifies the maximum movie length in seconds. (default: 600)
-P overlap
Specifies the length of overlapping parts in consecutive clips in seconds. (default: 5)



flvdump.py (for debugging)

This program dumps the contents of a FLV file. This is used solely for debugging purposes.

Syntax:

flvdump.py [options] flvfile



recordwin.sh

This program is a shell script that launches a VNC server (x11vnc), the screen recorder (flvrec.py) and a voice recorder (arecord), and combines the output files into a single playable FLV file. A recording area in the screen can be either an entire desktop or a single window. In the latter case, a target window can be chosen by giving the window ID or window name, or simply click a window after a prompt cursor appears. When a filename is unspecified, a generated movie is automatically given a unique filename.

Syntax:

recordwin.sh [options] [filename]

Options:

-all
Instructs to record an entire desktop.
-name window_name
Specifies the title of the target window.
-id window_id
Specifies the Window ID of the target window.
-display display_name
Specifies the name of the X11 screen where a VNC server is to be started.



Adding Audio

flvrec.py can designate a child process to record audio during recording. By giving -S option, the specified command line is executed when the recording is started. The child process can capture audio input and encode it as an appropriate format. The process is terminated when the recording is stopped. To put it onto an FLV movie, the audio needs to be encoded as MP3 format. After the recording is finished, the user can use the flvaddmp3.py command to combine the movie and audio output.

NOTICE: The audio sampling rate must be one of the following: 5500Hz, 11025Hz, 22050Hz, or 44100Hz.

1. Record the screen and audio simultaneously:

$ flvrec.py -S 'arecord -f cd out.wav'

2. Convert the WAV file into MP3:

$ lame out.wav out.mp3

3. Add the MP3 file to the movie:

$ flvaddmp3 out200908122312.flv out.mp3 final.flv

  or

1. Just do this:

$ recordwin.sh

recordwin.sh is a script for making these tasks easy. It launches a VNC server and automatically does the things described above.


Embedding Movie

Currently the following free/opensource embeddable movie players are known to work with vnc2flv:



Changes

  • 2010/01/22: flvsplit.py added.
  • 2009/11/14: SIGINT bug fixed.
  • 2009/10/25: FLV metadata support.
  • 2009/08/30: recordwin.sh script is added.
  • 2009/08/24: Improved documentation.
  • 2009/08/17: Synchronized audio recording support is added.
  • 2009/08/02: various bugfixes. Command name changed: mp3add.py -> flvaddmp3.py.
  • 2009/07/22: flvcat.py added.
  • 2009/07/04: rfb protocol handling modified. (hopefully better auto-scrolling)
  • 2009/07/02: mp3add.py and flvdump.py added.
  • 2009/06/28: Initial release.



Related Links



Terms and Conditions

Copyright (c) 2009 Yusuke Shinyama <yusuke at cs dot nyu dot edu>

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.


Yusuke Shinyama
0

0
 

pyvnc2swf

pyvnc2swf:

Homepage: http://www.unixuser.org/~euske/vnc2swf/
Discussion: http://lists.sourceforge.net/lists/listinfo/vnc2swf-users

$Id: pyvnc2swf.html,v 1.2 2008/11/16 02:39:40 euske Exp $


Pyvnc2swf is a cross-platform screen recording tool. It captures screen motion through VNC protocol and generates a Shockwave Flash (SWF) movie. Pyvnc2swf suite comes with three Python programs:

  • vnc2swf.py – Recorder
  • edit.py – Movie editor (This is NOT a general SWF file editor. It only supports movies generated by vnc2swf.)
  • play.py – Simple movie viewer

For questions, please read the FAQ and list archives before sending me emails.

Terms and Conditions: Pyvnc2swf comes with ABSOLUTELY NO WARRANTY. This software is distributed under the GNU General Public License.


Installation

In all platforms, the following packages are required:

  • Python (2.4 or above)
  • Pygame (1.6 or above)
  • Optional: PyMedia (1.3.5 or above – required for mpeg encoding)

In most Linux distros, these packages are readily available. In Mac OS X, you would need an additional OS X build of Pygame package.

Also, you need at least one VNC server:

  • RealVNC or TightVNC (Unix, Linux or Windows)
  • x11vnc (Unix/Linux for recording an existing desktop)
  • OSXVnc (Mac OS X)
  • GNOME Vino (This is not an independent package, but if you have GNOME desktop environment which supports remote desktop functionality, you have it.)



Recording

vnc2swf.py program captures a VNC sessions and records it in either SWF or VNCLog format. This is a VNC client and communicates directly with a VNC server. A user need to start a VNC server in advance.

vnc2swf.py runs in two different modes: GUI (Graphical User Interface) mode and CLI (Command Line Interface) mode. In the GUI mode, start recording by clicking the “Start” button. Then choose the “Save as…” command from the “File” menu to save the recorded movie to a file. In the CLI mode, a user needs to specify the output filename from command line. Recording is started immediately. In both modes, a user is prompted for a VNC password if the server requires authentication (and unless the user doesn’t specify the password file). In the CLI mode, hit Control-C to stop recording. After finishing recording, it generates two files with the specified name: a .swf and .html file. The .html file contains an HTML tag and a javascript code to provide seek bar function.

A user can choose three different methods to encode movie image: “flv“, “swf5“, “swf7“, “mpeg” (PyMedia required), or “vnc“. The first swf5 encoding (default) provides a reasonable movie size. The second encoding method, swf7 provides a smaller SWF movie. This is, however, not recommended to use within vnc2swf.py for two reasons: This type of encoding is only supported by Flash Player version 7 or newer. Also, generating a movie with on-the-fly swf7 encoding is slower so you might experience frame dropping. Actually, you can convert a swf5-encoded movie into swf7-encoded one after recording by using edit.py, so anyway you don’t need to use this method when recording. The third encoding method is vnc. This method generates a .vnc (VNCLog) file, which is compatible with vncrec output file. You can convert it to a SWF movie with edit.py. A .vnc file is not a SWF movie by itself, but its encoding is the fastest.

NOTE: Unlike the C version, vnc2swf.py doesn’t handle any user interaction. If you want to control the server’s desktop, you need to launch vncviewer or its equivalent separately.

Syntax

  • (GUI) $ vnc2swf.py [-o filename] [options] [host[:display] [port]]
  • (CLI) $ vnc2swf.py -n -o filename [options] [host[:display] [port]]

Example

(Record a virtual screen)
$ vncserver -geometry 640x480
$ vnc2swf.py -o out.swf localhost:1

(Record an existing screen)
$ x11vnc -localhost -viewonly -wait 10 -defer 10 -bg
$ vnc2swf.py -o out.swf localhost:0

(Record a remote screen)
$ vnc2swf.py -n -o out.flv vnc.example.com:1

If you’re using x11vnc, see also recordwin. This is a convenient script to record a particular window.

Recording Tips

  • Use as small screen size as possible, or try to specify the smallest clipping rectangle. With a large screen, VNC’s screen polling gets slower and vnc2swf also gets slower for converting bigger images. Using a small screen also helps reducing the movie size.
  • Reducing the framerate sometimes helps reducing the movie size. If the generated movie is still very big, try resampling frames or scaling the image with edit.py.
  • To record a long movie (more then 20min.), the only available option is to use flv (or mpeg if you have PyMedia). swf5 or swf7 files have a limitation and lcan have up to 16000 frames, which is roughly 22 minutes.
  • If you experience frame dropping, try changing the server options for screen polling (if any). If you’re using x11vnc, try adding -wait 10 -defer 10.
  • When recording flv movie, you can dump a live stream output to stdout by speficing ‘-‘ as a filename. But currently I have no idea how to use. (broadcasting your desktop on the web?)

Options

-n
Console mode (no GUI).

-o outputfile
Specifies the output filename. This option is required in CLI mode. In GUI mode, when not specified it prompts the user for the filename. The movie encoding type is usually inferred from the filename, so the filename should end with either “.swf” or “.vnc“. Otherwise, the user need to specify the output movie encoding with -t option (see below.)

-C clipping
Specifies the clipping rectangle. The geometry must be as form of “widthxheight+left+top” (e.g. “400x300+120+0“). Unlike other X11 applications, all rectangular components are required. Negative values are not supported.

-r framerate
Specifies the framerate in fps. (default=12.0)

-t encodingtype
Specifies the output movie encoding method (“flv“, “mpeg“, “swf5“, “swf7” or “vnc“). When omitted, the encoding type is automatically inferred from the filename (*.swf = swf5, *.vnc = vnc).

-N
Disables cursor pseudo-encoding. Pyvnc2swf normally tries to use cursor pseudo-encoding to capture a mouse cursor position so that a cursor can be moved separately from a screen image and it reduces the movie size. However this might not work with some vnc servers. This option can be used for disabling the function.

-P passwdfile
Specifies a password file. If specified, its content is automatically loaded and supplied as password when a VNC server requires it. A password file contains an encrypted password string and can be created with vncpasswd. A user can directly specify ~/.vnc/passwd, which normally contains the password for the local vnc server.

-e vncencodings
Specifies the preferred encodings for VNC image transfer (this is different from movie encoding). Normally you don’t need to change this option. Encodings are comma-separated integers (default=”5,4,0″). Changing encodings might improve recording performance.

-S subprocess (Supported on Un*x only, Python 2.4 or above is required)
Set a command to run during recording. This option is useful for recording voice with a separated program. A command line is a space-separated sequence of arguments which are passed to a child process like a usual shell command line. However the command line is not passed to a shell and the arguments are directly passed to the child process without any substitution. A child process is started immediately after recording starts and sent SIGINT after recording finishes.

-d
Increases debug level.



Editing

edit.py program is for editing or reorganizing one or multiple movies generated by vnc2swf.py. This program also supports converting a .vnc file into .swf movie, changing the encoding method (swf5->swf7), attaching MP3 audio file to a movie, extracting images from a movie and resampling/scaling/clipping a movie image.

edit.py currently supports only command line interface. The user must give one output filename and one or more input filename(s). Input movies are concatenated sequentially (in the specified order) and the desired effects are applied.

Syntax

$ edit.py -o outfile.swf [options] infile ...

Example

(Convert .vnc file into .swf with compressed video encoding)
$ edit.py -o out.swf -c -t swf7 input.vnc

(Attach an mp3 file to .swf)
$ edit.py -o out.swf -a voice.mp3 in.swf

(Concatenate two movies and extract the frames into another movie)
$ edit.py -o out.swf -f 100-200,350- movie1.swf movie2.swf

(Clip the top left area of the movie and shrink it to half the size)
$ edit.py -o small.swf -C 320x240+0+0 -s 0.5 in.swf

(Convert .swf into MPEG)
$ edit.py -o out.mpg input.swf

(Convert .swf into .flv)
$ edit.py -o out.flv input.swf

Options

-o outputfile
Specifies the output filename. This option is always required.

-c
Compress a movie with zlib. Compressions is supported for both (swf5 and swf7) types of movies, but usually it’s most effective when applied to swf7-encoded movies.

-t encodingtype
Specifies the encoding method for an output movie. When this option is not specified, the encoding type is inferred from the output filename extention.

Type Extension Description
swf5 .swf SWF movie (default)
swf7 SWF movie with stream video encoding support
flv .flv FLV movie
mpeg .mpg MPEG movie (requires PyMedia)
bmp .bmp BMP image sequence
png .png PNG image sequence

Note that swf7 encoding is supported only with Flash Player version 7 or newer.

-f frames or
-F frames
Specifies a sequence of frames presented in the output movie. When omitted, all frames are presented in the original order (default). Frames can be specified with a comma-separated list of integers. A range of integers can be also specified by using - (hyphen) sign. For example: 10,200,300-400 specifies the frames whose number is 10 and 200, plus every frame between frame 300 and 400. The beginning (or ending) frame number can be omitted (e.g. -100 or 300-). In this case, the first (or last) frame number is used as the other end of the range.

-F option and -f option is same except that -F doesn’t chop the audio while -f does. When you’re putting audio on the movie, if you use -f and -a option at the same time, it chops an mp3 file according to the selected frames. However, when you want to cast a continuous sound (such as music) onto a whole movie, this might not be the desired effect. In such a case, use -F instead of -f.

-a mp3file
Attaches mp3 file(s) to the movie. (Adding audio to FLV format is currently not supported.) Multiple mp3 files are concatenated in the specified order.
NOTE: When specifying multiple mp3 files, make sure every file has the same bitrate as the first one. And do NOT use “variable bitrate” (VBR) mp3 files, as the SWF format doesn’t support them!

-s scaling
Rescale the movie image with a specified ratio which is given as a fraction.
NOTE: There will be noises with non-multiple scaling (e.g. 0.7).

-C clipping
Clips the movie into a specified rectangle. The geometry must be as form of “widthxheight+left+top” (e.g. “400x300+120+0“).

-K keyinterval
Insert a keyframe in every N frames. Keyframes work as hints for Flash Player and are useful for seeking a frame within a long movie. When the number of total frames exceeds 10,000, inserting keyframes in every 500 frames (-K 500) is recommended.

-r framerate
Changes the frame rate of the movie. This option itself doesn’t do any frame resampling and simply changes the movie speed. When this option is omitted, edit.py tries to keep the original frame rate in the output movie.

-R resampleframes
Resample (or “thin down”) a movie by picking one from every N frames.

-S skipmp3frames
Skip the first N mp3-frames of the mp3 file. When ‘s‘ is appended to the number (such as ‘1.0s‘), it indicates the number of seconds instead of frames. This option is useful when there is a time lag between a recorded image and audio.

-B blocksize
Sets the blocksize for swf7 or flv encoding method (default=32). This must be a multiple of 16.

-b
Suppress a seekbar in a generated html file.

-l
Disables movie loop in a generated html file.

-d
Increases debug level.



Previewing

play.py is a simple player for a .swf or .vnc file. This program might be useful for spotting the right frame number in a recorded movie. However its speed is awkward and audio output is not supported. It only supports vnc2swf-generated files and cannot play general SWF movies.

The player accepts the following keys:

Syntax

$ play.py [options] moviefile ...

Options

-r framerate
Specifies the framerate to play.

-s scaling
Specifies the scaling ratio with a fraction.

-C clipping
Specifies the clipping rectangle. The geometry must be as form of “widthxheight+left+top” (e.g. “400x300+120+0“).

-d
Increases debug level.



Frequently Asked Questions

I found weird artifacts in a recorded movie. How to fix it?
Probably you played the SWF file directly. A SWF movie should be played in the exactly same size as it is recorded. Use an HTML file generated by vnc2swf.py or edit.py.

How to make a movie with audio?
Record your audio separately and encode it with an MP3 encoder like Lame. Then combine them with edit.py.

A browser freezes when I try to seek within a movie.
Put keyframes in every hundreds frame. Try -K option in edit.py. Normally putting keyframes in every 500 frames (-K 500) gives a reasonable result.



Structure of the Program

For those who are interested in learning or extending the program, I drew a simple figure to explain how data goes between objects within pyvnc2swf.


Yusuke Shinyama <yusuke at cs dot nyu dot edu>
0

0
 

21 aplicaciones para desarrolladores web

Noticia extraida de WWWhatsnew.com:
———————————————–

Gracias al post que me he encontrado en Smashing Hub, voy a realizar una pequeña recopilación de sobre 21 aplicaciones web ideales para desarrolladores web.

En la recopilación hablaremos sobre editores de código, editores de imagen y creadores de logotipos.

Empecemos:

Editores de código

Amy Editor es un editor muy sofisticado con una gran interfaz que incluye herramientas profesionales como si estuvieras utilizando un editor de código instalable.

Entre sus funciones podemos destacar que podemos abrir varios archivos mediante pestañas, resaltado del código para diferentes idiomas y la posibilidad de administrar diferentes proyectos a la vez.

Bespin es una aplicación creada principalmente por los desarrolladores de Mozilla Labs, básicamente lo que nos permitirá es editar códigos embed.

Entre ellos la edición del nuevo código HTML5. Además, es una aplicación que ya tiene creado un plugin con el que podremos usar más funciones en el navegador Mozilla Firefox.

Kodingen digamos que es un pequeño pack en la nube, donde incluye todo lo necesario para programar en internet, es decir, un excelente editor de imágenes, un editor de código y varias herramientas más.

No obstante, tiene un problema esta aplicación y es que de hecho está aún en fase beta por lo que sólo lo pueden utilizar un limitado número de usuarios. No obstante es una buena aplicación que contiene todo lo necesario para desarrolladores web.

EditArea es otra herramienta para editar código web que incluye las funciones básicas de resalto de sintaxis, búsquedas y remplazar el código, además de un soporte multi-lenguaje y varias características más.

Lo mejor es que es un editor de código libre por lo que tendremos la posibilidad de alojarlo en nuestro servidor web.

Practicode es un editor multi-código, es decir que podremos editar desde código HTML, hasta CSS pasando por Javascript, XHTML y Visual Basic Script. Todo ello con una interfaz gráfica excelente y con varios tutoriales para aprender más aún.

Clean CSS es una simple herramienta que nos permitirá limpiar con totalidad nuestro código CSS obteniendo como resultado un código más legible y más limpio.

Real Time jQuery Editor es una de las herramientas que me ha gustado más de esta sección y es que nos permite editar y codificar el código JQuery de forma instantánea, es decir, en tiempo real. Con una gran interfaz y funcionalidades, se convierte sin duda en la herramienta ideal para los desarrolladores de JQuerry.

Editores de imagen

Photoshop.com es una herramienta que nos permitirá editar nuestras imágenes en la web. Con muchas de las funciones básicas y avanzadas de la edición de imagen, se convierte en una buena alternativa al photoshop instalable (para quien no necesita el 100% de las posibilidades de la versión desktop de Photoshop, claro).

Entre sus funciones destacamos la posibilidad de: acceder a nuestra cuenta con una dirección web personalizada, compartir los trabajos, tener un espacio de 2GB de almacenamiento gratuito (o pagar varias cuotas para incrementar este espacio) y tutoriales.

Picnik como bien comentamos ya hace varios años en wwwhatsnew, es un editor muy eficaz, que además de las características básicas incorpora avanzadas, filtros, efectos y un sinfín más de herramientas muy sofisticadas.

Pixlr.com, como bien hablo mi compañero Lucas Cepeda en 2008, es un excelente editor, muy potente, ya que incluye todas las funciones necesarias siendo muy fácil de utilizar y familiarizarse con los menús y herramientas que lo componen.

También, podemos considerar a Pixlr como una alternativa bastante similar a Photoshop.com o a Picnik.

OnlineImageEditor es un sencillo editor de imágenes dedicado especialmente para aquellas personas que no tienen conocimientos avanzados sobre la edición de imágenes o la utilización de herramientas profesionales.

Con un diseño simple y efectivo podrás modificar tus imágenes rápidamente añadiendo efectos, letras, formas…

Sumopaint es una aplicación que nos ofrece un entorno muy agradable para realizar toda clase de efectos, filtros y ajustes en nuestras fotos.

Pixer.us es otra excelente herramienta de edición de imágenes en línea gratuita, que incluye todas las funciones básicas, efectos, combinaciones de colores… Todo un todoterreno de la edición fotográfica.

Creadores de logotipos

Flashbannernow es una excelente aplicación para diseñar banner flash para tu sitio web o blog sin ninguna dificultad en su utilización.

Uno de los inconvenientes de este sitio es que para utilizarse deberemos colocar un banner en nuestro sitio web dando referencia a este servicio y que lo hemos utilizado en alguna parte de nuestro sitio web, no obstante, sigue siendo una buena aplicación para crear banners personalizados en flash.

123 Banner es una sencilla herramienta que nos permitirá crear logotipos fácilmente eligiendo una template, aun que hay que destacar que no todos los templates son atractivos…

Entre sus funciones, podemos destacar la posibilidad de utilizar banderas para nuestras creaciones y una interfaz muy amigable con la que podremos diseñar rápida y eficazmente.

Kizoa es otra herramienta que nos proporciona todas las herramientas básicas para crear los logotipos, pero aparte de ellas incorpora otras más avanzadas que nos permitirá personalizar al máximo nuestra creación. Por ejemplo, incorporan herramientas para añadir música, crear transiciones de imagen, efectos, etc.

123Slideshow es una alternativa al anterior servicio comentado (123Banner), con unas prestaciones bastante interesantes, funcionales y sobre todo potentes. Podremos crear con facilidad, logotipos o presentaciones en flash, con transacciones, efectos, etc.

Online Logo Maker es una sencilla herramienta con la que podrás crear banners profesionales para tu sitio web o blog. Lo mejor del servicio es que no requiere ningún tipo de registro para ser utilizado, por lo que solo con acceder ya podremos empezar a crear o editar banners.

Web 2.0 Logo Generator, es un servicio diseñado por simwebsol y que básicamente nos permite crear logotipos dospuntoceristas con tan solo escribir el texto y elegir varias de las opciones que nos proponen para mejorar la calidad final y el aspecto antes de descargárnoslo a nuestro ordenador.

thefreelogomakers.com es un servicio web que nos permitirá crear logotipos rápidamente con su interfaz moderna e intuitiva. Incluye las herramientas más básicas para la creación de los mismos.

Mybannermaker es un servicio web muy potente que nos permitirá, con la ayuda de tutoriales paso a paso, crear nuestro logotipo para añadirlo en nuestro sitio web o blog con tan sólo unos clics.

Si tienes una aplicación para alguna de estas categorías, no dudes en dejarnos un comentario sobre ella, muchos usuarios lo agradecerán.

0

0
 

Google Documents List Data API

Python Language Guide (v3.0) – Google Documents List Data API v3.0 – Google Code:

Python Language Guide (v3.0)

In addition to providing some background on the capabilities of the Documents List Data API, this guide provides examples for interacting with the API using the Python client library. If you’re interested in understanding more about the underlying protocol used by the Python client library to interact with the Documents List, please see the protocol guide.

Important: The Google Documents List Data API v3.0 is in Labs, and its features might change unexpectedly until it graduates. Version 2.0 is the latest graduated version.

  1. Audience
  2. Getting started
  3. Retrieving folder contents
  1. Copying documents

Audience

This document is intended for developers who want to write client applications using the Google Data Python client library that interact with Google Documents.

Getting started

Google Documents uses Google Accounts for authentication, so if you have a Google account you are all set. Otherwise, you can create a new account.

Installing the library

To use the Python client library, you’ll need Python 2.2+ and the modules listed on the DependencyModules wiki page. After downloading the client library, see Getting Started with the Google Data Python Library for help installing and using the Python client.

Setting up your own project

To include the examples in this guide into your own code, you’ll need the following import statements:

import gdata.docs.data
import gdata.docs.client

You will also need to setup a DocsClient object, which represents a client connection (with authentication) to the Documents List API.

client = gdata.docs.client.DocsClient(source='yourCo-yourAppName-v1')
client.ssl = True  # Force all API requests through HTTPS
client.http_client.debug = False  # Set to True for debugging HTTP requests

The source argument is optional and should follow the format: company-applicationname-version. It’s recommended to include this parameter for logging purposes.

Note: The rest of the guide assumes you created a DocsClient in the variable client.

Authenticating to the Documents List API

The Python client library can be used to work with either public or private feeds, however the Documents List Data API only provides access to private feeds. That means your client application must send authenticated requests to the API. This can be done via ClientLogin username/password authentication, AuthSub, or OAuth.

Please see the Google Data APIs Authentication Overview for more information on AuthSub, OAuth, and ClientLogin.

Tip: The API supports SSL (HTTPS). If you’re using AuthSub/OAuth, make sure to specify a scope of https://docs.google.com/feeds/ in order to request feeds over SSL. You can force all API requests to be over HTTPS by setting the DocsClient‘s ssl property: client.ssl = True.

AuthSub for web applications

AuthSub Authentication for Web Applications should be used by client applications which need to authenticate their users to Google or Google Apps accounts. The operator does not need access to the username and password for the Google Docs user – only an AuthSub token is required.

View instructions for incorporating AuthSub into your web application

OAuth for web or installed/mobile applications

OAuth can be used as an alternative to AuthSub, and is intended for web applications. OAuth is similar to using the secure and registered mode of AuthSub in that all data requests must be digitally signed and you must register your domain.

View instructions for incorporating OAuth into your installed application

ClientLogin for installed/mobile applications

ClientLogin should be used by installed or mobile applications which need to authenticate their users to Google accounts. On first run, your application prompts the user for their username/password. On subsequent requests, an authentication token is referenced.

View instructions for incorporating ClientLogin into your installed application

Back to top

Retrieving a list of documents

To fetch a feed containing a list of the currently authenticated user’s documents, call the client’s GetDocList() method. By default, this method queries the main doclist feed URI:

https://docs.google.com/feeds/default/private/full

You can pass GetDocList() an optional customized query URI and/or limit for the maximum number of results to return within a page.

Here is an example of querying the user’s doclist and printing the title, type, and resource id of a document:

def PrintFeed(feed):
  print '\n'
  if not feed.entry:
    print 'No entries in feed.\n'
  for entry in feed.entry:
    print entry.title.text.encode('UTF-8'), entry.GetDocumentType(), entry.resource_id.text

    # List folders the document is in.
    for folder in entry.InFolders():
      print folder.title

feed = client.GetDocList()
PrintFeed(feed)

The resulting feed is a gdata.docs.data.DocList containing a list of gdata.docs.data.DocsEntry. Each entry represents a document (spreadsheet, presentation, word processor document, pdf, etc.) in the user’s document list. The DocsEntry encapsulates the information shown in the protocol developer’s guide.

Document resource ID

This guide often refers to the notion of a “document ID” and a document “resource ID”. The resource ID can be used in a number of places, most notably when exporting the document or querying for the entry again. Each resource ID includes the type of document and the document’s unique ID. It can be found as a property of a gdata.docs.data.DocsEntry object:

entry.resource_id.text

The document ID is the alphanumeric portion of the resource ID: everything following the ‘:’ or ‘%3A’. It is recommend that you store a document’s full resource ID rather than just the document ID because the type is included within the entire resource ID.

Paging through results

By default the API will return the first 100 documents in the user’s document list. This saves bandwidth and improves performance. To retrieve the rest of the user’s docs, your client needs to page through the results by following the feed.GetNextLink(). Alternatively, the library’s GetEverything() method can be used to fetch the entire list:

docs = client.GetEverything()  # makes multiple HTTP requests.
print 'User has a total of %s documents in their account' % len(docs)
for doc in docs:
  print doc.title.text, ' - ', doc.GetDocumentType()

Retrieving a entry or resource again

If you want to retrieve a document entry that you’ve retrieved before, you can improve efficiency by telling the server to send the entry only if it has changed since the last time you retrieved it.

To do this sort of conditional retrieval, call the GetDoc() with the document’s resource id and the entry’s ETag (entry.etag). For example:

import gdata.client

try:
  doc = client.GetDoc('document%3A0AdkQLCU4KIBYZGZya2o4NGdfMTQ2NWhiemZjZ2M5', etag='"WEwVFBBDBSp7ImBr"')
except gdata.client.NotModified, error:
  print error

When the server receives this request, it checks to see whether the item that you requested has the same ETag as the one you specified. If the ETags match, then the item hasn’t changed, and the server returns either an HTTP 304 Not Modified status code or an HTTP 412 Precondition Failed status code. Both of those status codes indicate that the item you just retrieved is up-to-date.

If the ETags don’t match, then the item has been modified since the last time you requested it, and the server returns the updated entry.

For more information about ETags, see the Google Data APIs Reference Guide.

Back to top

Searching the documents feed

You can search the Document List using some of the standard Google Data API query parameters. Categories are used to restrict the type of document (spreadsheet, folder, etc.) returned. The full-text query string (q parameter) is used to search the content of all the documents. More detailed information on parameters specific to the Documents List can be found in the Documents List Data API Reference Guide.

Retrieving all documents and folders

A list of all the user’s document and folders can be retrieved by addingthe showfolders=true parameter to the main doclist URI:

feed = client.GetDocList(uri='/feeds/default/private/full?showfolders=true')

Retrieving all word processor documents

A list of only word processor documents can be retrieved by using the document category as follows:

feed = client.GetDocList(uri='/feeds/default/private/full/-/document')

Retrieving all spreadsheets

A list of only spreadsheets can be retrieved by using the spreadsheet category as follows:

feed = client.GetDocList(uri='/feeds/default/private/full/-/spreadsheet')

Category queries can work for other document types as well. For a list of possible categories, see the Reference Guide.

Retrieving all presentations that I own

A list of pdfs the user’s owns can be queried with the pdf and mine categories:

feed = client.GetDocList(uri='/feeds/default/private/full/-/pdf/mine')

Retrieving a list of folders

A list of only folders can be retrieved by using the folder category:

feed = client.GetDocList(uri='/feeds/default/private/full/-/folder')

Retrieving a certain arbitrary file type

To return a list of arbitrary files of mimetype application/msword, send a category query that includes the scheme and content type:

feed = client.GetDocList(uri='/feeds/default/private/full/-/{http://schemas.google.com/g/2005#kind}application/msword')

Note, this URL needs to be fully URL encoded:

feed = client.GetDocList(
    uri='/feeds/default/private/full/-/%7Bhttp%3A%2F%2Fschemas.google.com%2Fg%2F2005%23kind%7Dapplication%2Fmsword')

More example queries can be found in the protocol guide.

Performing title queries

It is possible to retrieve documents by matching on their title rather than contents. To do this, add the title parameter query URI. To match a title exactly, add a title-exact=true parameter to indicate this is the full, explicit title. Since this parameter is case-insensitive and since multiple docs can have the same title, a feed is returned.

feed = client.GetDocList(uri='/feeds/default/private/full?title=Test&title-exact=true&max-results=5')

Note: title-exact queries are case-insenstive. For example, the sample above will print documents that match “Test”, “test”, and “TeSt”, but not “Test title”.

Performing a full text query

You can also search the contents of documents by using the q parameter:

feed = client.GetDocList(uri='/feeds/default/private/full?q=example+query')

This searches the entire contents of every document for the string “example query” and returns all documents where this string is found. This is different than searching just the title of every document, which can be done as described in the section Performing title queries.

Back to top

Retrieving folder contents

To retrieve a list of items in a particular folder, pass the GetDocList() method a folder’s content feed URI:

https://docs.google.com/feeds/default/private/full/folder%3Afolder_id/contents

A folder’s content feed can be found as entry.content.src on a folder entry. Each folder entry in the documents list will contain such a link.

The following example queries for a list of folders, fetches the items contained in the first result, and prints the title and folders the resource is in:

feed = client.GetDocList(uri='/feeds/default/private/full/-/folder')
folder = feed.entry[0]

print 'Contents of folder: ' + folder.title.text
feed = client.GetDocList(uri=folder.content.src)
for doc in feed.entry:
  print doc.title.text, [f.title for f in doc.InFolders()]

By default, folder entries will be returned within the folders feed (e.g. you don’t have to include the showfolders=true parameter. The folders feed can also be queried using the query parameters defined in the Documents List Data API Reference Guide.

Querying for resources at the root folder level

You can query for a list of documents/folders at the root level by using folder:root as the folder feed’s resource ID. For example:

feed = client.GetDocList(uri='/feeds/default/private/full/folder%3Aroot/contents/-/folder')

Back to top

Uploading documents

Creating an empty document

The API allows for creating empty documents using the Create() method. The examples below create a few documents (of various types) in the user’s doclist.

# Create an empty document
new_doc = client.Create(gdata.docs.data.DOCUMENT_LABEL, 'My Doc')
print 'Document "%s" created' % new_doc.title.text

# Create an empty spreadsheet. By default, the writers_can_invite setting is True.
new_spreadsheet = client.Create(gdata.docs.data.SPREADSHEET_LABEL, 'My Spreadsheet', writers_can_invite=False)
print 'Spreadsheet "%s" created' % new_spreadsheet.title.text

# Create an empty presentation
new_preso = client.Create(gdata.docs.data.PRESENTATION_LABEL, 'My Presentation')
print 'Presentation "%s" created' % new_preso.title.text

Uploading documents with content

The Python client library provides an Upload() method for uploading documents to Google Docs. You can choose to use a gdata.data.MediaSource object or pass the file name directly. For more information on the MediaSource class, please use the Python built-in documentation system:

import gdata.data
help(gdata.data.MediaSource)

For your convenience, there is a static dictionary member in the gdata.docs.data module named MIMETYPES. It maps upper-case file extensions to their common MIME types.

This example uploads a word processor document, assuming file_path is the path to a valid document. The entry returned from the upload is a gdata.docs.data.DocsEntry object containing information about the document that was created on the server.

ms = gdata.data.MediaSource(file_path='/path/to/your/test.doc', content_type='application/msword')
entry = client.Upload(ms, 'MyDocTitle')
print 'Document now accessible online at:', entry.GetAlternateLink().href

Similarly, you can pass in the file name directly to Upload():

entry = client.Upload('/path/to/your/test.doc', 'MyDocTitle', content_type='application/msword')
print 'Document now accessible online at:', entry.GetAlternateLink().href

If passing a filename, always provide the content type.

Creating/uploading documents to folders

Both Create() and Upload() accept an additional keyword arg for specifying a folder to create/upload a document to.

Creating an empty document in a folder

To create an empty document, presentation, or spreadsheet in an existing folder, pass Create() a DocsEntry object or resource ID representing the destination folder.

new_doc = client.Create(gdata.docs.data.DOCUMENT_LABEL, 'MyDocTitle', folder_or_id=dest_folder)

It is assumed dest_folder is a gdata.docs.data.DocsEntry object representing the destination folder.

Uploading a document to a folder

Similar to creating a document inside a folder, you can upload an existing resource directly into a folder by passing Upload() a DocsEntry object or full URI of the destination folder.

new_spreadsheet = client.Upload('/path/to/your/test.csv', 'MyDocTitle', content_type='text/csv', folder_or_uri=dest_folder)

It is assumed dest_folder is a gdata.docs.data.DocsEntry object representing the destination folder.

Uploading files of any type

Note: This feature is only available to Google Apps Premier domains.

Google Apps Premier domains can upload files of arbitrary type. Uploading an arbitrary file is the same as uploading documents (with and without metadata), except there is no restriction on the file’s Content-Type. Unlike normal document uploads, arbitrary file uploads preserve their original format/extension, meaning there is no loss in fidelity when the file is stored in Google Docs.

By default, uploaded document files will be converted to a native Google Docs format. For example, an .xls upload will create a Google Spreadsheet. To keep the file as an Excel spreadsheet (and therefore upload the file as an arbitrary file), specify the convert=false parameter to preserve the original format. The convert parameter is true by default for document files. The parameter will be ignored for types that are not convertible (e.g. .exe, .mp3, .mov, etc.).

Here is an example of uploading a .doc file as an arbitrary file:

import os.path

f = open('/path/to/your/test.doc')
ms = gdata.data.MediaSource(file_handle=f, content_type='application/msword', content_length=os.path.getsize(f.name))
entry = client.Upload(ms, f.name, folder_or_uri=client.DOCLIST_FEED_URI + '?convert=false')

A list of common mimetypes can be found here.

All document entries will be marked with a field that indicates the amount of quota a file is using: entry.quota_bytes_used.text. File size limits for arbitrary uploads are posted in the Google Docs Help Center.

Back to top

Copying documents

Note: The copy feature is only available for document, spreadsheet, and presentation types. Other formats (e.g. PDFs) do not support the copy command.

To duplicate a document in a user’s document list, set the entry.id.text to the source entry’s self link (source_entry.GetSelfLink().href). The library has a Copy() method to do this for you.

duplicated_entry = client.Copy(source_entry, 'MyTwin')

Note: A document cannot be copied directly into a folder. Instead, first issue the copy command, followed by a move operation. See Moving a resource into a folder.

Back to top

Updating existing documents

Updating documents requires the use of ETags to make sure you are not overwriting another client’s changes. An entry’s ETag can be found by calling entry.etag.

Note: If you want to update a document regardless of whether someone else has updated it since you last retrieved it, substitute "*" for the entry’s ETag value or include the force=True argument on the call to Update(). That will force a unconditional delete on the entry.

For more information on ETags, see the Google Data APIs Reference Guide.

Updating metadata

Here is an example of updating a presentation’s metadata, but leaving its content unchanged. The presentation’s name will be changed to ‘Better presentation title’. Simply pass your modified entry to the client’s Update() method.

existing_entry.title.text = 'Better presentation title'
updated_entry = client.Update(existing_entry)

# To force the update, even if another client has made changes.
# updated_entry = client.Update(existing_entry, force=True)

Replacing a document’s content

To update a document’s content, use the Atom entry’s edit-media link. The following example replaces the document’s content with replacementContent.doc’s content, and updates the document’s title to ‘updated document’ in the same request.

import gdata.data

# Load the replacement content in a MediaSource. Also change the attachment's title and description.
ms = gdata.data.MediaSource(file_path='/path/to/replacementContent.doc', content_type='application/msword')
entry.title.text = 'updated document'

updated_entry = client.Update(entry, media_source=ms)

print "Document '%s' changed to '%s'" % (entry.title.text, updated_entry.title.text)

Back to top

Deleting documents and folders

Trashing a document or folder

To trash a document or folder, use the Delete() method of the client object on the edit link of the Atom entry representing the document. For example, to trash one of the new documents from the upload examples above, you would execute the following.

client.Delete(entry)

# To force the update, regardless of another client's changes:
# client.Delete(entry, force=True)

If the document was deleted successfully, the server responds with an HTTP 200 OK.

Deleting a document or folder

Deleting a document or folder permanently removes the object from the user’s documents list. The process for deleting a document is similar to trashing a document, just include the delete=true parameter.

client.Delete(entry.GetEditLink().href + '?delete=true', force=True)

Back to top

Downloading and exporting documents

To export documents from the Documents List feed, you need an entry object or the resource ID (e.g. document:12345) of the document, spreadsheet, or presentation.

Tip: You can use the gdata.client.DocsClient.GetFileContent() method to return a files contents in memory (rather than writing it to local disk). The examples below write the file to disk.

Exporting word processor documents

The following example fetches a document by its resource id, and exports the entry as a .doc file:

entry = client.GetDoc('document%3A0AdkQLChiemZjZ2M5')

file_path = '/path/to/save/your_document.doc'
print 'Exporting document to %s...' % file_path

client.Export(entry, file_path)
print 'Exported %s as a .doc file' % entry.title.text

Alternatively, you can pass in the resource id, as the Export helper method also accepts that. The following example exports the same resource as a .html file:

file_path = '/path/to/save/your_document.html'
print 'Exporting document to %s...' % file_path

client.Export('document%3A0AdkQLChiemZjZ2M5', file_path)
print 'Exported document as a .doc file'

Exporting presentations

The following example exports a presentation entry as a .swf file:

file_path = '/path/to/save/your_presentation.swf'
print 'Downloading presentation to %s...' % file_path
client.Export(entry, file_path)

Exporting spreadsheets

The following example exports a spreadsheet entry as an .xls file:

file_path = '/path/to/save/your_spreadsheets.xls'
print 'Downloading spreadsheet to %s...' % file_path
client.Export(entry, file_path)

When exporting to .csv or .tsv, you can specify which grid/sheet to download by using the gid argument:

file_path = '/path/to/save/your_spreadsheets.csv'
print 'Downloading spreadsheet to %s...' % file_path
client.Export(entry, file_path, gid=1)  # export the second sheet

Important: In order to download spreadsheets, your client needs a valid token for the Spreadsheets API service. See the downloading spreadsheets section of the protocol guide for more details.

Exporting Spreadsheets using AuthSub/OAuth

If you’re using AuthSub, request a multi-scoped token, good for both the Documents List API and the Spreadsheets API. Pass in scope=['https://docs.google.com/feeds/', 'https://spreadsheets.google.com/feeds/'] to gdata.gauth.generate_auth_sub_url().

Exporting Spreadsheets using ClientLogin

For ClientLogin, first create a SpreadsheetsService object (to obtain a spreadsheets token), and then swap that token into your DocsClient object. This example demonstrates that process:

import gdata.spreadsheet.service

spreadsheets_client = gdata.spreadsheet.service.SpreadsheetsService(source='yourCo-yourAppName-v1')
spreadsheets_client.ClientLogin('[email protected]', 'pa$$word', client.source)

# substitute the spreadsheets token into our client
docs_token = client.auth_token
client.auth_token = gdata.gauth.ClientLoginToken(spreadsheets_client.GetClientLoginToken())

client.Export(entry, file_path)

client.auth_token = docs_token  # reset the DocList auth token

Downloading PDFs and arbitrary files

PDF and arbitrary files cannot be exported in a format other than the format they are stored in. It is also not possible to manually construct the download URL for these types of files. Instead, your client can use the Download() method to send an HTTP GET to the entry’s content ‘src’ link:

entry = client.GetDoc('pdf%3A0B9kQLCU4KIBNzA4NTQ4NTdhYmM4')
client.Download(entry, '/path/to/save/%s.pdf' % entry.title.text)
print 'Downloaded pdf'

Tip: You can use the gdata.client.DocsClient.GetFileContent() method to return a file’s contents in memory (rather than writing it to local disk). The examples below write the file to disk.

Back to top

Folder management

Creating folders

The Create() helper can also be used to create a folder. Simply pass it a folder category and folder name:

new_folder = client.Create(gdata.docs.data.FOLDER_LABEL, 'My Folder')
print 'Folder "%s" created' % new_folder.title.text

To create a folder inside another folder, pass in a parent folder entry (or resource ID) as the folder_or_id kwarg. This example will create a new subfolder named ‘SubFolder’ under the previous example ‘My Folder’:

sub_folder = client.Create(gdata.docs.data.FOLDER_LABEL, 'SubFolder', folder_or_id=new_folder)

Moving documents and folders

Moving a document into a folder requires that you have a gdata.data.DocsEntry object for the document, and another for the folder to which the document should be moved. The DocsClient module provides a Move() method for moving resources in and out of folders.

source_doc = client.GetDoc('document%3A0AdkQLCU4KIBYZGZya2o4NGdfMTQ2MmdkbW1wamM3')
dest_folder = client.GetDoc('folder%3A0B9kQLCU4KIBYZWM4YjIwMjYtZDI1My00YWM4LWE1ZDktZTZjOGVjMzJkNjYz')
new_entry = client.Move(source_doc, dest_folder)
print '%s moved into %s' % (source_doc.title.text, dest_folder.title.text)

The first argument to Move() is a DocsEntry object representing the source folder or document to relocate. The second argument is a DocsEntry object representing the destination folder.

Note: This method performs a true move; meaning the resource will be removed from any folder(s) it is currently in. To add a resource to an additional folder, be sure to specify the keep_in_folders=True keyword argument.

This example removes a document from the folder(s) it is in, moving it to the root level:

was_moved = client.Move(source_doc)
print '%s moved to root level' % source_doc.title.text

Back to top

Modifying Document Sharing Permissions

Overview of Sharing (ACLs)

Document and folder sharing is controlled via the access control list feed. Access control lists are just basic lists that show who has access to a given resource. In the ACL feed, we have the following roles for a given document or folder:

  • owner — the owner of the document. As an owner you have the ability to modify the ACL feed, delete the document, etc.
  • writer — a collaborator.
  • reader — a viewer (equivalent to read-only access).

Note: Please note that the accepted values for each role are case-sensitive.

The API supports sharing permissions on multiple levels. These values correspond to the acl_entry.scope.type attribute:

  • user — a user’s email address.
  • group — a Google Group email address.
  • domain — a Google Apps domain.

Retrieving the ACL feed for a document

The GetAclPermissions() method can be used to retrieve the sharing permissions for a document. To retrieve the permission for a given resource, you need the acl feed link: doc_entry.GetAclFeedLink().

The following example fetches the first document the authenticated user owns, queries its ACL feed, and prints out the permission entries:

feed = client.GetDocList(uri='/feeds/documents/private/full/-/mine?max-results=1')
acl_feed = client.GetAclPermissions(feed.entry[0].resource_id.text)
for acl in acl_feed.entry:
  print '%s (%s) is %s' % (acl.scope.value, acl.scope.type, acl.role.value)

Modifying the ACL feed for a document

Adding a new permission

To add a new permission to a document, your client needs to create a new gdata.docs.data.Acl and POST it to the server.

Here’s an example that adds ‘[email protected]’ as a reader to a document represented by doc_entry:

import gdata.acl.data

scope = gdata.acl.data.AclScope(value='[email protected]', type='user')
role = gdata.acl.data.AclRole(value='reader')
acl_entry = gdata.docs.data.Acl(scope=scope, role=role)

new_acl = client.Post(acl_entry, doc_entry.GetAclFeedLink().href)
print "%s %s added as a %s" % (new_acl.scope.type, new_acl.scope.value, new_acl.role.value)

Possible values for the Role are reader, writer, and owner.

Group and Domain level sharing

Similar to sharing with a single user, you can share documents or folders across a Group or domain if you have a Google Apps domain.

To share a resource or folder with an entire Google Apps domain, set the AclScope as such:

scope = gdata.acl.data.AclScope(value='example.com', type='domain')

Note: Certain sharing ACLs may only be possible if the domain is configured to allow such permissions (e.g. if sharing outside of the domain for Google Apps domains is enabled, etc).

To share a document or folder with a Google Group mailing list, set the AclScope as such:

scope = gdata.acl.data.AclScope(value='[email protected]', type='group')

Updating sharing permissions

We can update the ACL entry that was just added by calling Update() with the updated ACL entry.

This example modifies our previous acl_entry by updating ‘[email protected]’ to be a writer (collaborator):

acl_entry.role.value = 'writer'
updated_acl = client.Update(acl_entry)

# To force the update, even if you do not have the latest changes to the entry:
# updated_acl = client.Update(acl_entry, force=True)

Removing sharing permissions

To remove an existing sharing permission, first retrieve the AclEntry, then call the client’s Delete() method. For example:

acl_entry = client.GetAclPermissions('presentation%3A0A1234567890').entry[0]
client.Delete(acl_entry)

You can also pass the ACL entry’s edit link instead of an entry object, and/or force the deletion with force=True:

# force=True sets the If-Match: * header instead of using the entry's ETag.
client.Delete(acl_entry.GetEditLink().href, force=True)

For more information about ETags, see the Google Data APIs Reference Guide.

Back to top

Document Revisions

Retrieving document revisions

Document revisions are available via the revisions feed. Similar to the <gd:feedLink> for ACLs, every document entry will have a <gd:feedLink> pointing to the revisions feed:

revision_feed_link = entry.GetRevisionsFeedLink().href

To fetch the revision history for a given document, use the GetRevisions() method, passing it a resource ID:

revision_feed = client.GetRevisions('spreadsheet%3A0A1234567890')

The server will respond with a gdata.docs.data.RevisionFeed containing a list of gdata.docs.data.Revision entries.

Properties of a revision entry:

  • The entry.updated.text field is the timestamp a revision was created.
  • The entry.author[0].email.text field is the creator of that revision.
  • An entry.publish element will be present and its value attribute set to “true” if the revision is published. The entry’s published link can be accessed by revision_entry.GetPublishLink().href
  • A entry.publish_auto element will be present if the revision is published. Its value attribute will be set to “true” if the “Automatically re-publish when changes are made” checkbox has been selected in the Google Docs UI.
  • A entry.publish_outside_domain field will be present if the revision is published and the document is in a Google Apps domain. Its value property will be set to “true” (the default) if the document has been published outside of the domain.

Note: While document and presentation revisions have an auto-incrementing revision number, this may have gaps if revisions are deleted so you should not rely on a consecutive numbering. Spreadsheet revisions look almost identical, but their revision IDs are not zero-based and auto-incrementing – instead they are based on the revision’s timestamp, and so they will be an increasing series of seemingly random numbers.

Downloading a revision

The <atom:content> field’s ‘src’ attribute can be used to download a particular revision. In the case of a native Google Document format, you can also download the document in the API’s supported exportFormats:

entry.content.src

See the Downloading documents section for examples of how to download/export documents.

Note: You will need a valid AuthSub/OAuth or ClientLogin token valid for the appropriate service. See the Downloading and exporting documents section.

Publishing documents

Note: The publishing features are only available for document, spreadsheet, and presentation types. Other formats (e.g. PDFs) do not support the publishing commands.

The API supports the following modifications to a document’s published settings:

  1. Publish/unpublish a document
  2. Publish a document at a different revision
  3. Change whether document changes are auto-republished
  4. Change whether documents are published outside of a Google Apps domain

To change the published settings on a document, fetch the revision entry in question, modify the publish properties of the entry, and call the client’s Update() method.

This example fetches the revision feed for a document, and publishes the first revision by modifying its publish settings:

# Fetch document document%3A0AdkQp0MnpnZjQz's revision feed.
revision_feed = client.GetRevisions('document%3A0AdkQp0MnpnZjQz')
entry = revision_feed.entry[0]

# Modify the first revision entry's publised settings.
entry.publish = gdata.docs.data.Publish(value='true')
entry.publish_auto = gdata.docs.data.PublishAuto(value='false')

# Send the modified entry to the server.
updated_entry = client.Update(entry, force=True)
print 'Revision published at %s' % updated_entry.GetPublishLink().href

Note that entry.publish_auto.value must be set to “false” in order to publish a version other than the latest version. If you try to publish a revision and publish_auto is set to “true”, the document’s head revision will still be the version published.

Note: Unless you are unpublishing a document, the revision entry should include all published elements: publish, publish_auto (and publish_outside_domain if in a Google Apps domain). Also, whether or not a document can be published outside the domain will be determined by the domain’s policy settings in the Google Apps control panel.

0

0
 

mooshell-Django application to test web development frontends

mootools’s mootools-shell at master – GitHub:

README
Test you mootools code.
Django application.
0

0
 

Genshi and web2py

GenshiRecipes/web2py – Genshi:


GenshiRecipes/web2py

web2py allows for almost seemless integration with Genshi.

The first thing to do, after you’ve installed  web2py and Genshi, is to save the code below into a module named Genshi4web2py.py and place it somewhere in your PYTHONPATH (site-packages or in the root of web2py).

#!/usr/bin/env python

'''
The Genshi4web2py module provides Genshi markup templating functionality to the
web2py framework.  It does not provide Genshi's text-based templating since
web2py's built-in template is so similar, it would be redundant.

To enable Genshi templating on a controller basis, put the following code in
your controller::

    from Genshi4web2py import render
    response.postprocessing.append(lambda x: render(x, request, response))

If you would prefer to enable Genshi for a complete Application, the above code
can be placed in a model file.  This module can also make use of web2py's
cache system for a large speed boost.  To do so pass cache to render like so::

    response.postprocessing.append(lambda x: render(x, request, response, cache=cache))

Note that using the cache for templates will cause frustration in a development 
environment since changes to a view will only be reflected when the cache
refreshes (the default is every 10 minutes).

@var regex_include: a compiled regular expression used to identify Genshi 
    templates.
@var Genshi: indicates if Genshi support is enabled
@var READLIMIT: the max number of bytes of a template to read when identifying
    a template as a Genshi template
'''
import re
import os
import types

try:
    from genshi.template import TemplateLoader, Context, TemplateNotFound, TemplateSyntaxError
    from genshi.filters.html import HTMLFormFiller
    from genshi import HTML
    Genshi = True
    READLIMIT=512
    regex_include=re.compile('(?P<all>(?:\{\{\s*include\s+[\'"]|' +
                             '<xi:include\s+href=[\'"])(?P<name>[^\'"]*)' +
                             '[\'"]\s*(?:\}\}|(?:/>|>\s*</xi:include>)))')
except ImportError, e: Genshi = False

def render(vars, request, response, **kwargs):
    '''Renders the controller output with a Genshi Template

    B{Render Options} - "renderOptions" can be specified as a dictionary in 
    L{vars}.  It is used to specify certain options the rendering engine 
    should use.  Specifying any of these is optional.  Below are the specific 
    valid rendering options::

        - B{viewdirs}: a list of paths to template folders in which to look 
            for views
        - B{view}: the name of the view to use for the controller calling 
            L{render}
        - B{Content-Type}: the Content-Type header as it should be sent to 
            the browser
        - B{HTMLFormFill}: a dictionary of values used to fill elements of 
            forms in side the template after template parsing
        - B{GenshiDoctype}: the doctype that Genshi will apply to the resulting 
            rendered output
        - B{GenshiRenderEngine}: the engine Genshi will use to render the view

    @type vars: dict
    @param vars: a dictionary of variables to pass to the template
    @param request: the web2py request instance.  Used to determine the current
        application folder
    @param response: the web2py response instance.  Used to set headers if
        needed.
    @type kwargs: dict
    @param kwargs: any additional keyword arguments will be made available for
        the run environment of the view.

    @returns: If the template exists and is valid, a normal string will be
        returned; otherwise the passed L{vars} will be returned to be parsed by
        a downstream template renderer.

    @raises TemplateSyntaxError: In the event that a template has a syntax
        error, a TemplateSyntaxError will be raised.
    '''

    if type(vars) == types.StringType:
        return vars

    cache = kwargs.get('cache', None)
    appfolder = os.path.dirname(os.path.normpath(request.folder))
    initview = os.path.join(appfolder, 'init', 'views')
    viewdirs = [ os.path.join(request.folder, 'views') ]

    if os.path.exists(initview) and viewdirs[0] != initview:
        viewdirs.append(initview)

    opts = {'viewdirs': viewdirs
            ,'view':response.view
            ,'Content-Type':"text/html; charset=utf-8"
            ,'GenshiDoctype':'html'
            ,'GenshiRenderEngine':'html'
            ,'HTMLFormFill':vars.get('HTMLFormFill')
            }

    if vars.get('renderOptions'):
        opts.update(vars['renderOptions'])

    cachekey = ''.join(opts['viewdirs'])
    if cache:
        loader = cache.ram(cachekey
                           , lambda:TemplateLoader(opts['viewdirs']
                                                   , auto_reload=False))
    else:
        loader = TemplateLoader(opts['viewdirs'], auto_reload=False)

    try:
        if cache:
            output = cache.ram(cachekey+opts['view']
                               , lambda:loader.load(opts['view']))
        else:
            output = loader.load(opts['view'])
    except TemplateNotFound, e:
        return vars
    except TemplateSyntaxError, e:
        f = open(os.path.normpath(e.filename)).read(READLIMIT)
        if not regex_include.search(f):
            return vars
        else:
            raise e

    ctxt = Context(request=request, response=response, HTML=HTML)
    ctxt.update(vars)
    ctxt.update(kwargs)
    output = output.generate(ctxt)
    if opts.get('HTMLFormFill'):
        try:
            output = output.filter(HTMLFormFiller(data=opts['HTMLFormFill']))
        except:
            pass
    output = output.render(opts['GenshiRenderEngine']
                           , doctype=opts['GenshiDoctype'])

    response.headers['Content-Type']=opts['Content-Type']
    return output

(You may also follow the instructions in the docstring of the module for usage instructions.)

Second, create an application in web2py. There are two ways to hook Genshi into web2py, application-wide or controller-wide. In either case, the inclusion code looks like:

    from Genshi4web2py import render
    response.postprocessing.append(lambda x: render(x, request, response))

If you wish to use Genshi throughout that application, then you can place this code in a model file so that it is executed for every controller in the application. If, however, you wish to only use it with one controller, include this code somewhere in the controller.

To invoke Genshi there is nothing more to do, simply make your controllers as you would if using normal web2py templates and make your views as Genshi templates. Genshi4web2py will look for the view corresponding to the running controller and detect if it is a Genshi template. If so, it will render it, otherwise it will pass it on to the internal web2py template renderer.

0

0
 

Advanced WMD : The Wysiwym Markdown Editor

wmd – Advanced Demo:

Advanced WMD Demo

This demo uses CSS and a little JavaScript to show a side-by-side comparison of WMD’s input and output. Switch the window on the right from Preview to HTML Output to see the markup that WMD produces.

Site owners can configure WMD to submit text in either HTML or Markdown.

This example is also a quick way to write HTML. Start with a blank page and enter your text; when you’re done, just copy the HTML output to the clipboard.


wmd-1.0.1.zip

wmd.googlecode.com


0

0
 

API Embed.ly Python y JQuery

#!/usr/bin/env python
import urllib
import urllib2
try:
    import json
except ImportError:
    try:
        import simplejson as json
    except ImportError:
        raise ImportError("Need a json decoder")
ACCEPTED_ARGS = ['maxwidth', 'maxheight', 'format']
def get_oembed(url, **kwargs):
    """
Example Embedly oEmbed Function
"""
    api_url = 'http://api.embed.ly/v1/api/oembed?'
    params = {'url':url }
    for key, value in kwargs.items():
        if key not in ACCEPTED_ARGS:
            raise ValueError("Invalid Argument %s" % key)
        params[key] = value
    oembed_call = "%s%s" % (api_url, urllib.urlencode(params))
    return json.loads(urllib2.urlopen(oembed_call).read())
if __name__ == "__main__":
    urls = ["http://vimeo.com/9503416",
            "http://twitpic.com/13whni"]
    for url in urls:
        print "\n\nurl: %s\n" % url
        print get_oembed(url)
0

0
 

API Call Using JavaScript with JQuery

 // Call API to get a video oEmbed JSON response
var url = escape('http://vimeo.com/9503416');
var api_url = 'http://api.embed.ly/v1/api/oembed?url=' + url + '&callback=?';
//jQuery JSON call
$.getJSON( api_url, function(json) {
    var html = json.html;
    $('#videodiv').html(html);
});

0

0