Skip to content

Commit

Permalink
[core, gtk] use aMSNAccount to set the dp, change the UI API (dp choo…
Browse files Browse the repository at this point in the history
…ser)

Fix creating the directory in backend
Use backend to update dp in personalinfo
  • Loading branch information
luckyluke committed Sep 22, 2009
1 parent 7e61ea2 commit 3c03650
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 73 deletions.
4 changes: 2 additions & 2 deletions amsn2/backend/defaultaccountbackend.py
Expand Up @@ -174,8 +174,8 @@ def removeAccount(self, email):
""" DPs """
def getFileLocationDP(self, email, uid, shac):
dir = os.path.join(self.dps_dir, self._getDir(email))
if not os.path.isdir(self.dps_dir):
os.makedirs(self.dps_dir, 0700)
if not os.path.isdir(dir):
os.makedirs(dir, 0700)
return os.path.join(dir, shac+".img")

def _getDir(self, email):
Expand Down
41 changes: 41 additions & 0 deletions amsn2/core/account_manager.py
@@ -1,8 +1,13 @@
import os
import Image
import logging
import papyon
import __builtin__
from views import AccountView
from views import StringView

logger = logging.getLogger('amsn2.core.account_manager')

class aMSNAccount(object):
""" aMSNAccount : a Class to represent an aMSN account
This class will contain all settings relative to an account
Expand All @@ -20,6 +25,7 @@ def __init__(self, core, accountview):
self.personalinfoview = core._personalinfo_manager._personalinfoview
self.do_save = accountview.save
self.backend_manager = core._backend_manager
self.client = None
self.lock()
self.load()

Expand Down Expand Up @@ -47,6 +53,41 @@ def save(self):
self.view.dp = self.personalinfoview.dp
self.backend_manager.saveAccount(self)

def set_dp(self, path):
if path:
try:
im = Image.open(path)
im.resize((96, 96), Image.BILINEAR)

# Write the file and rename it instead of creating a tmpfile
profile = self.client.profile
dp_path_tmp = self.backend_manager.getFileLocationDP(self.view.email, profile.id, 'tmp')
im.save(dp_path_tmp, "PNG")
f = open(dp_path_tmp)
dp_object = papyon.p2p.MSNObject(self.client.profile,
os.path.getsize(dp_path_tmp),
papyon.p2p.MSNObjectType.DISPLAY_PICTURE,
os.path.basename(path),
os.path.basename(path),
data=f)
f.close()

dp_path = self.backend_manager.getFileLocationDP(self.view.email, profile.id, dp_object._data_sha)
os.rename(dp_path_tmp, dp_path)

except OSError, e:
# FIXME: on Windows, it's raised if dp_path already exists
# http://docs.python.org/library/os.html#os.rename
logger.error('Trying to overwrite a saved dp')
return

except IOError, e:
logger.error(e)
return

self.client.msn_object_store.publish(dp_object)
self.personalinfoview.dp = dp_object

class aMSNAccountManager(object):
""" aMSNAccountManager : The account manager that takes care of storing
and retreiving all the account.
Expand Down
38 changes: 1 addition & 37 deletions amsn2/core/amsn.py
Expand Up @@ -33,9 +33,6 @@
import papyon
import logging

import Image
import tempfile

# Top-level loggers
papyon_logger = logging.getLogger("papyon")
logger = logging.getLogger("amsn2")
Expand Down Expand Up @@ -246,40 +243,7 @@ def contactCB(account):
self._gui.gui.aMSNContactDeleteWindow('Contact to remove: ', contactCB, ())

def changeDP(self):
def set_dp(view):
path = view.imgs[0][1]
f = open(path)
dp_obj = papyon.p2p.MSNObject(self._account.client.profile,
os.path.getsize(path),
papyon.p2p.MSNObjectType.DISPLAY_PICTURE,
f.name, f.name, data=f)
self._account.client.msn_object_store.publish(dp_obj)
self._personalinfo_manager._personalinfoview.dp = dp_obj

def open_file():
def update_dplist(file_path):
# TODO: fire up a window to choose the dp size and a friendly name
# TODO: save the new image in a local cache instead of a temp file
im = Image.open(file_path)
im.resize((96, 96), Image.BILINEAR)
fd, path = tempfile.mkstemp()
im.save(path, "PNG")
dp_view = ImageView('Filename', path)
dpwin.update_dp_list((dp_view, ))
filters = {'Image files':("*.png", "*.jpeg", "*.jpg", "*.gif", "*.bmp"),
'All files':('*.*')}
directory = os.path.join("amsn2", "themes", "displaypic", "default")
self._gui.gui.aMSNFileChooserWindow(filters, directory, update_dplist)

def capture():
pass

default_dps = ('dp_amsn', 'dp_female', 'dp_male', 'dp_nopic')
user_dps = [ImageView('Filename', self._theme_manager.get_dp(dp)[1]) for dp in default_dps]
dpwin = self._gui.gui.aMSNDPChooserWindow(user_dps,
(('Capture', capture),
('Open file', open_file)),
set_dp)
self._gui.gui.aMSNDPChooserWindow(self._account.set_dp ,self._backend_manager)

def createMainMenuView(self):
menu = MenuView()
Expand Down
7 changes: 5 additions & 2 deletions amsn2/core/personalinfo_manager.py
Expand Up @@ -7,6 +7,7 @@ def __init__(self, core):
"""

self._core = core
self._backend_manager = core._backend_manager
self._em = core._event_manager
self._personalinfoview = PersonalInfoView(self)
self._papyon_profile = None
Expand Down Expand Up @@ -73,8 +74,10 @@ def onPSMUpdated(self, psm):

def onDPUpdated(self, dp_msnobj):
self._personalinfoview._image.reset()
# TODO: use backend manager
self._personalinfoview._image.load('Filename', dp_msnobj._data.name)
path = self._backend_manager.getFileLocationDP(self._papyon_profile.account,
self._papyon_profile.id,
dp_msnobj._data_sha)
self._personalinfoview._image.load('Filename', path)
self._em.emit(self._em.events.PERSONALINFO_UPDATED, self._personalinfoview)

def onPresenceUpdated(self, presence):
Expand Down
19 changes: 2 additions & 17 deletions amsn2/gui/base/choosers.py
Expand Up @@ -26,30 +26,15 @@ class aMSNDPChooserWindow(object):
This Interface represent a window used to choose a display picture,
should show a list of default dps and the possibility to catch a picture from a webcam.
"""
def __init__(self, default_dps, actions, callback):
def __init__(self, callback, backend_manager):
"""
@type default_dps: list
@params default_dps: a list containing strings representing the paths of the default dps.
@type actions: tuple
@param actions: A tuple containing the options between
which the user can choose. Every option is a tuple itself, of the form (name, callback),
where callback is the function that will be called if the option is selected.
@type callback: function
@param callback: The function called when the dp has been choosed.
Its prototype is callback(dp_path)
@type backend_manager: aMSNBackendManager
This will eventually call the related show() method, so the window is
displayed when created.
"""
raise NotImplementedError

def update_dp_list(self, default_dps):
"""
@type default_dps: tuple
@params default_dps: a tuple containing strings representing the paths of the default dps.
This function updated the list of the dps that can be chosen,
for example after opening a file or taking a picture.
"""
raise NotImplementedError

45 changes: 30 additions & 15 deletions amsn2/gui/front_ends/gtk/choosers.py
Expand Up @@ -10,12 +10,13 @@ def __init__(self, filters, directory, callback):
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN, gtk.RESPONSE_OK))

for name in filters.keys():
filefilter = gtk.FileFilter()
filefilter.set_name(name)
for ext in filters[name]:
filefilter.add_pattern(ext)
self.add_filter(filefilter)
if filters:
for name in filters.keys():
filefilter = gtk.FileFilter()
filefilter.set_name(name)
for ext in filters[name]:
filefilter.add_pattern(ext)
self.add_filter(filefilter)

toggle = gtk.CheckButton("Show hidden files")
toggle.show()
Expand All @@ -28,7 +29,8 @@ def __init__(self, filters, directory, callback):

self.callback = callback
#self.set_size_request(500, 400)
self.set_current_folder_uri(directory)
if directory:
self.set_current_folder_uri(directory)

self.connect('selection-changed', self.activatePreview)
self.connect('response', self.onResponse)
Expand Down Expand Up @@ -56,22 +58,30 @@ def onResponse(self, chooser, id):


class aMSNDPChooserWindow(base.aMSNDPChooserWindow, gtk.Window):
def __init__(self, default_dps, actions, callback):
def __init__(self, callback, backend_manager):
gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
self.showed = False
self.set_default_size(550, 450)
self.set_position(gtk.WIN_POS_CENTER)
self.set_title("aMSN - Choose a Display Picture")
self.callback = callback
self.view = None

self.child = None

actions = (('Open file', self._open_file), )
default_dps = []
self._setup_boxes(actions)
self.update_dp_list(default_dps)
for dp in default_dps:
self._update_dp_list(default_dps)

self.show()
self.show_all()

def _open_file(self):
filters = {'Image files':("*.png", "*.jpeg", "*.jpg", "*.gif", "*.bmp"),
'All files':('*.*')}
aMSNFileChooserWindow(filters, None, self._update_dp_list)

def _setup_boxes(self, actions):
tscroll = gtk.ScrolledWindow()
tscroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
Expand Down Expand Up @@ -136,9 +146,14 @@ def __on_dp_click(self, source, event):
else:
return False

def update_dp_list(self, default_dps):
for dp in default_dps:
im = image.Image(None, dp)
self._model.append((im.to_pixbuf(96, 96), dp))

def _update_dp_list(self, dp_path):
im = gtk.Image()
try:
im.set_from_file(dp_path)
except:
return
self._model.prepend((gtk.gdk.pixbuf_new_from_file_at_size(dp_path, 96, 96), dp_path))
path = self._model.get_path(self._model.get_iter_first())
self.iconview.select_path(path)
self.iconview.grab_focus()

0 comments on commit 3c03650

Please sign in to comment.