Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRaul Gutierrez Segales <rgs@itevenworks.net>2013-02-03 18:23:02 (GMT)
committer Raul Gutierrez Segales <rgs@itevenworks.net>2013-02-03 19:10:55 (GMT)
commit92f971100d2a7a302992ed694b1dfc2719513429 (patch)
tree65b2101ce65850e0244d894b7d47d79939ed1931 /src
parent8a56a1dd6c6c71fc89c2ab04692b6e59c594f7f9 (diff)
Make FacebookOnlineAccount an extension and move the OnlineAccount*
stuff into jarabe/web
Diffstat (limited to 'src')
-rw-r--r--src/jarabe/Makefile.am3
-rw-r--r--src/jarabe/journal/journaltoolbox.py2
-rw-r--r--src/jarabe/journal/palettes.py2
-rw-r--r--src/jarabe/util/Makefile.am6
-rw-r--r--src/jarabe/util/facebook.py294
-rw-r--r--src/jarabe/util/facebook_online_account.py227
-rw-r--r--src/jarabe/web/Makefile.am5
-rw-r--r--src/jarabe/web/__init__.py18
-rw-r--r--src/jarabe/web/online_account.py (renamed from src/jarabe/util/online_account.py)0
-rw-r--r--src/jarabe/web/online_accounts_manager.py (renamed from src/jarabe/util/online_accounts_manager.py)17
10 files changed, 43 insertions, 531 deletions
diff --git a/src/jarabe/Makefile.am b/src/jarabe/Makefile.am
index d926d9f..39099a5 100644
--- a/src/jarabe/Makefile.am
+++ b/src/jarabe/Makefile.am
@@ -6,7 +6,8 @@ SUBDIRS = \
model \
view \
intro \
- util
+ util \
+ web
sugardir = $(pythondir)/jarabe
sugar_PYTHON = \
diff --git a/src/jarabe/journal/journaltoolbox.py b/src/jarabe/journal/journaltoolbox.py
index 71e614c..dc380aa 100644
--- a/src/jarabe/journal/journaltoolbox.py
+++ b/src/jarabe/journal/journaltoolbox.py
@@ -48,7 +48,7 @@ from jarabe.journal import model
from jarabe.journal.palettes import ClipboardMenu
from jarabe.journal.palettes import VolumeMenu
from jarabe.journal import journalwindow
-from jarabe.util import online_accounts_manager as oam
+from jarabe.web import online_accounts_manager as oam
_AUTOSEARCH_TIMEOUT = 1000
diff --git a/src/jarabe/journal/palettes.py b/src/jarabe/journal/palettes.py
index e03bc61..b69f55b 100644
--- a/src/jarabe/journal/palettes.py
+++ b/src/jarabe/journal/palettes.py
@@ -42,7 +42,7 @@ from jarabe.model import mimeregistry
from jarabe.journal import misc
from jarabe.journal import model
from jarabe.journal import journalwindow
-from jarabe.util import online_accounts_manager as oam
+from jarabe.web import online_accounts_manager as oam
class ObjectPalette(Palette):
diff --git a/src/jarabe/util/Makefile.am b/src/jarabe/util/Makefile.am
index 7f80330..3054b5a 100644
--- a/src/jarabe/util/Makefile.am
+++ b/src/jarabe/util/Makefile.am
@@ -5,8 +5,4 @@ sugardir = $(pythondir)/jarabe/util
sugar_PYTHON = \
__init__.py \
emulator.py \
- facebook.py \
- facebook_online_account.py \
- normalize.py \
- online_account.py \
- online_accounts_manager.py
+ normalize.py
diff --git a/src/jarabe/util/facebook.py b/src/jarabe/util/facebook.py
deleted file mode 100644
index 92529dc..0000000
--- a/src/jarabe/util/facebook.py
+++ /dev/null
@@ -1,294 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2012 Raul Gutierrez S. - rgs@itevenworks.net
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-#THE SOFTWARE.
-
-import json
-import logging
-import pycurl
-import time
-import urllib
-
-from gi.repository import GObject
-
-class FbAccount():
- _access_token = ""
-
- @classmethod
- def set_access_token(cls, access_token):
- logging.debug("LOOK = %s" % (access_token))
- cls._access_token = access_token
-
- @classmethod
- def access_token(cls):
- return cls._access_token
-
-class FbObjectNotCreatedException(Exception):
- pass
-
-class FbBadCall(Exception):
- pass
-
-class FbPhoto(GObject.GObject):
- PHOTOS_URL = "https://graph.facebook.com/me/photos?access_token=%s"
- COMMENTS_URL = "https://graph.facebook.com/%s/comments"
-
- __gsignals__ = {
- 'photo-created': (GObject.SignalFlags.RUN_FIRST, None, ([str])),
- 'photo-create-failed': (GObject.SignalFlags.RUN_FIRST, None, ([str])),
- 'comment-added': (GObject.SignalFlags.RUN_FIRST, None, ([str])),
- 'comment-add-failed': (GObject.SignalFlags.RUN_FIRST, None, ([str])),
- 'comments-downloaded': (GObject.SignalFlags.RUN_FIRST, None, ([object])),
- 'comments-download-failed': (GObject.SignalFlags.RUN_FIRST, None, ([str])),
- 'likes-downloaded': (GObject.SignalFlags.RUN_FIRST, None, ([object])),
- }
-
- def __init__(self, fb_object_id=None):
- GObject.GObject.__init__(self)
- self.fb_object_id = fb_object_id
-
- def create(self, image_path):
- GObject.idle_add(self._create, image_path)
-
- def add_comment(self, comment):
- self.check_created('add_comment')
- GObject.idle_add(self._add_comment, comment)
-
- def refresh_comments(self):
- """ raise an exception if no one is listening """
- self.check_created('refresh_comments')
- GObject.idle_add(self._refresh_comments)
-
- def check_created(self, method_name):
- if self.fb_object_id is None:
- errmsg = "Need to call create before calling %s" % (method_name)
- raise FbObjectNotCreatedException(errmsg)
-
- def _add_comment(self, comment):
- url = self.COMMENTS_URL % (self.fb_object_id)
-
- response = []
- def write_cb(buf):
- response.append(buf)
-
- res = self._http_call(url, [('message', comment)], write_cb, post=True)
- if res == 200:
- try:
- comment_id = self._id_from_response("".join(response))
- self.emit('comment-added', comment_id)
- except FbBadCall as ex:
- self.emit('comment-add-failed', str(ex))
- else:
- logging.debug("_add_comment failed, HTTP resp code: %d" % (res))
- self.emit('comment-add-failed', "Add comment failed: %d" % (res))
-
- def _create(self, image_path):
- url = self.PHOTOS_URL % (FbAccount.access_token())
- c = pycurl.Curl()
- params = [('source', (c.FORM_FILE, image_path))]
-
- response = []
- def write_cb(buf):
- response.append(buf)
-
- result = self._http_call(url, params, write_cb, post=True)
- if result == 200:
- photo_id = self._id_from_response("".join(response))
- self.fb_object_id = photo_id
- self.emit('photo-created', photo_id)
- else:
- logging.debug("_create failed, HTTP resp code: %d" % result)
-
- if result == 400:
- failed_reason = "Expired access token."
- elif result == 6:
- failed_reason = "Network is down."
- failed_reason += \
- "Please connect to the network and try again."
- else:
- failed_reason = "Failed reason unknown: %s" % (str(result))
-
- self.emit('photo-create-failed', failed_reason)
-
- def _id_from_response(self, response_str):
- response_object = json.loads(response_str)
-
- if not "id" in response_object:
- raise FbBadCall(response_str)
-
- fb_object_id = response_object['id'].encode('ascii', 'replace')
- return fb_object_id
-
- def _refresh_comments(self):
- """ this blocks """
- url = self.COMMENTS_URL % (self.fb_object_id)
-
- logging.debug("_refresh_comments fetching %s" % (url))
-
- response_comments = []
- def write_cb(buf):
- response_comments.append(buf)
-
- ret = self._http_call(url, [], write_cb, post=False)
- if ret != 200:
- logging.debug("_refresh_comments failed, HTTP resp code: %d" % ret)
- self.emit('comments-download-failed',
- "Comments download failed: %d" % (ret))
- return
-
- logging.debug("_refresh_comments: %s" % ("".join(response_comments)))
-
- try:
- response_data = json.loads("".join(response_comments))
- if 'data' not in response_data:
- logging.debug("No data inside the FB response")
- self.emit('comments-download-failed',
- "Comments download failed with no data")
- return
- except Exception as ex:
- logging.debug("Couldn't parse FB response: %s" % str(ex))
- self.emit('comments-download-failed',
- "Comments download failed: %s" % (str(ex)))
- return
-
- comments = []
- for c in response_data['data']:
- comment = {} # this should be an Object
- comment['from'] = c['from']['name']
- comment['message'] = c['message']
- comment['created_time'] = c['created_time']
- comment['like_count'] = c['like_count']
- comments.append(comment)
-
- if len(comments) > 0:
- self.emit('comments-downloaded', comments)
- else:
- self.emit('comments-download-failed', 'No comments found')
-
- def _http_call(self, url, params, write_cb, post=False):
- app_auth_params = [('access_token', FbAccount.access_token())]
-
- c = pycurl.Curl()
- c.setopt(c.WRITEFUNCTION, write_cb)
-
- if post:
- c.setopt(c.POST, 1)
- c.setopt(c.HTTPPOST, app_auth_params + params)
- else:
- c.setopt(c.HTTPGET, 1)
- params_str = urllib.urlencode(app_auth_params + params)
- url = "%s?%s" % (url, params_str)
-
- logging.debug("_http_call: %s" % (url))
-
- c.setopt(c.URL, url)
- c.perform()
- result = c.getinfo(c.HTTP_CODE)
- c.close()
-
- return result
-
-
-if __name__ == '__main__':
- import sys
- if len(sys.argv) != 3:
- print "Tests need access_token and an image path!"
- exit(1)
-
- access_token, photo_path = sys.argv[1:3]
- FbAccount.set_access_token(access_token)
-
-
-def test_create_photo(loop):
- def photo_created_cb(photo, photo_id, loop):
- print "Photo created: %s" % (photo_id)
- loop.quit()
-
- photo = FbPhoto()
- photo.connect('photo-created', photo_created_cb, loop)
- photo.create(photo_path)
-
-def test_add_comment(loop):
- def photo_created_cb(photo, photo_id, loop):
- print "Photo created: %s" % (photo_id)
-
- def comment_added_cb(photo, comment_id, loop):
- print "Comment created: %s" % (comment_id)
- loop.quit()
- return False
-
- photo = FbPhoto(photo_id)
- photo.connect("comment-added", comment_added_cb, loop)
- photo.add_comment("this is a test")
- return False
-
- photo = FbPhoto()
- photo.connect('photo-created', photo_created_cb, loop)
- photo.create(photo_path)
-
-def test_get_comments(loop):
- def photo_created_cb(photo, photo_id, loop):
- print "Photo created: %s" % (photo_id)
-
- def comment_added_cb(photo, comment_id, loop):
- print "Comment created: %s" % (comment_id)
-
- def comments_downloaded_cb(photo, comments, loop):
- print "%s comments for photo %s" % \
- (len(comments), photo.fb_object_id)
-
- for c in comments:
- print "Comment from %s with message: %s" % \
- (c["from"], c["message"])
-
- loop.quit()
-
- photo.connect('comments-downloaded',
- comments_downloaded_cb,
- loop)
- photo.refresh_comments()
- return False
-
- photo = FbPhoto(photo_id)
- photo.connect("comment-added", comment_added_cb, loop)
- photo.add_comment("this is a test")
- return False
-
- photo = FbPhoto()
- photo.connect('photo-created', photo_created_cb, loop)
- photo.create(photo_path)
-
-
-def timeout_cb(test_name, loop):
- print "%s timed out and failed" % (test_name)
- loop.quit()
- return False
-
-if __name__ == '__main__':
- tests = [eval(t) for t in dir() if t.startswith('test_')]
-
- for t in tests:
- print "\n=== Starting %s (%s) ===" % (t.__name__, time.time())
- loop = GObject.MainLoop()
- tid = GObject.timeout_add(30000, timeout_cb, t.__name__, loop)
- t(loop)
- loop.run()
- GObject.source_remove(tid)
- print "=== Finished %s (%s) ===\n" % (t.__name__, time.time())
diff --git a/src/jarabe/util/facebook_online_account.py b/src/jarabe/util/facebook_online_account.py
deleted file mode 100644
index dcc82ad..0000000
--- a/src/jarabe/util/facebook_online_account.py
+++ /dev/null
@@ -1,227 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2013 Walter Bender, Raul Gutierrez Segales
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-#THE SOFTWARE.
-
-from gettext import gettext as _
-import logging
-import os
-import tempfile
-import time
-
-from gi.repository import Gtk
-from gi.repository import GdkPixbuf
-from gi.repository import GConf
-
-from sugar3.datastore import datastore
-from sugar3.graphics.alert import Alert, NotifyAlert
-from sugar3.graphics.icon import Icon
-
-from jarabe.journal import journalwindow
-from jarabe.util import facebook
-from jarabe.util import online_account
-
-ACCOUNT_NEEDS_ATTENTION = 0
-ACCOUNT_ACTIVE = 1
-
-
-class FacebookOnlineAccount(online_account.OnlineAccount):
-
- ACCESS_TOKEN_KEY = "/desktop/sugar/collaboration/facebook_access_token"
- ACCESS_TOKEN_KEY_EXPIRATION_DATE = \
- "/desktop/sugar/collaboration/facebook_access_token_expiration_date"
-
- def __init__(self):
- online_account.OnlineAccount.__init__(self)
- self._client = GConf.Client.get_default()
- facebook.FbAccount.set_access_token(self._access_token())
-
- def is_configured(self):
- return self._access_token() is not None
-
- def is_active(self):
- expiration_date = \
- self._client.get_int(self.ACCESS_TOKEN_KEY_EXPIRATION_DATE)
- return expiration_date != 0 and expiration_date > time.time()
-
- def get_share_menu(self, journal_entry_metadata):
- if self.is_active():
- icon_name = 'facebook-share'
- else:
- icon_name = 'facebook-share-insensitive'
- fb_share_menu = FacebookShareMenu(journal_entry_metadata)
- fb_share_menu.set_image(Icon(icon_name=icon_name,
- icon_size=Gtk.IconSize.MENU))
- fb_share_menu.show()
- return fb_share_menu
-
- def get_refresh_button(self):
- return FacebookRefreshButton(self.is_active())
-
- def _access_token(self):
- return self._client.get_string(self.ACCESS_TOKEN_KEY)
-
-
-class FacebookShareMenu(online_account.OnlineShareMenu):
- __gtype_name__ = 'JournalFacebookMenu'
-
- def __init__(self, metadata):
- online_account.OnlineShareMenu.__init__(self, _('Facebook'))
-
- self._metadata = metadata
- self._comment = '%s: %s' % (self._get_metadata_by_key('title'),
- self._get_metadata_by_key('description'))
-
- self.connect('activate', self._facebook_share_menu_cb)
-
- def _get_metadata_by_key(self, key, default_value=''):
- if key in self._metadata:
- return self._metadata[key]
- return default_value
-
- def _facebook_share_menu_cb(self, menu_item):
- logging.debug('_facebook_share_menu_cb')
-
- tmp_file = tempfile.mktemp()
- self._image_file_from_metadata(tmp_file)
-
- photo = facebook.FbPhoto()
- photo.connect('photo-created', self._photo_created_cb, tmp_file)
- photo.connect('photo-create-failed',
- self._photo_create_failed_cb,
- tmp_file)
- result = photo.create(tmp_file)
-
- def _photo_created_cb(self, fb_photo, fb_object_id, tmp_file):
- logging.debug("_photo_created_cb")
-
- if os.path.exists(tmp_file):
- os.unlink(tmp_file)
-
- fb_photo.connect('comment-added', self._comment_added_cb)
- fb_photo.connect('comment-add-failed', self._comment_add_failed_cb)
- fb_photo.add_comment(self._comment)
-
- try:
- ds_object = datastore.get(self._metadata['uid'])
- ds_object.metadata['fb_object_id'] = fb_object_id
- datastore.write(ds_object, update_mtime=False)
- except Exception as ex:
- logging.debug("_photo_created_cb failed to write to datastore: " % \
- str(ex))
-
- def _photo_create_failed_cb(self, fb_photo, failed_reason, tmp_file):
- logging.debug("_photo_create_failed_cb")
-
- if os.path.exists(tmp_file):
- os.unlink(tmp_file)
-
- self._fb_notify(failed_reason)
-
- def _comment_added_cb(self, fb_photo, fb_comment_id):
- logging.debug("_comment_added_cb")
- self._fb_notify(_('Upload successful'))
-
- def _comment_add_failed_cb(self, fb_photo, failed_reason):
- logging.debug("_comment_add_failed_cb")
- self._fb_notify(failed_reason)
-
- def _fb_notify(self, message):
- alert = NotifyAlert()
- title_string = _('Facebook')
- alert.props.title = title_string
- alert.props.msg = message
- alert.connect('response', self._facebook_alert_response_cb)
- journalwindow.get_journal_window().add_alert(alert)
- alert.show()
-
- def _facebook_alert_response_cb(self, alert, response_id):
- journalwindow.get_journal_window().remove_alert(alert)
-
- def _image_file_from_metadata(self, image_path):
- """ Load a pixbuf from a Journal object. """
- pixbufloader = \
- GdkPixbuf.PixbufLoader.new_with_mime_type('image/png')
- pixbufloader.set_size(300, 225)
- try:
- pixbufloader.write(self._metadata['preview'])
- pixbuf = pixbufloader.get_pixbuf()
- except Exception as ex:
- logging.debug("_image_file_from_metadata: %s" % (str(ex)))
- pixbuf = None
-
- pixbufloader.close()
- if pixbuf:
- pixbuf.savev(image_path, 'png', [], [])
-
-
-class FacebookRefreshButton(online_account.OnlineRefreshButton):
- def __init__(self, is_active):
- online_account.OnlineRefreshButton.__init__(self, 'facebook-refresh-insensitive')
-
- self._metadata = None
- self._is_active = is_active
- self.set_tooltip(_('Facebook refresh'))
- self.set_sensitive(False)
- self.connect('clicked', self._fb_refresh_button_clicked_cb)
- self.show()
-
- def set_metadata(self, metadata):
- self._metadata = metadata
- if self._is_active:
- if self._metadata and 'fb_object_id' in self._metadata:
- self.set_sensitive(True)
- self.set_icon_name('facebook-refresh')
-
- def _fb_refresh_button_clicked_cb(self, button):
- logging.debug('_fb_refresh_button_clicked_cb')
-
- if self._metadata is None:
- logging.debug('_fb_refresh_button_clicked_cb called without metadata')
- return
-
- fb_photo = facebook.FbPhoto(self._metadata['fb_object_id'])
- fb_photo.connect('comments-downloaded',
- self._fb_comments_downloaded_cb)
- fb_photo.connect('comments-download-failed',
- self._fb_comments_download_failed_cb)
- fb_photo.refresh_comments()
-
- def _fb_comments_downloaded_cb(self, fb_photo, comments):
- logging.debug('_fb_comments_downloaded_cb')
-
- ds_object = datastore.get(self._metadata['uid'])
- for comment in comments:
- c_str = "%s: %s" % (comment['from'], comment['message'])
- ds_object.metadata['description'] += c_str
-
- datastore.write(ds_object, update_mtime=False)
-
- def _fb_comments_download_failed_cb(self, fb_photo, failed_reason):
- logging.debug('_fb_comments_download_failed_cb: %s' % (failed_reason))
- alert = NotifyAlert()
- alert.props.title = _('Comments download')
- alert.props.msg = failed_reason
- alert.connect('response', self.__fb_refresh_offline_response_cb)
- journalwindow.get_journal_window().add_alert(alert)
- alert.show()
-
- def __fb_refresh_offline_response_cb(self, alert, alert_id):
- pass
diff --git a/src/jarabe/web/Makefile.am b/src/jarabe/web/Makefile.am
new file mode 100644
index 0000000..b751410
--- /dev/null
+++ b/src/jarabe/web/Makefile.am
@@ -0,0 +1,5 @@
+sugardir = $(pythondir)/jarabe/web
+sugar_PYTHON = \
+ __init__.py \
+ online_account.py \
+ online_accounts_manager.py
diff --git a/src/jarabe/web/__init__.py b/src/jarabe/web/__init__.py
new file mode 100644
index 0000000..9c80ecb
--- /dev/null
+++ b/src/jarabe/web/__init__.py
@@ -0,0 +1,18 @@
+"""OLPC Sugar Jarabe utility modules
+"""
+
+# Copyright (C) 2008, One Laptop Per Child
+#
+# 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
diff --git a/src/jarabe/util/online_account.py b/src/jarabe/web/online_account.py
index 560c252..560c252 100644
--- a/src/jarabe/util/online_account.py
+++ b/src/jarabe/web/online_account.py
diff --git a/src/jarabe/util/online_accounts_manager.py b/src/jarabe/web/online_accounts_manager.py
index c262968..cb7a7ce 100644
--- a/src/jarabe/util/online_accounts_manager.py
+++ b/src/jarabe/web/online_accounts_manager.py
@@ -21,15 +21,28 @@
#THE SOFTWARE.
from gi.repository import GObject
+import logging
+import os
-from jarabe.util import facebook_online_account as fboa
+from jarabe import config
class OnlineAccountsManager(GObject.GObject):
@classmethod
def all_accounts(cls):
accounts = []
- accounts.append(fboa.FacebookOnlineAccount())
+
+ for f in os.listdir(os.path.join(config.ext_path, 'web')):
+ if f.endswith('.py') and not f.startswith('__'):
+ module_name = f[:-3]
+ logging.debug("OnlineAccountsManager loading %s" % \
+ (module_name))
+ try:
+ mod = __import__('web.' + module_name, globals(),
+ locals(), [module_name])
+ accounts.append(mod.get_account())
+ except Exception:
+ logging.exception('Exception while loading extension:')
return accounts
@classmethod