Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/readactivity.py
blob: a710d8530034bcd0749b2723c805d5670b4a1594 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# Copyright (C) 2007, Red Hat, Inc.
#
# 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 logging
from gettext import gettext as _

import gtk, gobject
import evince
import hippo
import os

from sugar.activity import activity
from sugar import network

from readtoolbar import ReadToolbar

_READ_PORT = 17982

class ReadHTTPRequestHandler(network.ChunkedGlibHTTPRequestHandler):
    def translate_path(self, path):
        return self.server._filepath

class ReadHTTPServer(network.GlibTCPServer):
    def __init__(self, server_address, filepath):
        self._filepath = filepath
        network.GlibTCPServer.__init__(self, server_address, ReadHTTPRequestHandler)

class ReadActivity(activity.Activity):
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)
        self._document = None
        self._filepath = None
        self._fileserver = None

        logging.debug('Starting read...')
        self.set_title(_('Read Activity'))
        
        evince.job_queue_init()
        self._view = evince.View()

        toolbox = activity.ActivityToolbox(self)

        self._toolbar = ReadToolbar(self._view)
        toolbox.add_toolbar(_('View'), self._toolbar)
        self._toolbar.show()

        self.set_toolbox(toolbox)
        toolbox.show()

        scrolled = gtk.ScrolledWindow()
        scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
        scrolled.props.shadow_type = gtk.SHADOW_NONE

        scrolled.add(self._view)
        self._view.show()
                
        self.set_canvas(scrolled)
        scrolled.show()

        self.connect("shared", self._shared_cb)

        if handle.uri:
            self._load_document(handle.uri)

        if self._shared_activity or not self._document:
            self._tried_buddies = []
            if self.get_shared():
                # Already joined for some reason, just get the document
                self._get_document()
            else:
                # Wait for a successful join before trying to get the document
                self.connect("joined", self._joined_cb)

    def read_file(self, file_path):
        logging.debug('ReadActivity.read_file: ' + file_path)
        self._load_document('file://' + file_path)

    def _download_result_cb(self, getter, tempfile, suggested_name, buddy):
        del self._tried_buddies
        logging.debug("Got document %s (%s) from %s (%s)" % (tempfile, suggested_name, buddy.props.nick, buddy.props.ip4_address))
        self._load_document("file://%s" % dest)

    def _download_error_cb(self, getter, err, buddy):
        logging.debug("Error getting document from %s (%s): %s" % (buddy.props.nick, buddy.props.ip4_address, err))
        self._tried_buddies.append(buddy)
        gobject.idle_add(self._get_document)

    def _download_document(self, buddy):
        getter = network.GlibURLDownloader("http://%s:%d/document" % (buddy.props.ip4_address, _READ_PORT))
        getter.connect("finished", self._download_result_cb, buddy)
        getter.connect("error", self._download_error_cb, buddy)
        logging.debug("Starting download...")
        getter.start(self.)
        return False

    def _get_document(self):
        next_buddy = None
        # Find the next untried buddy with an IP4 address we can try to
        # download the document from
        for buddy in self._shared_activity.get_joined_buddies():
            if buddy.props.owner:
                continue
            if not buddy in self._tried_buddies:
                if buddy.props.ip4_address:
                    next_buddy = buddy
                    break

        if not next_buddy:
            logging.debug("Couldn't find a buddy to get the document from.")
            return False

        gobject.idle_add(self._download_document, buddy)
        return False

    def _joined_cb(self, activity):
        gobject.idle_add(self._get_document)

    def _load_document(self, filepath):
        if self._document:
            del self._document
        self._document = evince.factory_get_document(filepath)
        self._view.set_document(self._document)
        self._toolbar.set_document(self._document)
        title = _("Read Activity")
        info = self._document.get_info()
        if info and info.title:
            title += ": " + info.title
        self.set_title(title)

        import urllib
        garbage, path = urllib.splittype(filepath)
        garbage, path = urllib.splithost(path or "")
        path, garbage = urllib.splitquery(path or "")
        path, garbage = urllib.splitattr(path or "")
        self._filepath = os.path.abspath(path)

        # When we get the document, start up our sharing services
        if self.get_shared():
            self._start_shared_services()

    def _start_shared_services(self):
        self._fileserver = ReadHTTPServer(("", _READ_PORT), self._filepath)

    def _shared_cb(self, activity):
        self._start_shared_services()