~didrocks/ubuntuone-client/dont-suffer-zg-crash

« back to all changes in this revision

Viewing changes to bin/ubuntuone-login

  • Committer: Bazaar Package Importer
  • Author(s): Rodrigo Moya
  • Date: 2010-06-23 23:08:15 UTC
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: james.westby@ubuntu.com-20100623230815-4m3ugh10u9x9xzw5
Tags: upstream-1.3.2
ImportĀ upstreamĀ versionĀ 1.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
 
 
3
 
# ubuntuone-login - Client side log-in utility for Ubuntu One
4
 
#
5
 
# Author: Rodney Dawes <rodney.dawes@canonical.com>
6
 
#
7
 
# Copyright 2009 Canonical Ltd.
8
 
#
9
 
# This program is free software: you can redistribute it and/or modify it
10
 
# under the terms of the GNU General Public License version 3, as published
11
 
# by the Free Software Foundation.
12
 
#
13
 
# This program is distributed in the hope that it will be useful, but
14
 
# WITHOUT ANY WARRANTY; without even the implied warranties of
15
 
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
16
 
# PURPOSE.  See the GNU General Public License for more details.
17
 
#
18
 
# You should have received a copy of the GNU General Public License along
19
 
# with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 
 
21
 
import pygtk
22
 
pygtk.require('2.0')
23
 
import gtk
24
 
import pango
25
 
import sys
26
 
import gettext
27
 
from ubuntuone import clientdefs
28
 
 
29
 
import dbus.service
30
 
 
31
 
from dbus.mainloop.glib import DBusGMainLoop
32
 
from ubuntuone.oauthdesktop.main import Login
33
 
 
34
 
from ubuntuone.oauthdesktop.logger import setupLogging
35
 
logger = setupLogging("ubuntuone-login")
36
 
 
37
 
DBusGMainLoop(set_as_default=True)
38
 
 
39
 
_ = gettext.gettext
40
 
ngettext = gettext.ngettext
41
 
 
42
 
DBUS_IFACE_AUTH_NAME = "com.ubuntuone.Authentication"
43
 
 
44
 
OAUTH_REALM = "https://ubuntuone.com"
45
 
OAUTH_CONSUMER = "ubuntuone"
46
 
 
47
 
NOTIFY_ICON_SIZE = 48
48
 
 
49
 
# Why thank you GTK+ for enforcing style-set and breaking API
50
 
RCSTYLE = """
51
 
style 'dialogs' {
52
 
  GtkDialog::action-area-border = 12
53
 
  GtkDialog::button-spacing = 6
54
 
  GtkDialog::content-area-border = 0
55
 
}
56
 
widget_class '*Dialog*' style 'dialogs'
57
 
"""
58
 
 
59
 
 
60
 
class LoginMain(object):
61
 
    """Main login manager process class."""
62
 
 
63
 
    def __init__(self, *args, **kw):
64
 
        """Initializes the child threads and dbus monitor."""
65
 
        gtk.rc_parse_string(RCSTYLE)
66
 
 
67
 
        logger.info(_("Starting Ubuntu One login manager version %s") %
68
 
                    clientdefs.VERSION)
69
 
 
70
 
        self.__bus = dbus.SessionBus()
71
 
 
72
 
    def _connect_dbus_signals(self):
73
 
        """Set up some signal handlers for DBus signals."""
74
 
        self.__bus.add_signal_receiver(
75
 
              handler_function=self.new_credentials,
76
 
              signal_name="NewCredentials",
77
 
              dbus_interface=DBUS_IFACE_AUTH_NAME)
78
 
        self.__bus.add_signal_receiver(
79
 
              handler_function=self.auth_denied,
80
 
              signal_name="AuthorizationDenied",
81
 
              dbus_interface=DBUS_IFACE_AUTH_NAME)
82
 
        self.__bus.add_signal_receiver(
83
 
              handler_function=self.got_oauth_error,
84
 
              signal_name="OAuthError",
85
 
              dbus_interface=DBUS_IFACE_AUTH_NAME)
86
 
 
87
 
 
88
 
    def new_credentials(self, realm=None, consumer_key=None, sender=None):
89
 
        """Signal callback for when we get new credentials."""
90
 
        self.set_up_desktopcouch_pairing(consumer_key)
91
 
 
92
 
        def got_port(*args, **kwargs):
93
 
            # Discard the value.  We don't really care about the port, here.
94
 
            pass
95
 
 
96
 
        def got_error(*args, **kwargs):
97
 
            logger.warn("On trying to start desktopcouch-service via DBus, "
98
 
                    "we got an error.  %s %s" % (args, kwargs,))
99
 
 
100
 
        # We have auth, so start desktopcouch service by asking for its port.
101
 
        dc_serv_proxy = self.__bus.get_object("org.desktopcouch.CouchDB", "/")
102
 
        dc_serv_proxy.getPort(reply_handler=got_port, error_handler=got_error)
103
 
 
104
 
    def auth_denied(self):
105
 
        """Signal callback for when auth was denied by user."""
106
 
        logger.info(_("Access to Ubuntu One was denied."))
107
 
 
108
 
        from twisted.internet import reactor
109
 
        reactor.stop()
110
 
 
111
 
    def got_oauth_error(self, message=None):
112
 
        """Signal callback for when an OAuth error occured."""
113
 
        def dialog_response(dialog, response):
114
 
            """Handle the dialog closing."""
115
 
            dialog.destroy()
116
 
 
117
 
        if message:
118
 
            logger.error(message)
119
 
            dialog = gtk.Dialog(title=_("Ubuntu One: Error"),
120
 
                                flags=gtk.DIALOG_NO_SEPARATOR,
121
 
                                buttons=(gtk.STOCK_CLOSE,
122
 
                                         gtk.RESPONSE_CLOSE))
123
 
            dialog.set_default_response(gtk.RESPONSE_CLOSE)
124
 
            dialog.set_icon_name("ubuntuone-client")
125
 
 
126
 
            area = dialog.get_content_area()
127
 
 
128
 
            hbox = gtk.HBox(spacing=12)
129
 
            hbox.set_border_width(12)
130
 
            area.pack_start(hbox)
131
 
            hbox.show()
132
 
 
133
 
            image = gtk.Image()
134
 
            image.set_from_icon_name("dialog-error", gtk.ICON_SIZE_DIALOG)
135
 
            image.set_alignment(0.5, 0.0)
136
 
            image.show()
137
 
            hbox.pack_start(image, False, False)
138
 
 
139
 
            vbox = gtk.VBox(spacing=12)
140
 
            vbox.show()
141
 
            hbox.pack_start(vbox)
142
 
 
143
 
            label = gtk.Label("<b>%s</b>" % _("Authorization Error"))
144
 
            label.set_use_markup(True)
145
 
            label.set_alignment(0.0, 0.5)
146
 
            label.show()
147
 
            vbox.pack_start(label, False, False)
148
 
 
149
 
            label = gtk.Label(message)
150
 
            label.set_line_wrap(True)
151
 
            label.set_max_width_chars(64)
152
 
            label.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
153
 
            label.set_alignment(0.0, 0.0)
154
 
            label.show()
155
 
            vbox.pack_start(label, True, True)
156
 
 
157
 
            dialog.connect('close', dialog_response, gtk.RESPONSE_CLOSE)
158
 
            dialog.connect('response', dialog_response)
159
 
 
160
 
            dialog.show()
161
 
        else:
162
 
            logger.error(_("Got an OAuth error with no message."))
163
 
 
164
 
    def set_up_desktopcouch_pairing(self, consumer_key):
165
 
        """Add a pairing record between desktopcouch and Ubuntu One"""
166
 
        try:
167
 
            from desktopcouch.pair.couchdb_pairing.couchdb_io import \
168
 
                 put_static_paired_service
169
 
            from desktopcouch.records.server import CouchDatabase
170
 
        except ImportError:
171
 
            # desktopcouch is not installed
172
 
            logger.debug(_("Not adding desktopcouch pairing since"
173
 
                " desktopcouch is not installed"))
174
 
            return
175
 
        # Check whether there is already a record of the Ubuntu One service
176
 
        db = CouchDatabase("management", create=True)
177
 
        if not db.view_exists("ubuntu_one_pair_record","ubuntu_one_pair_record"):
178
 
            map_js = """function(doc) {
179
 
                if (doc.service_name == "ubuntuone") {
180
 
                    if (doc.application_annotations &&
181
 
                        doc.application_annotations["Ubuntu One"] &&
182
 
                        doc.application_annotations["Ubuntu One"]["private_application_annotations"] &&
183
 
                        doc.application_annotations["Ubuntu One"]["private_application_annotations"]["deleted"]) {
184
 
                        emit(doc._id, 1);
185
 
                    } else {
186
 
                        emit(doc._id, 0)
187
 
                    }
188
 
                }
189
 
            }"""
190
 
            db.add_view("ubuntu_one_pair_record", map_js, None,
191
 
                "ubuntu_one_pair_record")
192
 
        results = db.execute_view("ubuntu_one_pair_record",
193
 
            "ubuntu_one_pair_record")
194
 
        found = False
195
 
        # Results should contain either one row or no rows
196
 
        # If there is one row, its value will be 0, meaning that there is
197
 
        #   already an Ubuntu One pairing record, or 1, meaning that there
198
 
        #   was an Ubuntu One pairing record but it has since been unpaired
199
 
        # Only create a new record if there is not one already. Specifically,
200
 
        #   do not add the record if there is a deleted one, as this means
201
 
        #   that the user explicitly unpaired it!
202
 
        for row in results:
203
 
            found = True
204
 
            if row.value == 1:
205
 
                logger.debug(_("Not adding desktopcouch pairing since"
206
 
                " the user has explicitly unpaired with Ubuntu One"))
207
 
            else:
208
 
                logger.debug(_("Not adding desktopcouch pairing since"
209
 
                " we are already paired"))
210
 
        if not found:
211
 
            put_static_paired_service(None, "ubuntuone")
212
 
            logger.debug(_("Pairing desktopcouch with Ubuntu One"))
213
 
 
214
 
    def main(self):
215
 
        """Starts the gtk main loop."""
216
 
        self._connect_dbus_signals()
217
 
 
218
 
        from twisted.internet import reactor
219
 
        reactor.run()
220
 
 
221
 
 
222
 
if __name__ == "__main__":
223
 
    gettext.bindtextdomain(clientdefs.GETTEXT_PACKAGE, clientdefs.LOCALEDIR)
224
 
    gettext.textdomain(clientdefs.GETTEXT_PACKAGE)
225
 
 
226
 
    # Register DBus service for making sure we run only one instance
227
 
    bus = dbus.SessionBus()
228
 
    if bus.request_name(DBUS_IFACE_AUTH_NAME, dbus.bus.NAME_FLAG_DO_NOT_QUEUE) == dbus.bus.REQUEST_NAME_REPLY_EXISTS:
229
 
        print _("Ubuntu One login manager already running, quitting")
230
 
        sys.exit(0)
231
 
 
232
 
    from twisted.internet import gtk2reactor
233
 
    gtk2reactor.install()
234
 
 
235
 
    login = Login(dbus.service.BusName(DBUS_IFACE_AUTH_NAME,
236
 
                                       bus=dbus.SessionBus()))
237
 
    manager = LoginMain()
238
 
    manager.main()