Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/webactivity.py
diff options
context:
space:
mode:
Diffstat (limited to 'webactivity.py')
-rw-r--r--webactivity.py504
1 files changed, 0 insertions, 504 deletions
diff --git a/webactivity.py b/webactivity.py
deleted file mode 100644
index 03c2002..0000000
--- a/webactivity.py
+++ /dev/null
@@ -1,504 +0,0 @@
-# Copyright (C) 2006, Red Hat, Inc.
-# Copyright (C) 2009 Martin Langhoff, Simon Schampijer, Daniel Drake, Tomeu Vizoso
-#
-# 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 of the License, 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-import logging
-from gettext import gettext as _
-
-import gobject
-gobject.threads_init()
-
-import gtk
-import base64
-import time
-import shutil
-import sqlite3
-import cjson
-import gconf
-import locale
-from hashlib import sha1
-
-import webkit
-
-from sugar.activity import activity
-from sugar.graphics import style
-import telepathy
-import telepathy.client
-from sugar.presence import presenceservice
-from sugar.graphics.tray import HTray
-from sugar import profile
-from sugar.graphics.alert import Alert
-from sugar.graphics.icon import Icon
-from sugar.graphics.toolbarbox import ToolbarButton
-from sugar import mime
-
-PROFILE_VERSION = 2
-
-_profile_version = 0
-_profile_path = os.path.join(activity.get_activity_root(), 'data/webkit')
-_version_file = os.path.join(_profile_path, 'version')
-
-if os.path.exists(_version_file):
- f = open(_version_file)
- _profile_version = int(f.read())
- f.close()
-
-if _profile_version < PROFILE_VERSION:
- if not os.path.exists(_profile_path):
- os.mkdir(_profile_path)
-
- shutil.copy('cert8.db', _profile_path)
- os.chmod(os.path.join(_profile_path, 'cert8.db'), 0660)
-
- f = open(_version_file, 'w')
- f.write(str(PROFILE_VERSION))
- f.close()
-
-
-def _seed_xs_cookie():
- ''' Create a HTTP Cookie to authenticate with the Schoolserver
- '''
- client = gconf.client_get_default()
- backup_url = client.get_string('/desktop/sugar/backup_url')
- if not backup_url:
- _logger.debug('seed_xs_cookie: Not registered with Schoolserver')
- return
-
- jabber_server = client.get_string(
- '/desktop/sugar/collaboration/jabber_server')
-
- pubkey = profile.get_profile().pubkey
- cookie_data = {'color': profile.get_color().to_string(),
- 'pkey_hash': sha1(pubkey).hexdigest()}
-
- # TODO set cookie for webkit
-
-#TODO set app version? and profile path
-
-def _set_accept_languages():
- ''' Set intl.accept_languages based on the locale
- '''
-
- lang = locale.getdefaultlocale()[0]
- if not lang:
- _logger.debug("Set_Accept_language: unrecognised LANG format")
- return
- lang = lang.split('_')
-
- # e.g. es-uy, es
- pref = lang[0] + "-" + lang[1].lower() + ", " + lang[0]
-
- #TODO set locale for webkit
-
- logging.debug('LANG set')
-
-from browser import TabbedView
-from webtoolbar import PrimaryToolbar
-from edittoolbar import EditToolbar
-from viewtoolbar import ViewToolbar
-import downloadmanager
-import filepicker
-
-_LIBRARY_PATH = '/usr/share/library-common/index.html'
-
-from model import Model
-from sugar.presence.tubeconn import TubeConnection
-from messenger import Messenger
-from linkbutton import LinkButton
-
-SERVICE = "org.laptop.WebActivity"
-IFACE = SERVICE
-PATH = "/org/laptop/WebActivity"
-
-_logger = logging.getLogger('web-activity')
-
-
-class WebActivity(activity.Activity):
- def __init__(self, handle):
- activity.Activity.__init__(self, handle)
-
- _logger.debug('Starting the web activity')
-
- self._tabbed_view = TabbedView(self)
-
- _set_accept_languages()
- _seed_xs_cookie()
-
- self._primary_toolbar = PrimaryToolbar(self._tabbed_view, self)
- self._primary_toolbar.connect('add-link', self._link_add_button_cb)
-
- self._tray = HTray()
- self.set_tray(self._tray, gtk.POS_BOTTOM)
- self._tray.show()
-
- self._edit_toolbar = EditToolbar(self)
- self._edit_toolbar_button = ToolbarButton(
- page=self._edit_toolbar,
- icon_name='toolbar-edit')
- self._primary_toolbar.toolbar.insert(
- self._edit_toolbar_button, 1)
-
- self._view_toolbar = ViewToolbar(self)
- view_toolbar_button = ToolbarButton(
- page=self._view_toolbar,
- icon_name='toolbar-view')
- self._primary_toolbar.toolbar.insert(
- view_toolbar_button, 2)
-
- self._primary_toolbar.show_all()
- self.set_toolbar_box(self._primary_toolbar)
-
- self.set_canvas(self._tabbed_view)
- self._tabbed_view.show()
-
- self.model = Model()
- self.model.connect('add_link', self._add_link_model_cb)
-
- self.connect('key-press-event', self._key_press_cb)
-
- if handle.uri:
- self._tabbed_view.current_browser.load_uri(handle.uri)
- elif not self._jobject.file_path:
- # TODO: we need this hack until we extend the activity API for
- # opening URIs and default docs.
- self._load_homepage()
-
- self.messenger = None
- self.connect('shared', self._shared_cb)
-
- # Get the Presence Service
- self.pservice = presenceservice.get_instance()
- try:
- name, path = self.pservice.get_preferred_connection()
- self.tp_conn_name = name
- self.tp_conn_path = path
- self.conn = telepathy.client.Connection(name, path)
- except TypeError:
- _logger.debug('Offline')
- self.initiating = None
-
- if self._shared_activity is not None:
- _logger.debug('shared: %s' %self._shared_activity.props.joined)
-
- if self._shared_activity is not None:
- # We are joining the activity
- _logger.debug('Joined activity')
- self.connect('joined', self._joined_cb)
- if self.get_shared():
- # We've already joined
- self._joined_cb()
- else:
- _logger.debug('Created activity')
-
- def _shared_cb(self, activity_):
- _logger.debug('My activity was shared')
- self.initiating = True
- self._setup()
-
- _logger.debug('This is my activity: making a tube...')
- self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube(SERVICE, {})
-
- def _setup(self):
- if self._shared_activity is None:
- _logger.debug('Failed to share or join activity')
- return
-
- bus_name, conn_path, channel_paths = \
- self._shared_activity.get_channels()
-
- # Work out what our room is called and whether we have Tubes already
- room = None
- tubes_chan = None
- text_chan = None
- for channel_path in channel_paths:
- channel = telepathy.client.Channel(bus_name, channel_path)
- htype, handle = channel.GetHandle()
- if htype == telepathy.HANDLE_TYPE_ROOM:
- _logger.debug('Found our room: it has handle#%d "%s"'
- %(handle, self.conn.InspectHandles(htype, [handle])[0]))
- room = handle
- ctype = channel.GetChannelType()
- if ctype == telepathy.CHANNEL_TYPE_TUBES:
- _logger.debug('Found our Tubes channel at %s'%channel_path)
- tubes_chan = channel
- elif ctype == telepathy.CHANNEL_TYPE_TEXT:
- _logger.debug('Found our Text channel at %s'%channel_path)
- text_chan = channel
-
- if room is None:
- _logger.debug("Presence service didn't create a room")
- return
- if text_chan is None:
- _logger.debug("Presence service didn't create a text channel")
- return
-
- # Make sure we have a Tubes channel - PS doesn't yet provide one
- if tubes_chan is None:
- _logger.debug("Didn't find our Tubes channel, requesting one...")
- tubes_chan = self.conn.request_channel(telepathy.CHANNEL_TYPE_TUBES,
- telepathy.HANDLE_TYPE_ROOM,
- room, True)
-
- self.tubes_chan = tubes_chan
- self.text_chan = text_chan
-
- tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal( \
- 'NewTube', self._new_tube_cb)
-
- def _list_tubes_reply_cb(self, tubes):
- for tube_info in tubes:
- self._new_tube_cb(*tube_info)
-
- def _list_tubes_error_cb(self, e):
- _logger.debug('ListTubes() failed: %s'%e)
-
- def _joined_cb(self, activity_):
- if not self._shared_activity:
- return
-
- _logger.debug('Joined an existing shared activity')
-
- self.initiating = False
- self._setup()
-
- _logger.debug('This is not my activity: waiting for a tube...')
- self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes(
- reply_handler=self._list_tubes_reply_cb,
- error_handler=self._list_tubes_error_cb)
-
- def _new_tube_cb(self, identifier, initiator, type, service, params, state):
- _logger.debug('New tube: ID=%d initator=%d type=%d service=%s '
- 'params=%r state=%d' %(identifier, initiator, type,
- service, params, state))
-
- if (type == telepathy.TUBE_TYPE_DBUS and
- service == SERVICE):
- if state == telepathy.TUBE_STATE_LOCAL_PENDING:
- self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(
- identifier)
-
- self.tube_conn = TubeConnection(self.conn,
- self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES],
- identifier, group_iface = self.text_chan[
- telepathy.CHANNEL_INTERFACE_GROUP])
-
- _logger.debug('Tube created')
- self.messenger = Messenger(self.tube_conn, self.initiating,
- self.model)
-
- def _load_homepage(self):
- browser = self._tabbed_view.current_browser
- if os.path.isfile(_LIBRARY_PATH):
- browser.load_uri('file://' + _LIBRARY_PATH)
- else:
- default_page = os.path.join(activity.get_bundle_path(),
- "data/index.html")
- browser.load_uri('file://' + default_page)
-
- def _get_data_from_file_path(self, file_path):
- fd = open(file_path, 'r')
- try:
- data = fd.read()
- finally:
- fd.close()
- return data
-
- def read_file(self, file_path):
- if self.metadata['mime_type'] == 'text/plain':
- data = self._get_data_from_file_path(file_path)
- self.model.deserialize(data)
-
- for link in self.model.data['shared_links']:
- _logger.debug('read: url=%s title=%s d=%s' % (link['url'],
- link['title'],
- link['color']))
- self._add_link_totray(link['url'],
- base64.b64decode(link['thumb']),
- link['color'], link['title'],
- link['owner'], -1, link['hash'])
- logging.debug('########## reading %s' % data)
- self._tabbed_view.set_session(self.model.data['history'])
- self._tabbed_view.set_current_page(self.model.data['current_tab'])
- elif self.metadata['mime_type'] == 'text/uri-list':
- data = self._get_data_from_file_path(file_path)
- uris = mime.split_uri_list(data)
- if len(uris) == 1:
- self._tabbed_view.props.current_browser.load_uri(uris[0])
- else:
- _logger.error('Open uri-list: Does not support'
- 'list of multiple uris by now.')
- else:
- self._tabbed_view.props.current_browser.load_uri('file://' +
- file_path)
-
- def write_file(self, file_path):
- if not self.metadata['mime_type']:
- self.metadata['mime_type'] = 'text/plain'
-
- if self.metadata['mime_type'] == 'text/plain':
-
- browser = self._tabbed_view.current_browser
-
- if not self._jobject.metadata['title_set_by_user'] == '1':
- if browser.props.title:
- self.metadata['title'] = browser.props.title
-
- self.model.data['history'] = self._tabbed_view.get_session()
- self.model.data['current_tab'] = self._tabbed_view.get_current_page()
-
- f = open(file_path, 'w')
- try:
- logging.debug('########## writing %s' % self.model.serialize())
- f.write(self.model.serialize())
- finally:
- f.close()
-
- def _link_add_button_cb(self, button):
- self._add_link()
-
- def _key_press_cb(self, widget, event):
- if event.state & gtk.gdk.CONTROL_MASK:
- if gtk.gdk.keyval_name(event.keyval) == "d":
- self._add_link()
- return True
- elif gtk.gdk.keyval_name(event.keyval) == "f":
- _logger.debug('keyboard: Find')
- self._edit_toolbar_button.set_expanded(True)
- self._edit_toolbar.search_entry.grab_focus()
- return True
- elif gtk.gdk.keyval_name(event.keyval) == "l":
- _logger.debug('keyboard: Focus url entry')
- self._primary_toolbar.entry.grab_focus()
- return True
- elif gtk.gdk.keyval_name(event.keyval) == "minus":
- _logger.debug('keyboard: Zoom out')
- self._tabbed_view.props.current_browser.zoom_out()
- return True
- elif gtk.gdk.keyval_name(event.keyval) == "plus" \
- or gtk.gdk.keyval_name(event.keyval) == "equal":
- _logger.debug('keyboard: Zoom in')
- self._tabbed_view.props.current_browser.zoom_in()
- return True
- return False
-
- def _add_link(self):
- ''' take screenshot and add link info to the model '''
-
- browser = self._tabbed_view.props.current_browser
- uri = browser.props.uri
-
- for link in self.model.data['shared_links']:
- if link['hash'] == sha1(uri).hexdigest():
- _logger.debug('_add_link: link exist already a=%s b=%s' %(
- link['hash'], sha1(uri).hexdigest()))
- return
- buf = self._get_screenshot()
- timestamp = time.time()
- self.model.add_link(uri, browser.props.title, buf,
- profile.get_nick_name(),
- profile.get_color().to_string(), timestamp)
-
- if self.messenger is not None:
- self.messenger._add_link(uri, browser.props.title,
- profile.get_color().to_string(),
- profile.get_nick_name(),
- base64.b64encode(buf), timestamp)
-
- def _add_link_model_cb(self, model, index):
- ''' receive index of new link from the model '''
- link = self.model.data['shared_links'][index]
- self._add_link_totray(link['url'], base64.b64decode(link['thumb']),
- link['color'], link['title'],
- link['owner'], index, link['hash'])
-
- def _add_link_totray(self, url, buf, color, title, owner, index, hash):
- ''' add a link to the tray '''
- item = LinkButton(url, buf, color, title, owner, index, hash)
- item.connect('clicked', self._link_clicked_cb, url)
- item.connect('remove_link', self._link_removed_cb)
- self._tray.add_item(item, index) # use index to add to the tray
- item.show()
- if self._tray.props.visible is False:
- self._tray.show()
- self._view_toolbar.traybutton.props.sensitive = True
-
- def _link_removed_cb(self, button, hash):
- ''' remove a link from tray and delete it in the model '''
- self.model.remove_link(hash)
- self._tray.remove_item(button)
- if len(self._tray.get_children()) == 0:
- self._view_toolbar.traybutton.props.sensitive = False
-
- def _link_clicked_cb(self, button, url):
- ''' an item of the link tray has been clicked '''
- self._tabbed_view.props.current_browser.load_uri(url)
-
- def _pixbuf_save_cb(self, buf, data):
- data[0] += buf
- return True
-
- def get_buffer(self, pixbuf):
- data = [""]
- pixbuf.save_to_callback(self._pixbuf_save_cb, "png", {}, data)
- return str(data[0])
-
- def _get_screenshot(self):
- window = self._tabbed_view.props.current_browser.window
- width, height = window.get_size()
-
- screenshot = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, has_alpha=False,
- bits_per_sample=8, width=width,
- height=height)
- screenshot.get_from_drawable(window, window.get_colormap(), 0, 0, 0, 0,
- width, height)
-
- screenshot = screenshot.scale_simple(style.zoom(100),
- style.zoom(80),
- gtk.gdk.INTERP_BILINEAR)
-
- buf = self.get_buffer(screenshot)
- return buf
-
- def can_close(self):
- if downloadmanager.can_quit():
- return True
- else:
- alert = Alert()
- alert.props.title = _('Download in progress')
- alert.props.msg = _('Stopping now will cancel your download')
- cancel_icon = Icon(icon_name='dialog-cancel')
- alert.add_button(gtk.RESPONSE_CANCEL, _('Cancel'), cancel_icon)
- stop_icon = Icon(icon_name='dialog-ok')
- alert.add_button(gtk.RESPONSE_OK, _('Stop'), stop_icon)
- stop_icon.show()
- self.add_alert(alert)
- alert.connect('response', self.__inprogress_response_cb)
- alert.show()
- self.present()
-
- def __inprogress_response_cb(self, alert, response_id):
- self.remove_alert(alert)
- if response_id is gtk.RESPONSE_CANCEL:
- logging.debug('Keep on')
- elif response_id == gtk.RESPONSE_OK:
- logging.debug('Stop downloads and quit')
- downloadmanager.remove_all_downloads()
- self.close()
-
- def get_document_path(self, async_cb, async_err_cb):
- browser = self._tabbed_view.props.current_browser
- browser.get_source(async_cb, async_err_cb)