=== added directory 'extensions/video-downloader'
=== added file 'extensions/video-downloader/Makefile.am'
--- old/extensions/video-downloader/Makefile.am	1970-01-01 00:00:00 +0000
+++ new/extensions/video-downloader/Makefile.am	2009-01-07 16:44:21 +0000
@@ -0,0 +1,16 @@
+extensionsdir = $(EXTENSIONS_DIR)
+extensions_PYTHON = \
+	video-downlaoder.py
+
+extensionsinidir = $(EXTENSIONS_DIR)
+extensionsini_in_files = \
+	video-downlaoder.ephy-extension.in	
+extensionsini_DATA = $(extensionsini_in_files:.ephy-extension.in=.ephy-extension)
+
+@EPIPHANY_EXTENSION_RULE@
+
+EXTRA_DIST = \
+	$(extensionsini_in_files)
+
+CLEANFILES = $(extensionsini_DATA)
+DISTCLEANFILES = $(extensionsini_DATA)

=== added file 'extensions/video-downloader/video-downloader.ephy-extension.in'
--- old/extensions/video-downloader/video-downloader.ephy-extension.in	1970-01-01 00:00:00 +0000
+++ new/extensions/video-downloader/video-downloader.ephy-extension.in	2009-01-07 16:42:14 +0000
@@ -0,0 +1,10 @@
+[Epiphany Extension]
+_Name=Video Downloader
+_Description=Downloads embeded Youtube videos (and other video hosting sites) via clive.
+Authors=Adam Schmalhofer <schmalho@users.berlios.de>
+Version=1
+URL=http://blauebirke.wordpress.com/2008/09/09/epiphany-video-download-extension/
+
+[Loader]
+Type=python
+Module=video-downloader

=== added file 'extensions/video-downloader/video-downloader.py'
--- old/extensions/video-downloader/video-downloader.py	1970-01-01 00:00:00 +0000
+++ new/extensions/video-downloader/video-downloader.py	2009-01-07 16:24:32 +0000
@@ -0,0 +1,335 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Epiphany extension: Video downloader; 
+# Based on Creative Commons license viewer [Version 0.2 (27/07/2006)]
+#    Copyright (C) 2006 Jaime Frutos Morales <acidborg@gmail.com>
+# Copyright (C) 2008 Adam Schmalhofer <schmalho@users.berlios.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""
+An extension for the GNOME Web Browser 'Epiphany'. It searches the page as well
+as the URL in the address bar for known video hosting sites. These embeded 
+videos then can be via clive.
+"""
+
+CLIVE_VERSION = 1
+
+import re
+import gconf
+from subprocess import Popen, PIPE
+from os import path
+
+import epiphany
+import gobject
+import pygtk
+pygtk.require('2.0')
+import gtk
+import pynotify
+from pynotify import Notification
+from gettext import gettext as _, ngettext as N_
+
+GCONF_KEY_DOWNLOAD_FOLDER = '/apps/epiphany/directories/downloads_folder'
+GCONF_KEY_USE_PROXY = '/system/http_proxy/use_http_proxy'
+GCONF_KEY_PROXY_PORT = '/system/http_proxy/port'
+GCONF_KEY_PROXY_HOST = '/system/http_proxy/host'
+GCONF_KEY_USE_PROXY_AUTH = '/system/http_proxy/use_authentication'
+GCONF_KEY_PROXY_USER = '/system/http_proxy/authentication_user'
+GCONF_KEY_PROXY_PASSWORD = '/system/http_proxy/authentication_password'
+
+# Each element in EMBEDED_VIDEO_RE_LIST must contain exactly one set of braces.
+EMBEDED_VIDEO_RE_LIST = [
+    r'(?:[a-z]{2,3}\.)?youtube\.[a-z]{2,3}/[^\'"#&]*v[=/]([\w-]{11})',
+    r'video\.google\.com/googleplayer\.swf\?docid=(\d{19})',
+    r'www\.dailymotion\.com/swf/(\w{18})',
+    r'www\.guba\.com/f/root\.swf\?video_url=http://free\.guba\.com/uploaditem/(\d{10})/flash\.flv',
+    r'www\.metacafe\.com/fplayer/(\d{7}/\w+)\.swf',
+    r'(?:[a-z]{2,3}\.)?sevenload\.[a-z]{2,3}/pl/(\w{7})']
+# One element in VIDEO_PAGE_BASE for each in EMBEDED_VIDEO_RE_LIST. 
+# %s is replaced with the string matching the braces in EMBEDED_VIDEO_RE_LIST.
+VIDEO_PAGE_BASE = [
+    r'http://youtube.com/watch?v=%s',
+    r'http://video.google.com/videoplay?docid=%s',
+    r'http://www.dailymotion.com/video/%s',
+    r'http://www.guba.com/watch/%s',
+    r'http://www.metacafe.com/watch/%s',
+    r'http://sevenload.com/videos/%s' ]
+URL_VIDEO_RE_BASE_LIST = [ 
+    r'[a-z]{2,3}\.youtube\.com/watch\?v=[\w-]{11}',
+    r'video\.google\.com/videoplay\?docid=\d{19}',
+    r'www\.dailymotion\.com(/.*)?/video/',
+    r'www\.guba\.com/watch/',
+    r'www\.metacafe\.com/watch/',
+    r'[a-z]{2,3}\.sevenload\.com/(videos|sendungen/[a-z-]+/folgen|shows/[a-z-]+/episodes)/\w' ]
+CLIVE2X_ONLY_URL_VIDEO_RE_BASE_LIST = [ 
+    r'break\.com/[a-z-]+/[a-z-]+\.html',
+    r'www\.evisor\.tv/tv/[a-z0-9_-]+/[a-z0-9_-]+\d{4}\.htm',
+    r'www\.liveleak\.com/view\?i=\d{3}_\d{10}' ]
+if CLIVE_VERSION == 2:
+    URL_VIDEO_RE_BASE_LIST.extend(CLIVE2X_ONLY_URL_VIDEO_RE_BASE_LIST)
+URL_VIDEO_RE = re.compile('^http://(%s)' % 
+        '|'.join(URL_VIDEO_RE_BASE_LIST), re.I)
+EMBEDED_VIDEO_RE = re.compile('http://(%s)' % 
+        '|'.join(EMBEDED_VIDEO_RE_LIST), re.I)
+
+def _switch_page_cb(notebook, page, page_num, window):
+    ui_show(window, window.get_active_child())
+
+def _load_status_cb(embed, data, window):
+    detect_videos_in_address(window, embed)
+    if not embed.get_property('load-status') and not embed._has_video:
+        # page is loaded and url isn't a video hosting page
+        detect_videos_in_page(window, embed)
+    ui_show(window, embed)
+        
+def _video_button_pressed(button, event, window):
+    embed = window.get_active_child()
+    if pynotify.init('Basics'):
+        n = Notification(_('Started downloading.'), 
+                N_('Started to download %s video.', 
+                'Started to download %s videos.', len(embed._video_urls)) % \
+                         len(embed._video_urls) )
+        n.set_urgency(pynotify.URGENCY_LOW)
+        x, y = embed.get_pointer()
+        forget, x, y, forget = gtk.gdk.\
+                screen_get_default().get_display().get_pointer()
+        n.set_hint('x', x)
+        n.set_hint('y', y)
+        n.show()
+    download_videos(window, embed, embed._video_urls)
+
+def ui_init(window):
+    cc_image = gtk.Image()
+    icon_theme = gtk.icon_theme_get_default()
+    pixbuf = icon_theme.load_icon('video', 
+            gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)[0], 0)
+    cc_image.set_from_pixbuf(pixbuf)
+    cc_image.show()
+
+    eventbox = gtk.EventBox()    
+    eventbox.set_visible_window(True)
+    eventbox.connect ("button-press-event", _video_button_pressed, window);
+    # Pack the widgets
+    eventbox.add(cc_image)
+    eventbox.show()    
+
+    statusbar = window.get_statusbar()
+    statusbar.add_widget(eventbox)
+    statusbar._video_eventbox = eventbox
+
+def ui_show(window, embed):
+    if embed != window.get_active_child(): return
+
+    statusbar = window.get_statusbar()
+    eventbox = statusbar._video_eventbox
+    
+    try:
+        if embed._has_video:
+            n = len(embed._video_urls)
+            eventbox.set_tooltip_text(
+                    N_("%s embeded video", "%s embeded videos", n) % n)
+            eventbox.show()
+        else:
+            eventbox.hide()
+    except: 
+        eventbox.hide()
+
+def ui_destroy(window):
+    statusbar = window.get_statusbar()
+    eventbox = statusbar._video_eventbox
+    del statusbar._video_eventbox
+    statusbar.remove_widget(eventbox)
+
+def on_gconf_new_downloads_folder(client, gconf_id, gconf_entry, **kwargs):
+    update_downloads_folder()
+
+def on_gconf_proxy_changed(client, gconf_id, gconf_entry, **kwargs):
+    update_proxy_settings()
+
+def update_proxy_settings():
+    global proxy
+    g = gconf_client
+    if g.get_bool(GCONF_KEY_USE_PROXY):
+        # XXX: Should check if string is a valid proxy.
+        proxy = '%s:%s' % (g.get_string(GCONF_KEY_PROXY_HOST), \
+                g.get_int(GCONF_KEY_PROXY_PORT))
+        if g.get_bool(GCONF_KEY_USE_PROXY_AUTH):
+            proxy = 'http://%s:%s@%s' % (g.get_string(GCONF_KEY_PROXY_USER), \
+                    g.get_string(GCONF_KEY_PROXY_PASSWORD), proxy)
+    else:
+        proxy = None
+
+def update_downloads_folder():
+    global downloads_folder
+    new_folder = path.join(path.expanduser('~'), path.expanduser(
+            gconf_client.get_string(GCONF_KEY_DOWNLOAD_FOLDER)))
+    if path.isdir(new_folder):
+        downloads_folder = new_folder
+        return True
+    return False
+
+def download_videos(window, embed, video_urls):
+    clive_cmd_base = [ 'clive', '--quiet', '--emit-csv' ]
+    if proxy != None:
+        clive_cmd_base.append('--proxy=%s' % proxy)
+
+    for video_url in video_urls:
+        clive_cmd = clive_cmd_base + [ video_url ] 
+        try:
+            new_download_ps = Popen(clive_cmd, stdout=PIPE, stderr=PIPE)
+        except OSError, e:
+            print 'OSError executing clive', e
+            if e.args[0] == 2:
+                error_text = _("Video-downloader extension could not execute \
+                               'clive'. Please make sure clive is installed \
+                               in a directory listed in the $PATH variable.")
+            else:
+                error_text = str(e)
+            message = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, 
+                    buttons=gtk.BUTTONS_CLOSE, message_format=error_text)
+            message.run()
+            message.destroy()
+        else:
+            gobject.child_watch_add(new_download_ps.pid, on_clive_finished, 
+                    data=(window, embed, new_download_ps.stdout, 
+                          new_download_ps.stderr, video_url))
+
+def debug_video_urls(window, embed, video_urls):
+    """
+    A drop-in replacement for the function download_videos. It displays a 
+    dialog with the URLs which otherwise would be downloaded. 
+    
+    Used for debugging only.
+    """
+    message_text = "\n".join(video_urls)
+    message = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, 
+            buttons=gtk.BUTTONS_CLOSE, message_format=message_text)
+    message.run()
+    message.destroy()
+
+def detect_videos_in_address(window, embed):
+    url = embed.get_address()
+    if URL_VIDEO_RE.findall(url) != []:
+        embed._video_urls = [url]
+        embed._has_video = True
+    else:
+        embed._has_video = False
+
+def start_video_download(window, embed, clive_output):
+    """
+    Lets Epiphany download a video via EmbedPersist given the output
+    of clive (as a string array). Doesn't work with Webkit-backend.
+    """
+    url, file_name = clive_output[-1].split(',')[1:3]
+    persist = epiphany.ephy_embed_factory_new_object(epiphany.EmbedPersist)
+    persist.set_source(url[1:-1])    # url[1:-1] to remove the quotes
+    persist.set_fc_parent(window)
+    persist.set_fc_title(_('Save Video As'))
+    persist.set_dest(path.join(downloads_folder, file_name[1:-1]))
+    persist.set_embed(embed)
+    persist.set_flags(epiphany.EMBED_PERSIST_ASK_DESTINATION)
+    if not persist.save():
+        # Failed to start downloading the video
+        error_text = _("Failed to start the download. Please report this \
+                       problem as a comment at http://blauebirke.wordpress.com/2008/10/04/new-improvements-in-epiphany-video-downloader-extension/ \
+                       or send an email backend to schmalho@users.berlios.de.")
+        message = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, 
+                buttons=gtk.BUTTONS_CLOSE, message_format=error_text)
+        message.run()
+        message.destroy()
+
+def on_clive_finished(pid, condition, data):
+    """
+    Processes the results from the clive process. If succeded starts the
+    download. Otherwise displays an error message to the user.
+    """
+    window, embed, clive_stdout, clive_stderr, video_url = data
+    if condition == 0:
+        start_video_download(window, embed, clive_stdout.readlines())
+    else:
+        title_text = _('Video Downloader extension: Extracting video information via clive failed:')
+        error_text = ''.join(['Exited with status %s.\n' % condition] +
+                               clive_stderr.readlines() + '==========\n' +
+                               clive_stdout.readlines())
+        message = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, 
+                buttons=gtk.BUTTONS_CLOSE, message_format=title_text)
+        message.format_secondary_text(error_text)
+        message.run()
+        message.destroy()
+
+def detect_videos_in_page(window, embed):
+    # Get the HTML code
+    persist = epiphany.ephy_embed_factory_new_object(epiphany.EmbedPersist)
+    persist.set_flags(
+            epiphany.EMBED_PERSIST_NO_VIEW | epiphany.EMBED_PERSIST_COPY_PAGE)
+    persist.set_embed(embed)
+    page_string = persist.to_string()
+    video_urls = get_video_urls(page_string)
+    if video_urls:
+        embed._video_urls = video_urls
+        embed._has_video = True
+    else :
+        embed._has_video = False
+
+def get_video_urls(page_string):
+    """
+    Finds all unique videos represented by a plain text link from the 
+    page (something starting with a "http://"). 
+    
+    Returns a set of url-strings.
+    """
+    video_urls = set()
+    for packed_url in EMBEDED_VIDEO_RE.findall(page_string):
+        for video_id, page_base in zip(packed_url[1:], VIDEO_PAGE_BASE):
+            if video_id != '':
+                video_urls.add(page_base % video_id)
+    return video_urls
+
+def attach_window(window):
+    notebook = window.get_notebook()
+    ui_init(window)
+    signal_tab_switch = notebook.connect_after(
+            "switch_page", _switch_page_cb, window);
+    notebook._video_signal_tab_switch = signal_tab_switch
+
+def detach_window(window):
+    notebook = window.get_notebook()
+    notebook.disconnect(notebook._video_signal_tab_switch)
+    del notebook._video_signal_tab_switch
+    ui_destroy(window)
+
+def attach_tab(window, embed):
+    signal_load_status = embed.connect_after(
+            "notify::load-status", _load_status_cb, window)
+    embed._video_signal_load_status = signal_load_status
+
+def detach_tab(window, embed):
+    embed.disconnect(embed._video_signal_load_status)
+    del embed._video_signal_load_status
+
+gconf_client = gconf.client_get_default()
+gconf_client.notify_add(GCONF_KEY_DOWNLOAD_FOLDER, 
+        on_gconf_new_downloads_folder)
+for key in [ GCONF_KEY_USE_PROXY, GCONF_KEY_PROXY_HOST, GCONF_KEY_PROXY_PORT, 
+            GCONF_KEY_USE_PROXY_AUTH, GCONF_KEY_PROXY_USER, 
+            GCONF_KEY_PROXY_PASSWORD ]:
+    gconf_client.notify_add(key, on_gconf_proxy_changed)
+downloads_folder = path.expanduser('~')
+update_downloads_folder()
+update_proxy_settings()
+
+# DEBUG
+#download_videos = debug_video_urls

