diff --git a/desktop/qhandjoob.desktop b/desktop/qhandjoob.desktop
new file mode 100644
index 0000000000000000000000000000000000000000..105c9dbe534735ae81990368e0bdd851b454b4b9
--- /dev/null
+++ b/desktop/qhandjoob.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Name=QHandJoob
+Comment=Search for jobs
+Exec=qhandjoob
+Icon=qhandjoob
+Terminal=false
+Type=Application
+StartupNotify=true
+Categories=Network;Qt;
diff --git a/scripts/qhandjoob b/scripts/qhandjoob
new file mode 100755
index 0000000000000000000000000000000000000000..959660b0aa1feb93e1a0209901cf416909275a4e
--- /dev/null
+++ b/scripts/qhandjoob
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# vim: ft=python et softtabstop=4 cinoptions=4 shiftwidth=4 ts=4 ai
+
+# Copyright(C) 2010-2012 Sébastien Monel
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+
+from weboob.applications.qhandjoob import QHandJoob
+
+
+if __name__ == '__main__':
+ QHandJoob.run()
diff --git a/weboob/applications/qhandjoob/__init__.py b/weboob/applications/qhandjoob/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..941b9d89238d36f6381bfacb752e5ce2bea7cd24
--- /dev/null
+++ b/weboob/applications/qhandjoob/__init__.py
@@ -0,0 +1,3 @@
+from .qhandjoob import QHandJoob
+
+__all__ = ['QHandJoob']
diff --git a/weboob/applications/qhandjoob/main_window.py b/weboob/applications/qhandjoob/main_window.py
new file mode 100644
index 0000000000000000000000000000000000000000..2f03beed360035683cad3bbde0d0ab3ad0b08d17
--- /dev/null
+++ b/weboob/applications/qhandjoob/main_window.py
@@ -0,0 +1,134 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2010-2012 Sébastien Monel
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+from PyQt4.QtGui import QListWidgetItem, QImage, QPixmap, QLabel, QIcon, QBrush, QColor
+from PyQt4.QtCore import SIGNAL, Qt
+
+from decimal import Decimal
+
+from weboob.tools.application.qt import QtMainWindow, QtDo, HTMLDelegate
+from weboob.tools.application.qt.backendcfg import BackendCfg
+from weboob.capabilities.job import ICapJob, BaseJobAdvert
+from weboob.capabilities.base import NotLoaded, NotAvailable
+
+from .ui.main_window_ui import Ui_MainWindow
+
+class JobListWidgetItem(QListWidgetItem):
+ def __init__(self, job, *args, **kwargs):
+ QListWidgetItem.__init__(self, *args, **kwargs)
+ self.job = job
+
+ def __lt__(self, other):
+ return self.job.publication_date < other.job.publication_date
+
+ def setAttrs(self, storage):
+ text = u'%s' % self.job.title
+ self.setText(text)
+
+class MainWindow(QtMainWindow):
+ def __init__(self, config, storage, weboob, parent=None):
+ QtMainWindow.__init__(self, parent)
+ self.ui = Ui_MainWindow()
+ self.ui.setupUi(self)
+
+ self.config = config
+ self.storage = storage
+ self.weboob = weboob
+ self.process = None
+ self.displayed_photo_idx = 0
+ self.process_photo = {}
+ self.process_bookmarks = {}
+
+ self.ui.jobFrame.hide()
+
+ self.connect(self.ui.actionBackends, SIGNAL("triggered()"), self.backendsConfig)
+ self.connect(self.ui.searchEdit, SIGNAL('returnPressed()'), self.doSearch)
+ self.connect(self.ui.jobList, SIGNAL('currentItemChanged(QListWidgetItem*, QListWidgetItem*)'), self.jobSelected)
+
+ if self.weboob.count_backends() == 0:
+ self.backendsConfig()
+
+ def doSearch(self):
+ pattern = unicode(self.ui.searchEdit.text())
+ self.ui.jobList.clear()
+ self.process = QtDo(self.weboob, self.addJob)
+ self.process.do('search_job', pattern)
+
+ def addJob(self, backend, job):
+ if not backend:
+ self.process = None
+ return
+
+ if not job:
+ return
+
+ item = JobListWidgetItem(job)
+ item.setAttrs(self.storage)
+ self.ui.jobList.addItem(item)
+
+ def closeEvent(self, event):
+ QtMainWindow.closeEvent(self, event)
+
+ def backendsConfig(self):
+ bckndcfg = BackendCfg(self.weboob, (ICapJob,), self)
+ if bckndcfg.run():
+ pass
+
+ def jobSelected(self, item, prev):
+ if item is not None:
+ job = item.job
+ self.ui.queriesFrame.setEnabled(False)
+
+ self.process = QtDo(self.weboob, self.gotJob)
+ self.process.do('fillobj', job, backends=job.backend)
+
+ else:
+ job = None
+
+ self.setJob(job)
+
+ if prev:
+ prev.setAttrs(self.storage)
+
+ def gotJob(self, backend, job):
+ if not backend:
+ self.ui.queriesFrame.setEnabled(True)
+ self.process = None
+ return
+
+ self.setJob(job)
+
+ def setJob(self, job):
+ if job:
+ self.ui.descriptionEdit.setText("%s" % job.description)
+ self.ui.titleLabel.setText("
%s
" % job.title)
+ self.ui.backendLabel.setText("%s" % job.backend)
+ self.ui.jobNameLabel.setText("%s" % job.job_name)
+ self.ui.publicationDateLabel.setText("%s" % job.publication_date)
+ self.ui.societyNameLabel.setText("%s" % job.society_name)
+ self.ui.placeLabel.setText("%s" % job.place)
+ self.ui.payLabel.setText("%s" % job.pay)
+ self.ui.contractTypeLabel.setText("%s" % job.contract_type)
+ self.ui.formationLabel.setText("%s" % job.formation)
+ self.ui.experienceLabel.setText("%s" % job.experience)
+ self.ui.urlLabel.setText("%s" % job.url)
+ self.ui.jobFrame.show()
+ else:
+ self.ui.jobFrame.hide()
+
diff --git a/weboob/applications/qhandjoob/qhandjoob.py b/weboob/applications/qhandjoob/qhandjoob.py
new file mode 100644
index 0000000000000000000000000000000000000000..62eeb26f5a708f84bf52587b03f801b4b1cc8790
--- /dev/null
+++ b/weboob/applications/qhandjoob/qhandjoob.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2010-2012 Bezleputh
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+
+from weboob.capabilities.job import ICapJob
+from weboob.tools.application.qt import QtApplication
+from weboob.tools.config.yamlconfig import YamlConfig
+
+from .main_window import MainWindow
+
+
+class QHandJoob(QtApplication):
+ APPNAME = 'qhandjoob'
+ VERSION = '0.g'
+ COPYRIGHT = 'Copyright(C) 2010-2012 Sébastien Monel'
+ DESCRIPTION = "Qt application to search for job."
+ SHORT_DESCRIPTION = "search for job"
+ CAPS = ICapJob
+ CONFIG = {'queries': {}}
+ STORAGE = {'bookmarks': [], 'read': [], 'notes': {}}
+
+ def main(self, argv):
+ self.load_backends(ICapJob)
+ self.create_storage()
+ self.load_config(klass=YamlConfig)
+
+ self.main_window = MainWindow(self.config, self.storage, self.weboob)
+ self.main_window.show()
+ return self.weboob.loop()
diff --git a/weboob/applications/qhandjoob/ui/Makefile b/weboob/applications/qhandjoob/ui/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f0db5154cf49182632325b99b1c6d1875e938bff
--- /dev/null
+++ b/weboob/applications/qhandjoob/ui/Makefile
@@ -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)
+
diff --git a/weboob/applications/qhandjoob/ui/__init__.py b/weboob/applications/qhandjoob/ui/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/weboob/applications/qhandjoob/ui/main_window.ui b/weboob/applications/qhandjoob/ui/main_window.ui
new file mode 100644
index 0000000000000000000000000000000000000000..744bd5869afd4a91b8eb5f463efe753ef6feafa0
--- /dev/null
+++ b/weboob/applications/qhandjoob/ui/main_window.ui
@@ -0,0 +1,411 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 709
+ 572
+
+
+
+ QHandJoob
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+
+ 128
+ 128
+
+
+
+ true
+
+
+
+
+
+
+
+ Qt::Horizontal
+
+
+
+
+ 1
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+
-
+
+
-
+
+
+ <h1>Loading...</h1>
+
+
+
+ -
+
+
+ QFormLayout::ExpandingFieldsGrow
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Backend
+
+
+
+ -
+
+
+ Loading...
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Job Name
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Publication Date
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Society Name
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Place
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Pay
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Contract Type
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Formation
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Experience
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ URL
+
+
+
+ -
+
+
+ Loading...
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+ Loading...
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+ Loading...
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+ Loading...
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+ Loading...
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+ Loading...
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+ Loading...
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+ Loading...
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+ Loading...
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 5
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 50
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ toolBar
+
+
+ TopToolBarArea
+
+
+ false
+
+
+
+
+
+ Backends
+
+
+
+
+ jobList
+ descriptionEdit
+ searchEdit
+
+
+
+