self.cookies.add_cookie_header(req)
if forbidRedirect:
redirector = HTTPNoRedirector()
- _moduleLogger.info("Redirection disabled")
+ #_moduleLogger.info("Redirection disabled")
else:
redirector = urllib2.HTTPRedirectHandler()
- _moduleLogger.info("Redirection enabled")
+ #_moduleLogger.info("Redirection enabled")
http_handler = urllib2.HTTPHandler(debuglevel=self.debug)
https_handler = urllib2.HTTPSHandler(debuglevel=self.debug)
with gtk_toolbox.gtk_lock():
self._errorDisplay.push_exception()
finally:
- self._spawn_attempt_login(2)
+ self._spawn_attempt_login()
def _spawn_attempt_login(self, *args):
self._loginSink.send(args)
- def _attempt_login(self, numOfAttempts = 10, force = False):
+ def _attempt_login(self, force = False):
"""
@note This must be run outside of the UI lock
"""
try:
- assert 0 <= numOfAttempts, "That was pointless having 0 or less login attempts"
assert self._initDone, "Attempting login before app is fully loaded"
serviceId = self.NULL_BACKEND
hildonize.show_busy_banner_end(banner)
if not loggedIn:
- loggedIn, serviceId = self._login_by_user(numOfAttempts)
+ loggedIn, serviceId = self._login_by_user()
with gtk_toolbox.gtk_lock():
self._change_loggedin_status(serviceId)
@note Thread agnostic
"""
username, password = self._credentials
- try:
- loggedIn = self._phoneBackends[self._defaultBackendId].login(username, password)
- except Exception:
- # Retry in case the redirect failed
- # luckily is_authed does everything we need for a retry
- loggedIn = self._phoneBackends[self._defaultBackendId].is_authed(True)
- if not loggedIn:
- raise
- _moduleLogger.info("Redirection failed on initial login attempt, auto-corrected for this")
+ loggedIn = self._phoneBackends[self._defaultBackendId].login(username, password)
if loggedIn:
self._credentials = username, password
_moduleLogger.info("Logged into %r through settings" % self._phoneBackends[self._defaultBackendId])
return loggedIn
- def _login_by_user(self, numOfAttempts):
+ def _login_by_user(self):
"""
@note This must be run outside of the UI lock
"""
loggedIn, (username, password) = False, self._credentials
tmpServiceId = self.GV_BACKEND
- for attemptCount in xrange(numOfAttempts):
- if loggedIn:
- break
-
+ while not loggedIn:
with gtk_toolbox.gtk_lock():
credentials = self._credentialsDialog.request_credentials(
defaultCredentials = self._credentials
if not self._phoneBackends[tmpServiceId].get_callback_number():
# subtle reminder to the users to configure things
self._notebook.set_current_page(self.ACCOUNT_TAB)
- banner = hildonize.show_busy_banner_start(self._window, "Logging In...")
+ banner = hildonize.show_busy_banner_start(self._window, "Logging In...")
try:
username, password = credentials
- try:
- loggedIn = self._phoneBackends[tmpServiceId].login(username, password)
- except Exception:
- # Retry in case the redirect failed
- # luckily is_authed does everything we need for a retry
- loggedIn = self._phoneBackends[tmpServiceId].is_authed(True)
- if not loggedIn:
- raise
- _moduleLogger.info("Redirection failed on initial login attempt, auto-corrected for this")
+ loggedIn = self._phoneBackends[tmpServiceId].login(username, password)
finally:
with gtk_toolbox.gtk_lock():
hildonize.show_busy_banner_end(banner)
self._credentials = username, password
_moduleLogger.info("Logged into %r through user request" % self._phoneBackends[serviceId])
else:
+ # Hint to the user that they are not logged in
serviceId = self.NULL_BACKEND
self._notebook.set_current_page(self.ACCOUNT_TAB)
if status == conic.STATUS_CONNECTED:
if self._initDone:
- self._spawn_attempt_login(2)
+ self._spawn_attempt_login()
elif status == conic.STATUS_DISCONNECTED:
if self._initDone:
self._defaultBackendId = self._selectedBackendId
self._contactsViews[self._selectedBackendId].clear()
self._change_loggedin_status(self.NULL_BACKEND)
- self._spawn_attempt_login(2, True)
+ self._spawn_attempt_login(True)
except Exception, e:
self._errorDisplay.push_exception()
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_digit_clicked"/>
- <accelerator key="c" signal="clicked"/>
- <accelerator key="b" signal="clicked"/>
- <accelerator key="a" signal="clicked"/>
<accelerator key="2" signal="clicked"/>
+ <accelerator key="a" signal="clicked"/>
+ <accelerator key="b" signal="clicked"/>
+ <accelerator key="c" signal="clicked"/>
<child>
<widget class="GtkLabel" id="label10">
<property name="visible">True</property>
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_digit_clicked"/>
- <accelerator key="f" signal="clicked"/>
- <accelerator key="e" signal="clicked"/>
- <accelerator key="d" signal="clicked"/>
<accelerator key="3" signal="clicked"/>
+ <accelerator key="d" signal="clicked"/>
+ <accelerator key="e" signal="clicked"/>
+ <accelerator key="f" signal="clicked"/>
<child>
<widget class="GtkLabel" id="label11">
<property name="visible">True</property>
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_digit_clicked"/>
- <accelerator key="i" signal="clicked"/>
- <accelerator key="h" signal="clicked"/>
- <accelerator key="g" signal="clicked"/>
<accelerator key="4" signal="clicked"/>
+ <accelerator key="g" signal="clicked"/>
+ <accelerator key="h" signal="clicked"/>
+ <accelerator key="i" signal="clicked"/>
<child>
<widget class="GtkLabel" id="label13">
<property name="visible">True</property>
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_digit_clicked"/>
- <accelerator key="l" signal="clicked"/>
- <accelerator key="k" signal="clicked"/>
- <accelerator key="j" signal="clicked"/>
<accelerator key="5" signal="clicked"/>
+ <accelerator key="j" signal="clicked"/>
+ <accelerator key="k" signal="clicked"/>
+ <accelerator key="l" signal="clicked"/>
<child>
<widget class="GtkLabel" id="label14">
<property name="visible">True</property>
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_digit_clicked"/>
- <accelerator key="o" signal="clicked"/>
- <accelerator key="n" signal="clicked"/>
- <accelerator key="m" signal="clicked"/>
<accelerator key="6" signal="clicked"/>
+ <accelerator key="m" signal="clicked"/>
+ <accelerator key="n" signal="clicked"/>
+ <accelerator key="o" signal="clicked"/>
<child>
<widget class="GtkLabel" id="label15">
<property name="visible">True</property>
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_digit_clicked"/>
- <accelerator key="s" signal="clicked"/>
- <accelerator key="r" signal="clicked"/>
- <accelerator key="q" signal="clicked"/>
- <accelerator key="p" signal="clicked"/>
<accelerator key="7" signal="clicked"/>
+ <accelerator key="p" signal="clicked"/>
+ <accelerator key="q" signal="clicked"/>
+ <accelerator key="r" signal="clicked"/>
+ <accelerator key="s" signal="clicked"/>
<child>
<widget class="GtkLabel" id="label16">
<property name="visible">True</property>
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_digit_clicked"/>
- <accelerator key="v" signal="clicked"/>
- <accelerator key="u" signal="clicked"/>
- <accelerator key="t" signal="clicked"/>
<accelerator key="8" signal="clicked"/>
+ <accelerator key="t" signal="clicked"/>
+ <accelerator key="u" signal="clicked"/>
+ <accelerator key="v" signal="clicked"/>
<child>
<widget class="GtkLabel" id="label17">
<property name="visible">True</property>
<property name="receives_default">False</property>
<property name="focus_on_click">False</property>
<signal name="clicked" handler="on_digit_clicked"/>
- <accelerator key="z" signal="clicked"/>
- <accelerator key="y" signal="clicked"/>
- <accelerator key="x" signal="clicked"/>
- <accelerator key="w" signal="clicked"/>
<accelerator key="9" signal="clicked"/>
+ <accelerator key="w" signal="clicked"/>
+ <accelerator key="x" signal="clicked"/>
+ <accelerator key="y" signal="clicked"/>
+ <accelerator key="z" signal="clicked"/>
<child>
<widget class="GtkLabel" id="label18">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<widget class="GtkButton" id="logins_close_button">
- <property name="label" translatable="yes">gtk-close</property>
+ <property name="label" translatable="yes">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
try:
self._grab_account_info(loginSuccessOrFailurePage)
except Exception, e:
- _moduleLogger.exception(str(e))
- return False
+ # Retry in case the redirect failed
+ # luckily is_authed does everything we need for a retry
+ loggedIn = self.is_authed(True)
+ if not loggedIn:
+ _moduleLogger.exception(str(e))
+ return False
+ _moduleLogger.info("Redirection failed on initial login attempt, auto-corrected for this")
self._browser.cookies.save()
self._lastAuthed = time.time()
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+@todo Collapse voicemails
@todo Alternate UI for dialogs (stackables)
"""
return "%s %s" % (parts[0], parts[1][0])
+def _collapse_message(messageLines, maxCharsPerLine, maxLines):
+ lines = 0
+
+ numLines = len(messageLines)
+ for line in messageLines[0:min(maxLines, numLines)]:
+ linesPerLine = max(1, int(len(line) / maxCharsPerLine))
+ allowedLines = maxLines - lines
+ acceptedLines = min(allowedLines, linesPerLine)
+ acceptedChars = acceptedLines * maxCharsPerLine
+
+ if acceptedChars < (len(line) + 3):
+ suffix = "..."
+ else:
+ acceptedChars = len(line) # eh, might as well complete the line
+ suffix = ""
+ abbrevMessage = "%s%s" % (line[0:acceptedChars], suffix)
+ yield abbrevMessage
+
+ lines += acceptedLines
+ if maxLines <= lines:
+ break
+
+
+def collapse_message(message, maxCharsPerLine, maxLines):
+ r"""
+ >>> collapse_message("Hello", 60, 2)
+ 'Hello'
+ >>> collapse_message("Hello world how are you doing today? 01234567890123456789012345678901234567890123456789012345678901234567890123456789", 60, 2)
+ 'Hello world how are you doing today? 01234567890123456789012...'
+ >>> collapse_message('''Hello world how are you doing today?
+ ... 01234567890123456789
+ ... 01234567890123456789
+ ... 01234567890123456789
+ ... 01234567890123456789''', 60, 2)
+ 'Hello world how are you doing today?\n01234567890123456789'
+ >>> collapse_message('''
+ ... Hello world how are you doing today? 01234567890123456789012345678901234567890123456789012345678901234567890123456789
+ ... Hello world how are you doing today? 01234567890123456789012345678901234567890123456789012345678901234567890123456789
+ ... Hello world how are you doing today? 01234567890123456789012345678901234567890123456789012345678901234567890123456789
+ ... Hello world how are you doing today? 01234567890123456789012345678901234567890123456789012345678901234567890123456789
+ ... Hello world how are you doing today? 01234567890123456789012345678901234567890123456789012345678901234567890123456789
+ ... Hello world how are you doing today? 01234567890123456789012345678901234567890123456789012345678901234567890123456789''', 60, 2)
+ '\nHello world how are you doing today? 01234567890123456789012...'
+ """
+ messageLines = message.split("\n")
+ return "\n".join(_collapse_message(messageLines, maxCharsPerLine, maxLines))
+
+
class MergedAddressBook(object):
"""
Merger of all addressbooks
collapsedMessages.extend(messages[-(self._MIN_MESSAGES_SHOWN+0):])
else:
collapsedMessages = expandedMessages
+ #collapsedMessages = _collapse_message(collapsedMessages, 60, self._MIN_MESSAGES_SHOWN)
number = make_ugly(number)
* UI Tweak: Increased the size of the SMS dialog
* UI Tweak: Disable "Dial" when a text has started to be entered
* UI Tweak: Move the sms history scroll bars around the whole sms conversation, giving more room to see with
+* UI Tweak: Trying to be clearer by switching the login dialog from "Close" to "Cancel"
+* UI Tweak: Remove auto-cancel of login after X attempts
* Bug Fix: Expanded the types of the Enter key that are supported for going to full screen
* Bug Fix: Random people were reporting login issues
* Bug Fix: Hardened against issues with grabbing possible callback numbers
with test_utils.expected(RuntimeError):
backend.send_sms("5551234567", "Hello World")
assert backend.get_account_number() == "", "%s" % backend.get_account_number()
- backend.set_sane_callback()
assert backend.get_callback_number() == ""
with test_utils.expected(Exception):
recent = list(backend.get_recent())