global s/frontends/applications/

This commit is contained in:
Christophe Benz 2010-07-06 12:59:06 +02:00
commit 3bf9c2518b
88 changed files with 4387 additions and 28 deletions

View file

@ -0,0 +1 @@
from .qboobmsg import QBoobMsg

View file

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2010 Romain Bignon
#
# 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, version 3 of the License.
#
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from PyQt4.QtCore import SIGNAL
from weboob.tools.application.qt import QtMainWindow
from weboob.tools.application.qt.backendcfg import BackendCfg
from weboob.capabilities.messages import ICapMessages
from .ui.main_window_ui import Ui_MainWindow
from .messages_manager import MessagesManager
class MainWindow(QtMainWindow):
def __init__(self, config, weboob, parent=None):
QtMainWindow.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.config = config
self.weboob = weboob
self.manager = MessagesManager(weboob, self)
self.setCentralWidget(self.manager)
self.connect(self.ui.actionModules, SIGNAL("triggered()"), self.modulesConfig)
self.connect(self.ui.actionRefresh, SIGNAL("triggered()"), self.refresh)
def modulesConfig(self):
bckndcfg = BackendCfg(self.weboob, (ICapMessages,), self)
bckndcfg.show()
def refresh(self):
self.centralWidget().refresh()

View file

@ -0,0 +1,134 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2010 Romain Bignon
#
# 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, version 3 of the License.
#
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import time
from PyQt4.QtGui import QWidget, QTreeWidgetItem, QListWidgetItem
from PyQt4.QtCore import SIGNAL, Qt
from weboob.capabilities.messages import ICapMessages
from weboob.tools.application.qt import QtDo
from .ui.messages_manager_ui import Ui_MessagesManager
class MessagesManager(QWidget):
def __init__(self, weboob, parent=None):
QWidget.__init__(self, parent)
self.ui = Ui_MessagesManager()
self.ui.setupUi(self)
self.weboob = weboob
self.ui.backendsList.addItem('(All)')
for backend in self.weboob.iter_backends():
if not backend.has_caps(ICapMessages):
continue
item = QListWidgetItem(backend.name.capitalize())
item.setData(Qt.UserRole, backend)
self.ui.backendsList.addItem(item)
self.ui.backendsList.setCurrentRow(0)
self.backend = None
self.connect(self.ui.backendsList, SIGNAL('itemSelectionChanged()'), self._backendChanged)
self.connect(self.ui.messagesTree, SIGNAL('itemClicked(QTreeWidgetItem *, int)'), self._messageSelected)
self.connect(self.ui.messagesTree, SIGNAL('itemActivated(QTreeWidgetItem *, int)'), self._messageSelected)
self.connect(self, SIGNAL('gotMessage'), self._gotMessage)
def load(self):
self.refresh()
def _backendChanged(self):
selection = self.ui.backendsList.selectedItems()
if not selection:
self.backend = None
return
self.backend = selection[0].data(Qt.UserRole).toPyObject()
self.ui.messagesTree.clear()
self.refresh()
def refresh(self):
if self.ui.messagesTree.topLevelItemCount() > 0:
command = 'iter_new_messages'
else:
command = 'iter_messages'
self.ui.backendsList.setEnabled(False)
self.process = QtDo(self.weboob, self._gotMessage)
if self.backend:
self.process.do_backends(self.backend.name, command)
else:
self.process.do_caps(ICapMessages, command)
def _gotMessage(self, backend, message):
if message is None:
self.ui.backendsList.setEnabled(True)
return
item = QTreeWidgetItem(None, [time.strftime('%Y-%m-%d %H:%M:%S', message.get_date().timetuple()),
message.sender, message.title])
item.setData(0, Qt.UserRole, message)
root = self.ui.messagesTree.invisibleRootItem()
# try to find a message which would be my parent.
# if no one is found, insert it on top level.
if not self._insertMessage(root, item):
self.ui.messagesTree.addTopLevelItem(item)
# Check orphaned items which are child of this new one to put
# in.
to_remove = []
for i in xrange(root.childCount()):
sub = root.child(i)
sub_message = sub.data(0, Qt.UserRole).toPyObject()
if sub_message.thread_id == message.thread_id and sub_message.reply_id == message.id:
# do not remove it now because childCount() would change.
to_remove.append(sub)
for sub in to_remove:
root.removeChild(sub)
item.addChild(sub)
def _insertMessage(self, top, item):
top_message = top.data(0, Qt.UserRole).toPyObject()
item_message = item.data(0, Qt.UserRole).toPyObject()
if top_message and top_message.thread_id == item_message.thread_id and top_message.id == item_message.reply_id:
# it's my parent
top.addChild(item)
return True
else:
# check the children
for i in xrange(top.childCount()):
sub = top.child(i)
if self._insertMessage(sub, item):
return True
return False
def _messageSelected(self, item, column):
message = item.data(0, Qt.UserRole).toPyObject()
self.ui.messageBody.setText("<h1>%s</h1>"
"<b>Date</b>: %s<br />"
"<b>From</b>: %s<br />"
"<p>%s</p>"
% (message.title, str(message.date), message.sender, message.content))

View file

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2010 Romain Bignon
#
# 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, version 3 of the License.
#
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from weboob.capabilities.messages import ICapMessages
from weboob.tools.application import QtApplication
from .main_window import MainWindow
class QBoobMsg(QtApplication):
APPNAME = 'qboobmsg'
VERSION = '0.1'
COPYRIGHT = 'Copyright(C) 2010 Romain Bignon'
def main(self, argv):
self.load_backends(ICapMessages, storage=self.create_storage())
self.main_window = MainWindow(self.config, self.weboob)
self.main_window.show()
return self.weboob.loop()

View file

@ -0,0 +1,49 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright(C) 2010 Christophe Benz
#
# 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, version 3 of the License.
#
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from setuptools import setup
import os
os.system('make -C %s/ui' % os.path.dirname(__file__))
setup(
name='weboob-qboobmsg',
version='0.1',
description='QBoobMsg, the Weboob e-mail swiss-knife, Qt version',
author='Romain Bignon',
author_email='weboob@lists.symlink.me',
license='GPLv3',
url='http://weboob.org/QBoobMsg',
namespace_packages = ['weboob', 'weboob.frontends'],
packages=[
'weboob',
'weboob.frontends',
'weboob.frontends.qboobmsg',
'weboob.frontends.qboobmsg.ui',
],
scripts=[
'scripts/qboobmsg',
],
install_requires=[
'weboob-core-qt',
'weboob-messages-backends',
],
)

View file

@ -0,0 +1,13 @@
UI_FILES = $(wildcard *.ui)
UI_PY_FILES = $(UI_FILES:%.ui=%_ui.py)
PYUIC = pyuic4
all: $(UI_PY_FILES)
%_ui.py: %.ui
$(PYUIC) -o $@ $^
clean:
rm -f *.pyc
rm -f $(UI_PY_FILES)

View file

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>763</width>
<height>580</height>
</rect>
</property>
<property name="windowTitle">
<string>QBoobMsg</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout"/>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>763</width>
<height>24</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionModules"/>
<addaction name="actionRefresh"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<addaction name="menuFile"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionModules"/>
<addaction name="actionRefresh"/>
</widget>
<action name="actionModules">
<property name="text">
<string>Modules</string>
</property>
</action>
<action name="actionQuit">
<property name="text">
<string>Quit</string>
</property>
<property name="toolTip">
<string>Quit</string>
</property>
</action>
<action name="actionRefresh">
<property name="text">
<string>Refresh</string>
</property>
</action>
</widget>
<resources/>
<connections>
<connection>
<sender>actionQuit</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>381</x>
<y>289</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -0,0 +1,192 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MessagesManager</class>
<widget class="QWidget" name="MessagesManager">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>767</width>
<height>591</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QListWidget" name="backendsList">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
<widget class="QSplitter" name="splitter">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QTreeWidget" name="messagesTree">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="animated">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>false</bool>
</property>
<attribute name="headerDefaultSectionSize">
<number>100</number>
</attribute>
<attribute name="headerShowSortIndicator" stdset="0">
<bool>true</bool>
</attribute>
<attribute name="headerStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="headerDefaultSectionSize">
<number>100</number>
</attribute>
<attribute name="headerShowSortIndicator" stdset="0">
<bool>true</bool>
</attribute>
<attribute name="headerStretchLastSection">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string>Date</string>
</property>
<property name="textAlignment">
<set>AlignLeft|AlignVCenter</set>
</property>
</column>
<column>
<property name="text">
<string>From</string>
</property>
</column>
<column>
<property name="text">
<string>Title</string>
</property>
</column>
</widget>
<widget class="QTextEdit" name="messageBody">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QToolButton" name="expandButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="collapseButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string></string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>expandButton</sender>
<signal>clicked()</signal>
<receiver>messagesTree</receiver>
<slot>expandAll()</slot>
<hints>
<hint type="sourcelabel">
<x>733</x>
<y>31</y>
</hint>
<hint type="destinationlabel">
<x>527</x>
<y>150</y>
</hint>
</hints>
</connection>
<connection>
<sender>collapseButton</sender>
<signal>clicked()</signal>
<receiver>messagesTree</receiver>
<slot>collapseAll()</slot>
<hints>
<hint type="sourcelabel">
<x>733</x>
<y>60</y>
</hint>
<hint type="destinationlabel">
<x>527</x>
<y>150</y>
</hint>
</hints>
</connection>
</connections>
</ui>